⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at88sc153.cpp

📁 at88sc153加密芯片 at88sc153加密芯片 at88sc153加密芯片
💻 CPP
字号:

// Copyright (C) Elva, 1998

#include "stdafx.h"
#include "AT88SC153.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CGpa::CGpa()
{
}

CGpa::~CGpa()
{
}


void CGpa::SetInit(unsigned char *crypto, unsigned char *graine,unsigned char *host)
{
unsigned char i;

	for (i=0;i<8;i++)
	{
		Crypto[i] = crypto[i];
		GC[i] = graine[i];
		Q0[i] = host[i];
	}

	// Init R and S
	for (i=0;i<7;i++)
	{
		R[i] = 0;
		S[i] = 0;
	}

	// Init T
	for (i=0;i<5;i++)
	{
		T[i] = 0;
	}
}

void CGpa::Authenticate(unsigned char *q1,unsigned char *q2)
{
int i;

	for (i=0;i<4;i++)
	{
		calculKey(Crypto[2*i]);
		calculKey(Crypto[2*i+1]);
		calculKey(Q0[i]);
	}
	for (i=0;i<4;i++)
	{
		calculKey(GC[2*i]);
		calculKey(GC[2*i+1]);
		calculKey(Q0[i+4]);
	}


	for (i=0;i<8;i++)
	{
		Q2[i] = calcul(2);
		Q2[i] <<= 4;
		Q2[i] |= calcul(2);
		Q1[i] = calcul(2);
		Q1[i] <<= 4;
		Q1[i] |= calcul(2);

		q2[i] = Q2[i];
		q1[i] = Q1[i];
	}

}

void CGpa::calculKey(unsigned char key)
{
unsigned char Ri,Ti,Si;

	// calcul des variables intermediaires
	Ri = key & 0x1F;
	Si = ((key << 3) & 0x78) + ((key >> 5) & 0x07);
	Ti = (key >> 3) & 0x1F;

	calculState(Ri,Ti,Si);
}

void CGpa::calculState(unsigned char Ri, unsigned char Ti, unsigned char Si)
{
unsigned char temp,bit0;

	bit0 = (R[6] >> 4) & 1;
	temp = (2*R[6] | bit0) & 0x1F;
	R[6] = R[5];
	R[5] = R[4];
	R[4] = R[3];
	R[3] = R[2] ^ Ri;
	R[2] = R[1];
	R[1] = R[0];
	R[0] = (R[4] + temp);
	if ( R[0] > 31 )
	{
		R[0] %= 31;
		if ( R[0] == 0 ) R[0] = 31;
	}

	bit0 = (S[6] >> 6) & 1;
	temp = (2*S[6] | bit0) & 0x7F;
	S[6] = S[5];
	S[5] = S[4] ^ Si;
	S[4] = S[3];
	S[3] = S[2];
	S[2] = S[1];
	S[1] = S[0];
	S[0] = (S[6] + temp) ;
	if ( S[0] > 127 )
	{
		S[0] %= 127;
		if ( S[0] == 0 ) S[0] = 127;
	}

	temp = T[4];
	T[4] = T[3];
	T[3] = T[2];
	T[2] = T[1] ^ Ti;
	T[1] = T[0];
	T[0] = (T[3] + temp);
	if ( T[0] > 31 )
	{
		T[0] %= 31;
		if ( T[0] == 0 ) T[0] = 31;
	}
}

unsigned char CGpa::calcul(void)
{
unsigned char Ri,Ti,Si_,Si;
unsigned char lastCalc = 0;

	calculState(0,0,0);
	Ri = (R[0] ^ R[4]) & 0x1F;
	Ti = (T[0] ^ T[3]) & 0x1F;
	Si  = S[0];
	Si_ = ~S[0];

	lastCalc = ( (Ri & Si_) | (Si & Ti) ) & 0xF;
	return lastCalc;
}

unsigned char CGpa::calcul(unsigned char nbre)
{
unsigned char i;
unsigned char calc;

	for (i=0;i<nbre;i++)
	{
		calc = calcul();
	}
	return calc;
}

SC153::~SC153()
{
	FreeLibrary(gLibDLL);
}

