【加密芯片】加密芯片——ATSHA204A的使用

閒扯一下

好久沒寫博客了,技術之路在於堅持,長期寫博客,總結, 是對自己一個不錯的鍛鍊,希望看到的博友能夠堅持下去,一起互勉。

前言

最近由於產品需要,加班加點完成了這個項目的預研。加密芯片的目的,哪裏都可搜索的到,這裏就不多說,主要談一些自己在接觸中的一些心得,以及技術備註,以便以後查閱和使用。

資料參考列表:

ATSHA204A加密芯片攻略——使用篇

atsha204a加密芯片使用攻略——配置篇

github源碼實例

配置

以下所講是如何直接使用,以及探討所實現過程中的問題解決,遺留問題。

GitHub源碼不建議直接運行,需要在理解的基礎上。自己的配置代碼如下:

void read_config(int fd, struct atsha204a_command_packet *command_packet)
{
    uint8_t status;
    //1.du入測試
    memset(readdata, -1, 32);
    cmd_args.op_code = command_packet->op_code;
    cmd_args.param_1 = command_packet->param1;
    cmd_args.param_2 = command_packet->param2;
    cmd_args.data_len_1 = command_packet->data_len;
    cmd_args.data_1 = command_packet->data;
    cmd_args.data_len_2 = 0;
    cmd_args.data_2 = NULL;
    cmd_args.data_len_3 = 0;
    cmd_args.data_3 = NULL;
    cmd_args.tx_size = 0x10;
    cmd_args.tx_buffer = global_tx_buffer;
    cmd_args.rx_size = 0x10;
    cmd_args.rx_buffer = global_rx_buffer;
    status = sha204m_execute(fd, &cmd_args);
    if (status != SHA204_SUCCESS) { printf(" Read data zone  FAILED! \n"); }
    else{ printf(" Read data zone  SUCCESS! \n"); }
    printf("read_data addr:%02x\n", command_packet->param2);
    printf_hex_array("readdata: ", 32, readdata);
    memcpy(readdata, &global_rx_buffer[1], 32);
    printf_hex_array("readdata: ", 32, readdata);
}
void write_config(int fd, struct atsha204a_command_packet *command_packet)
{
    uint8_t status;
    memset(readdata, -1, 32);
    cmd_args.op_code = command_packet->op_code;
    cmd_args.param_1 = command_packet->param1;
    cmd_args.param_2 = command_packet->param2;
    cmd_args.data_len_1 = command_packet->data_len;
    cmd_args.data_1 = command_packet->data;
    cmd_args.data_len_2 = 0;
    cmd_args.data_2 = NULL;
    cmd_args.data_len_3 = 0;
    cmd_args.data_3 = NULL;
    cmd_args.tx_size = 0x10;
    cmd_args.tx_buffer = global_tx_buffer;
    cmd_args.rx_size = 0x10;
    cmd_args.rx_buffer = global_rx_buffer;
    status = sha204m_execute(fd, &cmd_args);
    if (status != SHA204_SUCCESS) { printf(" Write data zone  FAILED! \n"); }
    else{ printf(" Write data zone  SUCCESS! \n"); }
    printf("read_data addr:%02x\n", command_packet->param2);
    printf_hex_array("readdata: ", 32, readdata);
    memcpy(readdata, &global_rx_buffer[1], 32);
    printf_hex_array("readdata: ", 32, readdata);
}
void my_config(int fd, uint8_t* key_15)
{
    static uint8_t status = SHA204_SUCCESS;
    uint8_t serect[32] = { 0 };	//the key of slot 0
    uint8_t tmp_conf[2];

    uint8_t data1[4] = { 0x80, 0xA0, 0x80, 0xA0 };
    int slot = 10;
    uint16_t slot_addr = (uint16_t)(10 * 8);

    //1.du入測試 0x05
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x05;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);

    //1.du入測試 SN
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x80;
    get_sn_command.param2 = 0x00;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);
    //1.du入測試 0x15
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x15;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);
    printf("===================開始配置========================\n");
    //1.config區配置solt0/1(key_15) 加密讀 加密寫 關聯的solt區爲 solt10(key_0)   
    printf("config區配置solt0/1\n");
    // data1[4] = { 0x8A, 0xA0, 0x8A, 0xA0 };
    data1[0] = 0x8A; data1[1] = 0xA0; data1[2] = 0x8A; data1[3] = 0xA0;
    get_sn_command.op_code = 0x12;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x05;
    get_sn_command.data_len = 4;
    get_sn_command.data = data1;
    write_config(fd, &get_sn_command);
    //1.du入測試 0x05
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x05;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);
    //2.solt10(key_0)  可隨意讀寫//鎖定後還能進行讀寫嗎?因該是不能寫
    printf("config區配置solt10/11\n");
    // data1[4] = { 0x00, 0x00, 0x00, 0x00 };
    data1[0] = 0x00; data1[1] = 0x00; data1[2] = 0x00; data1[3] = 0x00;
    get_sn_command.op_code = 0x12;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x0A;
    get_sn_command.data_len = 4;
    get_sn_command.data = data1;
    write_config(fd, &get_sn_command);
    //3.鎖定config區
    //3.1 讀取0x15地址配置信息
    printf("3.1 讀取0x15地址配置信息\n");
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x15;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);
    //3.2鎖定config區
    data1[0] = 0x00; data1[1] = 0x00; data1[2] = 0x55; data1[3] = 0x00;
    get_sn_command.op_code = 0x17;
    get_sn_command.param1 = 0x80;
    get_sn_command.param2 = 0x00;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    write_config(fd, &get_sn_command);
    //3.3 讀取0x15地址配置信息
    printf("3.3 讀取0x15地址配置信息\n");
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x15;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);//0x00 0x00 0x55 0x00 成功
    //4. 寫入祕鑰 slot 
    printf("4.1 讀取slot數據\n");
    slot_addr = (uint16_t)(0 * 8);
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x82;
    get_sn_command.param2 = slot_addr;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);
    //4.2 往slot0寫入祕鑰
    slot_addr = (uint16_t)(0 * 8);
    get_sn_command.op_code = 0x12;
    get_sn_command.param1 = 0x82;
    get_sn_command.param2 = slot_addr;
    get_sn_command.data_len = 32;
    get_sn_command.data = key_15;
    write_config(fd, &get_sn_command);
    //4.3 往slot10寫入祕鑰
    slot_addr = (uint16_t)(10 * 8);
    get_sn_command.op_code = 0x12;
    get_sn_command.param1 = 0x82;
    get_sn_command.param2 = slot_addr;
    get_sn_command.data_len = 32;
    get_sn_command.data = key_0;
    write_config(fd, &get_sn_command);
    //4.4 鎖定slot data區
    get_sn_command.op_code = 0x17;
    get_sn_command.param1 = 0x81;
    get_sn_command.param2 = 0x00;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    write_config(fd, &get_sn_command);
    //4.5 讀取0x15地址配置信息
    printf("4.5 讀取0x15地址配置信息\n");
    get_sn_command.op_code = 0x02;
    get_sn_command.param1 = 0x00;
    get_sn_command.param2 = 0x15;
    get_sn_command.data_len = 0;
    get_sn_command.data = NULL;
    read_config(fd, &get_sn_command);//0x00 0x00 0x00 0x00 成功

}

具體的配置意義可以詳細查看atsha204a加密芯片使用攻略——配置篇或者官方的Datasheet文檔。

遺留問題

當前調用驗證函數random_challenge_response_authentication(),出現驗證碼不一致的問題,幾經調整無果,其他的問題暫時沒有。

主要排除方法:更換mac命令的mode參數,使用temp_key或者使用slot區祕鑰來查看Mac後的digest結果,查看代碼生成驗證碼是否有誤。

當前驗證碼結果依然不一致,後期若解決再做記錄。

-------------------------------------------------------------------------------

驗證結果不一致排查:

1.檢查配置區是否存在問題;

2.檢查配置命令是否錯誤;

定位到:主機端生成驗證碼存在問題!更換主機端SHA256算法,結果驗證碼一致,驗證通過!!!

------------------------------------------------------------------------------

配置過程注意:

1.芯片的config區和data區一旦鎖定,沒有辦法解鎖,鎖的方法只能通過lock command來進行鎖定。配置錯誤,芯片基本之間廢了,我在這個過程中浪費了兩片。

2.config區在沒鎖定的時候,可以使用write command來進行寫操作,但注意,0x00-0x03地址(word地址,詳情請參考手冊)不能被寫,0x15word地址不能使用write command來寫。

3.在config鎖定前,data區(包括slot區和OTP區)既不能寫也不能讀。而在config鎖定後,data區鎖定前,data區只能寫不能讀,在data區鎖定後,可以根據config中的配置來進行讀寫。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章