在這個IOT的時代,數據加密已經四處被提及了。安全性需求也日益增高。但是我們的linux主機的芯片,自身卻沒有帶ISO7816接口。這次由於客戶的需求,必須要加加密芯片,因此只能找尋類似於USB轉ISO7816, UART/SPI轉7816接口等芯片。搜來搜去,竟然搜到一顆AK9529,UART轉7816。。因此,就拿來用了。這顆芯片的資料不多,基本參數如下:
1. 默認使用38400,8,n,1接口,低位先發送。
2.該芯片支持同時接兩張卡,因此有slot0和slot1兩個接口
3.在數據幀結構上,採用循環冗餘校驗的方法。即文檔上所說的LCR。LRC: longitudinal redundancy check, which does the exclusive-or operation to each character in the string. For example, if a message of 3 bytes D1, D2, and D3. Then LRC of this message is D1 xor D2 xor D3, and the stream would be D1, D2, D3, and LRC.
以下是該芯片的整體工作流程:
第一步,發送getslotstatus指令對slot進行查詢,分別發送slot0的和slot1的。當發送slot0的時候,數據內容如下:
get_slot_status[11] = {0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65};
回覆如下:
81, 00, 00, 00, 00, 00, 00, 01, 00, 01, 81
根據0x81指令,其格式如下:
bStatus = 0x01, bError = 0x00, bClockStatus = 0x01. bStatus的值以及bError的值,分別查看table2和table3.
當bStatus = 0x01,表示一張卡片存在,並且未激活。
當bError = 0x00時,表示該命令執行成功。無錯誤產生。
於是發送第二條指令Poweron 指令0x62
poweron[11] ={0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62};
回覆數據如下:
80, 15, 00, 00, 00, 00, 00, 00, 00, 00, 3B, xx, xxxxxxxxxxxxx
查詢AK9529的命令手冊,可以得知,0x3B開始,就是卡片內部的數據交互了。爲了安全起見,將剩餘的報文用xx來表示。
到此,芯片驅動基本上打通了。剩下的就是慢慢完善所有的指令了。
在此特別注意,如果發送一些錯誤指令,讓芯片進入了錯誤狀態的話,芯片不會返回任何數據,即使你後來發的是正確的數據。此時,似乎只有重新上電或則將AK9529復位纔可以恢復。可能也是爲了安全性考慮。
另外,如下是整體命令的表格。發送指令和回覆指令相互對應關係如下:
以下是我的測試代碼:
const unsigned char get_slot_status[11] = {0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x65};
const unsigned char Poweron[11] ={0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62};
void main(void)
{
int uart_fd;
int ret;
char RxBuffer[256];
int i;
uart_fd = Uart_Init_Port("/dev/ttyS1", 38400, 8, 'n', 1);
while(1)
{
sleep(1);
write(uart_fd, &Poweron[0], 11);
usleep(100000);
while(1)
{
ret = read(uart_fd, RxBuffer, 256);
if (ret > 0)
{
for (i = 0; i < ret; i++)
{
printf("%02X, ", RxBuffer[i]);
}
}
else
{
printf("\r\n");
break;
}
}
}
}