SC153::SC153()
{
char directory[ MAX_PATH ];

	GetSystemDirectory( directory,MAX_PATH);
#ifdef _DEBUG
	lstrcat(directory,"\\IdeLibraries\\iicD.dll" );
	gLibDLL = LoadLibrary(directory);
#else
	lstrcat(directory,"\\IdeLibraries\\iic.dll" );
	gLibDLL = LoadLibrary(directory);
#endif
	CardOk = FALSE;


	if (gLibDLL)
	{
		gLibInit = (DLL_INITN)GetProcAddress(gLibDLL,"DInit");
		gLibPowOn = (DLL_VOID)GetProcAddress(gLibDLL,"DPowerOn");
		gLibPowOff = (DLL_VOID)GetProcAddress(gLibDLL,"DPowerOff");
		gLibPC = (DLL_PC)GetProcAddress(gLibDLL,"DTestPC");
		gLibCommand = (DLL_COMMANDC)GetProcAddress(gLibDLL,"DCommand");
		gLibReset = (DLL_RESET)GetProcAddress(gLibDLL,"DReset");
		gLibSendByte = (DLL_SENDBYTE)GetProcAddress(gLibDLL,"DSend");
		gLibReadByte = (DLL_READBYTE)GetProcAddress(gLibDLL,"DRead");
		gLibStop = (DLL_VOID)GetProcAddress(gLibDLL,"DStop");
		gLibAck = (DLL_VOID)GetProcAddress(gLibDLL,"DAck");
		gLibNack = (DLL_VOID)GetProcAddress(gLibDLL,"DNack");
		CardOk = TRUE;
	}

}

int SC153::RazCard(int number,BYTE *answer)
{
int i;
int num =1;
BYTE libPc;

	if ( number == 3 )
	{
		num = 3;
		number = 0;
	}
	for ( i=0;i<num;i++)
	{
		if ( gLibInit(number) )
		{
			gLibPowOff();
			Sleep(100);
			gLibPowOn();
			Sleep(10);
			libPc = gLibPC();

			if ( libPc )
			{
				CardOk = TRUE;
				gLibReset(TWC,answer);
				return 0;
			}
			gLibPowOff();
		}
		number ++;
	}
	CardOk = FALSE;
	return -1;
}

int SC153::RemoveCard(void)
{
	CardOk = FALSE;
	gLibPowOff();
	return 0;
}

int SC153::InitPRG(BYTE *secret,BYTE *crypto,BYTE *host)
{
	GPA.SetInit(crypto,secret,host);
	return 0;
}

