📄 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 + -