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

📄 7816.c

📁 cpu卡驱动程序,带ESAM模块认证,已经调试通过的
💻 C
📖 第 1 页 / 共 2 页
字号:
//
  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 + -