int SC153::ReadEEPROM(BYTE chip,BYTE zone,BYTE add,BYTE *data,BYTE number)
{
BYTE i;
BYTE cmd;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	if ( zone > 3 )
	{
		ErrNo = BAD_ZONE;
		return ErrNo;
	}
	if ( number > 8 )
	{
		ErrNo = BAD_NUMBER_READ;
		return ErrNo;
	}
	if ( number == 0 )
		return 0;
	do
	{
		cmd = (chip<<4) | ((zone<<2)& 0x0C) | 0x01;

		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		if ( gLibSendByte(add) )
		{
			ErrNo = NACK_ADDRESS;
			break;
		}
		for (i=0;i<number;i++)
		{
			data[i] = gLibReadByte();
			if ( i == (number -1) )
			{
				gLibNack();
			}
			else
				gLibAck();
		}
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}

int SC153::WriteEEPROM(BYTE chip,BYTE zone,BYTE add,BYTE *data,BYTE number)
{
BYTE i;
BYTE cmd;
int a;
int b;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	if ( number == 0 )
		return 0;
	a = add / 8;
	b = (add+number-1) / 8;
	if ( a != b )
	{
		ErrNo = BAD_ADDRESS;
		return ErrNo;
	}
	do
	{
		cmd = (chip<<4) | ((zone<<2)& 0x0C);

		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		if ( gLibSendByte(add) )
		{
			ErrNo = NACK_ADDRESS;
			break;
		}
		for (i=0;i<number;i++)
		{
			if ( gLibSendByte(data[i]) )
			{
				ErrNo = NACK_DATA;
				break;
			}
		}
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}

int SC153::ReadFuse(BYTE chip, BYTE *fuse)
{
BYTE cmd;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	do
	{
		cmd = (chip <<4) | 0x0E;
		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		*fuse = gLibReadByte();
		gLibNack();
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}

int SC153::WriteFuse(BYTE chip, BYTE fuse)
{
BYTE cmd;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	do
	{
		cmd = (chip <<4) | 0x0A;
		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		if ( gLibSendByte(fuse) )
		{
			ErrNo = NACK_ADDRESS_FUSES;
			break;
		}
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}


int SC153::VerifyPWD(BYTE chip, BYTE num,BYTE *pwd)
{
int i;
BYTE cmd;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	do
	{
		cmd = (chip<<4) | ( (num & 0x03)<<2 ) | 0x03;

		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		for (i=0;i<3;i++)
		{
			ErrNo = 0;
			if ( gLibSendByte(pwd[i]) )
			{
				ErrNo = NACK_PASSWORD;
				i = 3;
			}
		}
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}

int SC153::InitAuthentication(BYTE chip, BYTE *host)
{
BYTE cmd;
int i;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	do
	{
		cmd = (chip<<4) | 0x02;

		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		for (i=0;i<8;i++)
		{
			if ( gLibSendByte(host[i]) )
			{
				ErrNo = NACK_HOST;
				break;
			}
		}
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}


int SC153::VerifyAuthentication(BYTE chip, BYTE *challenge)
{
int i;
BYTE cmd;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	do
	{
		cmd = (chip<<4) | 0x06;

		if ( gLibCommand(cmd,TWC) )
		{
			ErrNo = NACK_COMMAND;
			break;
		}
		for (i=0;i<8;i++)
		{
			if ( gLibSendByte(challenge[i]) )
			{
				ErrNo = NACK_CHALLENGE;
				break;
			}
		}
		ErrNo = 0;
		break;
	}while (TRUE);
	gLibStop();
	if ( ErrNo )
		IsCardPresent();
	return ErrNo;
}


int SC153::Authenticate(BYTE chip, BYTE *q0,BYTE *q1,BYTE *q2)
{
BYTE crypto[8];
int i;

	if ( !CardOk )
	{
		if ( gLibPC() )
		{
			ErrNo = NO_CARD;
			return ErrNo;
		}
		else
		{
			CardOk = TRUE;
		}
	}
	if ( !InitAuthentication(chip,q0) )
	{
		if ( !VerifyAuthentication(chip,q1) )
		{
			if ( !ReadEEPROM(chip,0x03,0xE0,crypto,8) )
			{
				if ( crypto[0] != 255 )
				{
					ErrNo = BAD_AUTHENTICATION_CARD;
					return ErrNo;
				}
				for (i=1;i<8;i++)
				{
					if ( crypto[i] != q2[i] )
					{
						ErrNo = BAD_AUTHENTICATION_READER;
						i = 8;
					}
				}
			}

		}
	}
	return ErrNo;
}

int SC153::PresentPWD(BYTE chip,BYTE num,BYTE dir,BYTE *pwd)
{
int numero = num;
int add;
unsigned char PAC;

	if ( num > 1 )
	{
		ErrNo = BAD_INDEX;
		return ErrNo;
	}
	if ( dir )
	{
		numero = num | 0x02;
	}
	if ( VerifyPWD(chip,numero,pwd) )
	{
		ErrNo = BAD_PASSWORD;
		return ErrNo;
	}
	if ( !VerifyPWD(chip,numero,pwd) )
	{
		add = 0xF0 + num*0x08 + (dir == 1)*0x04;
		if ( !ReadEEPROM(chip,0x03,add,&PAC,1) )
		{
			if ( PAC != 255 )
			{
				ErrNo = BAD_PASSWORD;
			}
		}
	}
	return ErrNo;
}


void SC153::IsCardPresent(void)
{
	if ( !gLibPC() )
	{
		gLibPowOff();
		CardOk = FALSE;
		ErrNo = NO_CARD;
	}
}

int SC153::RunPRG(BYTE *ci1,BYTE *ci2)
{
	GPA.Authenticate(ci1,ci2);
	return 0;
}

int SC153::WriteLock(BYTE chip,BYTE zone,BYTE address,BYTE data)
{
BYTE lock;
BYTE wlm;

	if ( zone > 2 )
	{
		ErrNo = BAD_ZONE;
		return ErrNo;
	}
	if ( ReadEEPROM(chip,0x03,0xCD+zone,&wlm,1) )
	{
		return ErrNo;
	}
	if ( (wlm && 0x40) )
	{
		ErrNo = BAD_ZONE;
		return ErrNo;
	}
	if ( !WriteEEPROM(chip,zone,address,&data,1) )
	{
		lock = 0xFF ^ ( 1 << (address & 0x07) );
		WriteEEPROM(chip,zone,(address & 0xF8),&lock,1);
	}
	return ErrNo;
}

int SC153::WriteCheck(BYTE chip,BYTE zone,BYTE add,BYTE *data,BYTE number, BYTE *q0,BYTE *q1,BYTE *q2,BYTE *sc)
{
	if ( !Authenticate(chip,q0,q1,q2) )
	{
		if ( !WriteEEPROM(chip,zone,add,data,number) )
		{
			ReadEEPROM(chip,0x03,0xE0,sc,1);
		}
	}
	return ErrNo;
}

int SC153::ResetCard(BYTE *answer)
{
	gLibReset(TWC,answer);
	return 0;
}

int SC153::SimulCheck(BYTE nb, BYTE dir,BYTE *data,BYTE *sc)
{
int i;
BYTE check;

	if ( nb > 8 )
	{
		ErrNo = BAD_INDEX;
		return ErrNo;
	}
	if ( !nb )
	{
		ErrNo = BAD_INDEX;
		return ErrNo;
	}
	if ( dir > 2 )
	{
		ErrNo = BAD_INDEX;
		return ErrNo;
	}
	switch (dir)
	{
	case 0:
		for (i=0;i<nb;i++)
			GPA.calculKey(data[i]);
		break;
	case 1:
		GPA.calcul(8);
		GPA.calcul(nb*5);
		GPA.calcul(1);
		break;
	case 2:
		check = GPA.calcul(8);
		check <<= 4;
		check |= (GPA.calcul(4) & 0x0F);
		GPA.calcul(1);
		GPA.calcul((nb-1)*5);
		GPA.calcul(1);
		*sc = check;
		break;
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -