lcd/USER/IC_API.c
2026-05-22 17:19:03 +08:00

1023 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}