📄 7816.c
字号:
//
for (i = 0; i < 5; i++) // CLA INS P1 P2 P3
if (sendAByte(Buf[i]))
goto RET_ERR;
command_a:
do
{
if (receiveAByte(&rcv))
goto RET_ERR;
}
while (rcv == 0x60);
if (rcv == INS)
{
if (Lc == 0)
{
for (i = 0; i < Le + 2; i++)
{
if (receiveAByte(&rcv))
goto RET_ERR;
*p++ = rcv;
(*lenr)++;
}
if ((*(p-2) == 0x90) && (*(p-1) == 0x00)) // SW1, SW2
goto RET_OK;
else goto RET_ERR;
}
else
{
delayETU(50); // 反向保护时间,比规范宽1ETU
for (i = 0; i < Lc; i++)
{
if (sendAByte(*(comm + 5 + i)))
goto RET_ERR;
}
Lc = 0;
goto command_a;
}
}
else
{
switch (rcv)
{
case 0x61:
{
if (receiveAByte(&rcv))
goto RET_ERR;
if (bRESPAUTOFlag) // 自动取响应
{
delayETU(50); // 反向保护时间,比规范宽1ETU
Buf[0] = 0x0;
Buf[1] = 0xc0;
Buf[2] = 0x0;
Buf[3] = 0x0;
if (Le)
Buf[4] = Le;
else Buf[4] = rcv;
buflen = 5;
goto command_begin;
}
else
{
*p++ = 0x61;
*p++ = rcv;
*lenr += 2;
goto RET_OK;
}
}
case 0x6c:
{
if (receiveAByte(&rcv))
goto RET_ERR;
Buf[4] = rcv;
buflen = 5;
delayETU(50);
goto command_begin;
}
default:
{
*p++ = rcv;
(*lenr)++;
if (receiveAByte(&rcv))
goto RET_ERR;
*p++ = rcv;
(*lenr)++;
if ((*(p-2) == 0x90) && (*(p-1) == 0x00)) // SW1, SW2
goto RET_OK;
else goto RET_ERR;
}
break;
}
}
RET_OK:
return 0;
RET_ERR:
return 1;
}
//----------------------------------------------------------------;// ESAM和卡片命令// 输入输出变量说明// cRecvPtr ;卡片接收的数据区起始地址// cSendPtr ;卡片发送的数据区起始地址// cSendLen ;发送数据长度// cRecvLenr ;接收数据长度// 返回0--正确,返回1--错误// 用到的全局变量// bSamCardFlag ;ESAM和卡标志位// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;//; Routines called: cFM1702PiccComm, Command//; //; Calling routines: //----------------------------------------------------------------;uchar cExeCommand( uchar cSendLen, uchar *cSendPtr, uchar *cRecvLenr, uchar *cRecvPtr ){ uchar cReturnFlag; //如果使用非接触卡,分开发送命令
#ifdef PICC_CARD
//bNADflag=1 非接触卡片命令 if( bSamCardFlag ) { cReturnFlag = cFM1702PiccComm( cSendLen, cSendPtr, cRecvLenr, cRecvPtr ); //接收长度小于2或接收数据状态字不是9000,出错退出 if( (*cRecvLenr < 2) || (cRecvPtr[*cRecvLenr-2] != 0x90) || (cRecvPtr[*cRecvLenr-1] ) ) return(1); } //bNADflag=0 ESAM命令 else { SetRespAuto(); cReturnFlag = command( cSendLen, cSendPtr, cRecvLenr, cRecvPtr ); }
#else
SetRespAuto(); cReturnFlag = command( cSendLen, cSendPtr, cRecvLenr, cRecvPtr );#endif
return( cReturnFlag );}//----------------------------------------------------------------;// 通用APDU命令//----------------------------------------------------------------;// 选择文件// 输入输出变量说明// cFileID1 ;文件名// cFileID2 ;文件名// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar SelectFile( uchar cFileID1, uchar cFileID2 ){ uchar cReturnFlag; cCLA = 0; cINS = 0xA4; cP1 = 0; cP2 = 0; cLCLE = 2; cDatBuffer[5] = cFileID1; cDatBuffer[6] = cFileID2; cReturnFlag = cExeCommand( 7, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 读二进制文件// 输入输出变量说明// PP1 ;短文件标识// PP2 ;起始地址// ReadLenr ;读取数据长度// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar ReadBinary( uchar PP1, uchar PP2, uchar ReadLenr ){ uchar cReturnFlag; cCLA = 0; cINS = 0xB0; cP1 = PP1; cP2 = PP2; cLCLE = ReadLenr; cReturnFlag = cExeCommand( 5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 写二进制文件// 输入输出变量说明// PP1 ;短文件标识// PP2 ;起始地址// WriteLenr ;写数据长度// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar WriteBinary( uchar PP1, uchar PP2, uchar WriteLenr ){ uchar cReturnFlag; cCLA = 0; cINS = 0xD6; cP1 = PP1; cP2 = PP2; cLCLE = WriteLenr; cReturnFlag = cExeCommand( WriteLenr+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 取随机数// 输入输出变量说明// ReadLenr ;数据长度// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar GetRandom( uchar ReadLenr ){ uchar cReturnFlag; cCLA = 0; cINS = 0x84; cP1 = 0; cP2 = 0; cLCLE = ReadLenr; cReturnFlag = cExeCommand( 5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 内部认证// 输入输出变量说明// PP2 ;内部认证密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// cDatRvBuffer ;内部认证数据// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar InternalAuth( uchar PP2, uchar LLCC ){ uchar cReturnFlag; cCLA = 0; cINS = 0x88; cP1 = 0; cP2 = PP2; cLCLE = LLCC; cReturnFlag = cExeCommand( LLCC+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 外部认证// 输入输出变量说明// ExAuthP2 ;外部认证密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// cDatRvBuffer ;外部认证数据// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar ExternalAuth( uchar ExAuthP2, uchar LLCC ){ uchar cReturnFlag; cCLA = 0; cINS = 0x82; cP1 = 0; cP2 = ExAuthP2; cLCLE = LLCC; cReturnFlag = cExeCommand( LLCC+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 外部认证流程// 输入输出变量说明// InAuthP2 ;外部认证密钥号// ExAuthP2 ;外部认证主密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar ExAuthModule( uchar InAuthP2, uchar ExAuthP2, uchar LLCC ){ uchar cReturnFlag; cReturnFlag = GetRandom( LLCC ); TurnCardCommFlag(); cReturnFlag |= InternalAuth( InAuthP2, LLCC ); TurnCardCommFlag(); cReturnFlag |= ExternalAuth( ExAuthP2, LLCC ); return(cReturnFlag);}//----------------------------------------------------------------;// 外部认证流程(带分散)// 输入输出变量说明// InAuthP2 ;外部认证密钥号// ExAuthP2 ;外部认证密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar ExAuthModule1( uchar InAuthP2, uchar ExAuthP2, uchar LLCC ){ uchar cReturnFlag; //取随机数 if( GetRandom( LLCC ) ) { return(1); } vmemcpy( cDatRvBuffer, cDatBuffer+0x10, LLCC ); //ESAM分散密钥后加密随机数 TurnCardCommFlag(); if(DisExAuth( InAuthP2, CardBuffer.TradeRecord.cSeriBuffer, cDatBuffer+0x10 )) { return(1); } // TurnCardCommFlag(); return(ExternalAuth( ExAuthP2, LLCC ));}//----------------------------------------------------------------;// 密钥分散并加密// 输入输出变量说明// ExAuthP2 ;外部认证密钥号// DistrPtr ;分散因子地址// DataPtr ;外部认证数据// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar DisExAuth( uchar ExAuthP2, uchar *DistrPtr, uchar *DataPtr ){ uchar cReturnFlag; //分散密钥 cCLA = 0x80; cINS = 0xFA; cP1 = 0; cP2 = ExAuthP2; cLCLE = 8; vmemcpy( DistrPtr, cDatRvBuffer, 8 ); Nop(); cReturnFlag = cExeCommand( 13, cDatBuffer, &cCommRLenr, cDatRvBuffer ); //加密数据 cCLA = 0x80; cINS = 0xFA; cP1 = 0; cP2 = 0; cLCLE = 8; vmemcpy( DataPtr, cDatRvBuffer, 8 ); cReturnFlag = cExeCommand( 13, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 更新密钥// 输入输出变量说明// PP1 ;密钥类型// PP2 ;密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// cDatRvBuffer ;密钥密文// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar WriteKey( uchar PP1, uchar PP2, uchar LLCC ){ uchar cReturnFlag; cCLA = 0x84; cINS = 0xD4; cP1 = PP1; cP2 = PP2; cLCLE = LLCC; cReturnFlag = cExeCommand( LLCC+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 校验PIN// 输入输出变量说明// PP2 ;口令密钥号// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar VerifyPIN( uchar PP2 ){ uchar cReturnFlag; cCLA = 0x00; cINS = 0x20; cP1 = 0; cP2 = PP2; cLCLE = 0x02; cDatBuffer[5] = 0x12; cDatBuffer[6] = 0x34; //口令 cReturnFlag = cExeCommand( cLCLE+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 读记录文件// 输入输出变量说明// PP2 ;记录号(高5位)// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar ReadRecord( uchar PP2, uchar LLCC ){ uchar cReturnFlag;// cCLA = 0x00;// cINS = 0xB2;// cP1 = 0x01; cCLA = 0x80; cINS = 0x5C; cP1 = 0x00; cP2 = PP2; cLCLE = LLCC; cReturnFlag = cExeCommand( 5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// 扣减钱包// 输入输出变量说明// uDecMoney ;扣减金额(uint型)// 返回0--正确,返回1--错误// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar DecMoney( uint uDecMoney ){ uchar cReturnFlag; cCLA = 0x80; cINS = 0x30; cP1 = 0x01; cP2 = 0x14; cLCLE = 0x04; vmemcpy_p( &uDecMoney, cDatRvBuffer, 4 ); cReturnFlag = cExeCommand( cLCLE+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}//----------------------------------------------------------------;// MAC校验// 输入输出变量说明// PP1 ;密钥类型// PP2 ;密钥号// LLCC ;数据长度// 返回0--正确,返回1--错误// cDatRvBuffer ;密钥密文// 用到的全局变量// cDatBuffer ;命令数据区// cCommRLenr; ;命令接收长度/// 临时变量// returnflag ;返回标志//----------------------------------------------------------------;uchar CheckMAC( uchar AuthP2, uchar LLCC ){ uchar cReturnFlag; cCLA = 0x80; cINS = 0x4C; cP1 = 0; cP2 = AuthP2; cLCLE = LLCC+8; vClearStr( cDatBuffer+LLCC+5, 8 ); Nop(); cReturnFlag = cExeCommand( cLCLE+5, cDatBuffer, &cCommRLenr, cDatRvBuffer ); return(cReturnFlag);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -