1023 lines
23 KiB
C
1023 lines
23 KiB
C
#include "public.h"
|
||
#include "define.h"
|
||
#include "common.h"
|
||
#include "usboperate.h"
|
||
#include "ctranscode.h"
|
||
|
||
extern int icdev;
|
||
unsigned char MAIN_KEY[16];
|
||
unsigned char bufw[8192];
|
||
unsigned char bufr[8192];
|
||
//IC卡的唯一标识
|
||
unsigned char IC_Number[32];
|
||
void Check_LRC(unsigned char *BCD,unsigned short LEN);
|
||
#if 0
|
||
static int write_main_key(char*key)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x18+5; //LEN
|
||
|
||
bufw[pos++]=0x80; //CLA
|
||
bufw[pos++]=0xD4; //INS
|
||
bufw[pos++]=0x00; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=0x18; //Lc
|
||
bufw[pos++]=0x00; //KID
|
||
bufw[pos++]=0x01; //版本
|
||
bufw[pos++]=0x00; //标示
|
||
bufw[pos++]=0x08; //用途
|
||
bufw[pos++]=0x0F; //使用权限
|
||
bufw[pos++]=0x0F; //后续状态
|
||
bufw[pos++]=0xFF; //修改权限
|
||
bufw[pos++]=0x88; //错误记数
|
||
memcpy(bufw+pos,key,0x10);
|
||
pos+=0x10;
|
||
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("write_main_key:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
|
||
}
|
||
|
||
|
||
#endif
|
||
void Check_LRC(unsigned char *BCD,unsigned short LEN)
|
||
{
|
||
unsigned short i;
|
||
unsigned short Si=0,Qi=0;
|
||
|
||
for(i=0;i<LEN;i++)
|
||
{
|
||
Qi+=*(BCD+i);
|
||
Si+=Qi;
|
||
}
|
||
*(BCD+LEN)=Si>>8;
|
||
*(BCD+LEN+1)=Si;
|
||
}
|
||
|
||
int chk8024(void)
|
||
{
|
||
int ret,pos=0;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x45; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x01; //LEN
|
||
|
||
bufw[pos++]=0x00; //poweron
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("IC_poweron:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write sdb failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read hid failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
return 0;
|
||
}
|
||
/****************************************************
|
||
** Funcname: poweron
|
||
** Function: IC卡上电
|
||
** Input:
|
||
** Output: 无
|
||
** Returning Values: 无
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int poweron(unsigned char *ATR)
|
||
{
|
||
int ret,pos=0;
|
||
int len = 0;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x43; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x01; //LEN
|
||
|
||
//bufw[pos++]=0x00; //poweron
|
||
bufw[pos++]=0x02; //reset
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("IC_poweron:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0)
|
||
{
|
||
printf("write sdb failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0)
|
||
{
|
||
printf("read hid failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00)
|
||
{
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
len = bufr[6]*0x100+bufr[7]-1;
|
||
memcpy(ATR,(bufr+9),len);
|
||
return 0;
|
||
}
|
||
|
||
|
||
int select_EF(char file_name[2])
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x07; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0xA4; //INS
|
||
bufw[pos++]=0x02; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=0x02; //Lc
|
||
bufw[pos++]=file_name[0]; //data
|
||
bufw[pos++]=file_name[1]; //data
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("select_EF:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
}
|
||
|
||
static int read_binary(unsigned short offset,char *data_out,unsigned char* data_len)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x05; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0xB0; //INS
|
||
bufw[pos++]=((offset>>8)&0x7F); //P1
|
||
bufw[pos++]=(unsigned char)offset; //P2
|
||
bufw[pos++]=*data_len; //Lc
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("read_binary:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
*data_len=read_data_len-3;
|
||
memcpy(data_out,bufr+9,*data_len);
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
}
|
||
|
||
static int update_binary(unsigned short offset,char * Data_in,unsigned char Data_len)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=Data_len+5; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0xD6; //INS
|
||
bufw[pos++]=((offset>>8)&0x7F); //P1
|
||
bufw[pos++]=(unsigned char)offset; //P2
|
||
bufw[pos++]=Data_len; //Lc
|
||
memcpy(bufw+pos,Data_in,Data_len);
|
||
pos+=Data_len;
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("update_binary:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
}
|
||
|
||
static int get_challenge(char Data_len,char *out_data)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x05; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0x84; //INS
|
||
bufw[pos++]=0x00; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=Data_len; //Lc
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("get_challenge:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
memcpy(out_data,bufr+9,Data_len);
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
}
|
||
#if 0
|
||
static int get_response(unsigned char Data_len,char *out_data)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x05; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0xC0; //INS
|
||
bufw[pos++]=0x00; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=Data_len; //Lc
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("get_response:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
memcpy(out_data,bufr+9,Data_len);
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
}
|
||
#endif
|
||
static int Verify(unsigned char*Pin,unsigned char PinLen)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=PinLen+5; //LEN
|
||
|
||
bufw[pos++]=0x00; //CLA
|
||
bufw[pos++]=0x20; //INS
|
||
bufw[pos++]=0x00; //P1
|
||
bufw[pos++]=0x03; //P2
|
||
bufw[pos++]=PinLen; //Lc
|
||
memcpy(bufw+pos,Pin,PinLen);
|
||
pos+=PinLen;
|
||
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("verify:\t\n",bufw,pos);
|
||
#endif
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
|
||
}
|
||
|
||
|
||
|
||
static int change_crypt_key(char*key)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=0x18+5; //LEN
|
||
|
||
bufw[pos++]=0x80; //CLA
|
||
bufw[pos++]=0xD4; //INS
|
||
bufw[pos++]=0x01; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=0x18; //Lc
|
||
bufw[pos++]=0x02; //KID // ////////////////////////////////////////////////////////////////////////////////////
|
||
bufw[pos++]=0x01; //版本
|
||
bufw[pos++]=0x00; //标示
|
||
bufw[pos++]=0x0A; //用途
|
||
bufw[pos++]=0x33; //使用权限
|
||
bufw[pos++]=0x00; //后续状态//无效
|
||
bufw[pos++]=0x3F; //修改权限
|
||
bufw[pos++]=0x88; //错误记数
|
||
memcpy(bufw+pos,key,0x10);
|
||
pos+=0x10;
|
||
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("change_crypt_key:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
|
||
}
|
||
|
||
|
||
static int change_pin(unsigned char*Pin,unsigned char PinLen)
|
||
{
|
||
int ret,pos=0;
|
||
int read_data_len;
|
||
|
||
memset(bufr,0,sizeof(bufr));
|
||
memset(bufw,0,sizeof(bufw));
|
||
memcpy(bufw,"\x55\xaa\x88\x66",4);
|
||
pos=4;
|
||
bufw[pos++]=0x00; //SEQ
|
||
bufw[pos++]=0x44; //TAG
|
||
bufw[pos++]=0x00; //LEN
|
||
bufw[pos++]=PinLen+8+5; //LEN
|
||
|
||
bufw[pos++]=0x80; //CLA
|
||
bufw[pos++]=0xD4; //INS
|
||
bufw[pos++]=0x01; //P1
|
||
bufw[pos++]=0x00; //P2
|
||
bufw[pos++]=PinLen+8; //Lc
|
||
bufw[pos++]=0x03; //KID // ////////////////////////////////////////////////////////////////////////////////////
|
||
bufw[pos++]=0x01; //版本
|
||
bufw[pos++]=0x00; //标示
|
||
bufw[pos++]=0x0B; //用途
|
||
bufw[pos++]=0x0F; //使用权限
|
||
bufw[pos++]=0x03; //后续状态
|
||
bufw[pos++]=0x3F; //修改权限
|
||
bufw[pos++]=0x88; //错误记数
|
||
memcpy(bufw+pos,Pin,PinLen);
|
||
pos+=PinLen;
|
||
|
||
Check_LRC(bufw+4,pos-4);
|
||
pos+=2;
|
||
bufw[pos++]=3;
|
||
#ifdef IC_DEBUG
|
||
PrintHex("change_pin:\t\n",bufw,pos);
|
||
#endif
|
||
|
||
ret = USBWrite(icdev,bufw,pos,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("write failed!\n");
|
||
return -1;
|
||
}
|
||
ret = USBRead(icdev,bufr,1200,SCSI_TIMEOUT);
|
||
if(ret<0){
|
||
printf("read failed! ret = %d",ret);
|
||
return -1;
|
||
}
|
||
#ifdef IC_DEBUG
|
||
PrintHex("ret:\t\n",bufr,bufr[6]*0x100+bufr[7]+11);
|
||
#endif
|
||
|
||
if(bufr[8]!=0x00){
|
||
printf("ret code failed! ret = %d\n",bufr[8]);
|
||
return -1;
|
||
}
|
||
read_data_len=bufr[6]*0x100+bufr[7];
|
||
return bufr[6+read_data_len]*0x100+bufr[7+read_data_len]; //return sw
|
||
|
||
}
|
||
|
||
int write_memery_data(unsigned short offset,char * data_in, unsigned short in_len)
|
||
{
|
||
unsigned short i;
|
||
|
||
if(in_len == 0)
|
||
return -1;
|
||
|
||
for(i=0; i<in_len/0x80; i++){
|
||
if(update_binary(offset+i*0x80,data_in+i*0x80,0x80)!=0x9000)
|
||
return -2;
|
||
}
|
||
if(in_len%0x80 !=0){
|
||
if(update_binary(offset+i*0x80,data_in+i*0x80,in_len%0x80)!=0x9000)
|
||
return -2;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************
|
||
** Funcname: read_memery_data
|
||
** Function: 写相应机构传输密钥
|
||
** Input: 机构名称、密钥值
|
||
** Output: 无
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int read_memery_data(unsigned short offset,char * data_out, unsigned short out_len)
|
||
{
|
||
unsigned short i;
|
||
unsigned char read_len;
|
||
|
||
if(out_len == 0)
|
||
return -1;
|
||
|
||
for(i=0; i<out_len/0x80; i++){
|
||
read_len=0x80;
|
||
if(read_binary(offset+i*0x80,data_out+i*0x80,&read_len)!=0x9000)
|
||
return -2;
|
||
}
|
||
read_len=out_len%0x80;
|
||
if(read_len !=0){
|
||
if(read_binary(offset+i*0x80,data_out+i*0x80,&read_len)!=0x9000)
|
||
return -2;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/****************************************************
|
||
** Funcname: write_trans_key
|
||
** Function: 写相应机构传输密钥
|
||
** Input: 机构名称、密钥值
|
||
** Output: 无
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int write_trans_key(char *index_str,unsigned char str_len,char * data_in,unsigned short in_len)
|
||
{
|
||
unsigned char pkg[0x100];
|
||
unsigned char index_input[0x10];//while str_len<=0x10
|
||
unsigned char head[0x10];
|
||
unsigned char read_len;
|
||
unsigned short TOTAL,INDEX_TAIL,DATA_TAIL;
|
||
unsigned short index_adr,data_adr,data_len,counter_indexed_tag,pkg_counter;
|
||
unsigned short i;
|
||
|
||
if(str_len > 0x10)
|
||
return -1;
|
||
if(in_len == 0)
|
||
return -1;
|
||
|
||
|
||
read_len=0x10;
|
||
if(read_binary(0x00,(char *)head, &read_len)!=0x9000)
|
||
return -3;
|
||
|
||
TOTAL=head[0]*0x100+head[1];
|
||
INDEX_TAIL=head[2]*0x100+head[3];
|
||
DATA_TAIL=head[4]*0x100+head[5];
|
||
|
||
counter_indexed_tag=0;
|
||
index_adr=INFO_END;
|
||
data_adr=INDEX_END;
|
||
for(;counter_indexed_tag<TOTAL;index_adr+=pkg_counter){
|
||
read_len=0xff;
|
||
pkg_counter=0;
|
||
if(read_binary(index_adr,(char *)pkg, &read_len)!=0x9000)
|
||
return -4;
|
||
while(1){
|
||
if(pkg_counter+1+1 > 0xff)
|
||
break;
|
||
if(pkg_counter+1+1+pkg[pkg_counter+1] > 0xff)
|
||
break;
|
||
if(counter_indexed_tag >= TOTAL)
|
||
break;
|
||
if(pkg[pkg_counter] != TAG)
|
||
return -5;
|
||
data_adr=pkg[pkg_counter+2]*0x100+pkg[pkg_counter+3];
|
||
data_len=pkg[pkg_counter+4]*0x100+pkg[pkg_counter+5];
|
||
if(pkg[pkg_counter+1]-4 == str_len){
|
||
if(memcmp(pkg+pkg_counter+6,index_str,str_len) == 0){ //找到索引
|
||
if(data_len != in_len)
|
||
return -6; //目标数据长度与写入数据长度不等,
|
||
goto _finded;
|
||
}
|
||
}
|
||
data_adr += data_len;
|
||
pkg_counter+= pkg[pkg_counter+1] +2;
|
||
counter_indexed_tag++;
|
||
}
|
||
}
|
||
TOTAL++;
|
||
head[0]=TOTAL/0x100;
|
||
head[1]=TOTAL%0x100;
|
||
|
||
if(INDEX_TAIL !=index_adr)
|
||
return -72;
|
||
INDEX_TAIL=index_adr+6+str_len;
|
||
if(INDEX_TAIL > INDEX_END-0x100)
|
||
return -7;
|
||
head[2]=INDEX_TAIL/0x100;
|
||
head[3]=INDEX_TAIL%0x100;
|
||
|
||
if(DATA_TAIL !=data_adr)
|
||
return -71;
|
||
DATA_TAIL=data_adr+in_len;
|
||
if(DATA_TAIL > DATA_END-0x100)
|
||
return -8;
|
||
head[4]=DATA_TAIL/0x100;
|
||
head[5]=DATA_TAIL%0x100;
|
||
|
||
if(update_binary(0x00,(char *)head,0x10)!=0x9000)
|
||
return -10;
|
||
|
||
index_input[0]=TAG;
|
||
index_input[1]=4+str_len;
|
||
index_input[2]=(data_adr)/0x100;
|
||
index_input[3]=(data_adr)%0x100;
|
||
index_input[4]=(in_len)/0x100;
|
||
index_input[5]=(in_len)%0x100;
|
||
memcpy(index_input+6,index_str,str_len);
|
||
|
||
if(update_binary(index_adr,(char *)index_input,index_input[1]+2)!=0x9000)
|
||
return -12;
|
||
_finded:
|
||
for(i=0;i<in_len/0x80;i++){
|
||
if(update_binary(data_adr+i*0x80,data_in+i*0x80,0x80)!=0x9000)
|
||
return -14;
|
||
}
|
||
if(in_len%0x80 !=0){
|
||
if(update_binary(data_adr+i*0x80,data_in+i*0x80,in_len%0x80)!=0x9000)
|
||
return -14;
|
||
}
|
||
return 0;
|
||
}
|
||
/****************************************************
|
||
** Funcname: read_trans_key
|
||
** Function: 读取相应机构密钥值
|
||
** Input: 机构名称
|
||
** Output: 密钥值
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
|
||
int read_trans_key(char *index_str,unsigned char str_len,char * data_out,unsigned short *out_len)
|
||
{
|
||
unsigned char pkg[0x100];
|
||
unsigned char head[0x10];
|
||
unsigned char read_len;
|
||
unsigned short TOTAL;
|
||
unsigned short index_adr,data_adr,counter_indexed_tag,pkg_counter;
|
||
unsigned short i;
|
||
|
||
if(str_len > 0x10)
|
||
return -1;
|
||
|
||
|
||
read_len=0x10;
|
||
if(read_binary(0x00,(char *)head, &read_len)!=0x9000)
|
||
return -3;
|
||
|
||
TOTAL=head[0]*0x100+head[1];
|
||
// INDEX_TAIL=head[2]*0x100+head[3];
|
||
// DATA_TAIL=head[4]*0x100+head[5];
|
||
|
||
counter_indexed_tag=0;
|
||
index_adr=INFO_END;
|
||
data_adr=INDEX_END;
|
||
for(;counter_indexed_tag<TOTAL;index_adr+=pkg_counter){
|
||
read_len=0xff;
|
||
pkg_counter=0;
|
||
if(read_binary(index_adr,(char *)pkg, &read_len)!=0x9000)
|
||
return -4;
|
||
while(1){
|
||
if(pkg_counter+1+1 > 0xff)
|
||
break;
|
||
if(pkg_counter+1+1+pkg[pkg_counter+1] > 0xff)
|
||
break;
|
||
if(counter_indexed_tag >= TOTAL)
|
||
break;
|
||
if(pkg[pkg_counter] != TAG)
|
||
return -5;
|
||
if(pkg[pkg_counter+1]-4 == str_len){
|
||
if(memcmp(pkg+pkg_counter+6,index_str,str_len) == 0){ //找到索引
|
||
data_adr=pkg[pkg_counter+2]*0x100+pkg[pkg_counter+3];
|
||
*out_len=pkg[pkg_counter+4]*0x100+pkg[pkg_counter+5];
|
||
for(i=0; i<*out_len/0x80; i++){
|
||
read_len = 0x80;
|
||
if(read_binary(data_adr+i*0x80,data_out+i*0x80,&read_len)!=0x9000)
|
||
return -6;
|
||
}
|
||
read_len = *out_len%0x80;
|
||
if(read_len != 0){
|
||
if(read_binary(data_adr+i*0x80,data_out+i*0x80,&read_len)!=0x9000)
|
||
return -6;
|
||
}
|
||
return 0;
|
||
}
|
||
}
|
||
pkg_counter+= pkg[pkg_counter+1] +2;
|
||
counter_indexed_tag++;
|
||
}
|
||
}
|
||
return -7;
|
||
}
|
||
/****************************************************
|
||
** Funcname: IC_poweron
|
||
** Function: 更改口令
|
||
** Input: 新口令
|
||
** Output: 无
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int IC_poweron(void)
|
||
{
|
||
int ret;
|
||
unsigned char ATR[32]={0};
|
||
int IC_ID=0;
|
||
unsigned char i = 0;
|
||
|
||
if(chk8024() < 0)
|
||
return -1; //no card
|
||
if(poweron(ATR) < 0)
|
||
return -2; //poweron fail
|
||
|
||
memset(IC_Number, 0, sizeof(IC_Number));
|
||
//memcpy(IC_Number, ATR, sizeof(ATR));
|
||
Byte2String(8, ATR + 8, IC_Number);
|
||
#if 0
|
||
int l= 0;
|
||
printf("IC_poweron start\n");
|
||
for(l = 0; l < sizeof(bufr); l++)
|
||
{
|
||
printf("%02x ", bufr[l]);
|
||
}
|
||
printf("IC_poweron end\n");
|
||
|
||
printf("ATR start\n");
|
||
for(l = 0; l < 32; l++)
|
||
{
|
||
printf("%02x ", ATR[l]);
|
||
}
|
||
printf("ATR end\n");
|
||
#endif
|
||
ret = select_EF("\xEF\x02");
|
||
if((ret != 0x9000)&&((ret &0x6100)!=0x6100))
|
||
return -3; //card err//卡片结构异常
|
||
for(i=0;i<4;i++)
|
||
{
|
||
IC_ID *= 0x100;
|
||
IC_ID += ATR[12+i];
|
||
}
|
||
return IC_ID;
|
||
}
|
||
|
||
/****************************************************
|
||
** Funcname: CARD_PRESSENT
|
||
** Function: 更改口令
|
||
** Input: 新口令
|
||
** Output: 无
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int CARD_PRESSENT(void)
|
||
{
|
||
char card_challenge[8];
|
||
|
||
memset(card_challenge,0,8);
|
||
if(get_challenge(4,card_challenge)!=0x9000)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
/****************************************************
|
||
** Funcname: IC_crypt_change
|
||
** Function: 更改数据加密密钥
|
||
通过用户口令认证或管理口令认证才能使用
|
||
** Input: 加密密钥明文,16字节
|
||
** Output:
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int IC_crypt_change(char*key)
|
||
{
|
||
if(change_crypt_key(key)!=0x9000)
|
||
return -1;
|
||
else
|
||
return 0;
|
||
}
|
||
int IC_PIN_verify(char * PIN_str, unsigned char PIN_len)
|
||
{
|
||
int ret = 0;
|
||
if((PIN_len >6 )||(PIN_len < 2))
|
||
return -1;
|
||
ret = Verify((unsigned char *)PIN_str,PIN_len);
|
||
if(ret == 0x6983)
|
||
return -2;//locked
|
||
if(ret == 0x9000)
|
||
return 0;
|
||
if((ret &0xFFF0) == 0x63C0)
|
||
return (ret&0x0F);
|
||
return 0;
|
||
|
||
|
||
}
|
||
|
||
/****************************************************
|
||
** Funcname: IC_init
|
||
** Function: IC卡上电复位
|
||
** Input: none
|
||
** Output: 加密机型号、角色类型
|
||
** Returning Values: 0-success
|
||
** Author:
|
||
** Amendment Record:
|
||
***************************************************/
|
||
int Read_hsm_model(char * data_out,char * data_len)
|
||
{
|
||
*data_len=0x10;
|
||
|
||
if(read_binary(0x10,data_out,(unsigned char *)data_len)!= 0x9000)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
int Read_role_type(char * data_out,char * data_len)
|
||
{
|
||
*data_len=0x10;
|
||
|
||
if(read_binary(0x20,data_out,(unsigned char *)data_len)!= 0x9000)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
int CARD_format(char* hsm_model)
|
||
{
|
||
//unsigned char main_key_new[16];
|
||
|
||
char zero[0x80];
|
||
//int i,ret = 0;
|
||
|
||
if(change_pin((unsigned char *)default_pin_str,6)!=0x9000)
|
||
return -2;
|
||
|
||
memset(zero,0,0x80);
|
||
//for(i=0;i<0x3D00/0x80;i++){
|
||
//if(update_binary(i*0x80,zero,0x80) != 0x9000) //必须写过后才能读操作
|
||
// return -1;
|
||
// }
|
||
|
||
if(update_binary(0x10,hsm_model,0x10) != 0x9000)
|
||
return -1;
|
||
|
||
|
||
if(update_binary(0x00,"\x00\x00\x01\x00\x10\x00",0x06) != 0x9000)
|
||
return -1;
|
||
|
||
|
||
return 0;
|
||
}
|
||
int reg_cardholder(char* role_type)
|
||
{
|
||
if(update_binary(0x20,role_type,0x10)!=0x9000)
|
||
return -1;
|
||
|
||
return 0;
|
||
}
|
||
|
||
int reg_dev(char record_num,char* HSM)
|
||
{
|
||
if((record_num >= 0x0D)||(record_num < 0x00))
|
||
return -3;
|
||
|
||
if(update_binary((record_num+3)*0x10,HSM,0x10)!=0x9000)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
|
||
int read_reg(char data_out[0x0D][0x10])
|
||
{
|
||
unsigned char data_len=0;
|
||
|
||
data_len=0xD0;
|
||
if(read_binary(0x30,data_out[0],&data_len)!=0x9000)
|
||
return -1;
|
||
return 0;
|
||
}
|
||
|
||
|