之前的ATSHA204A芯片獲取SN的Demo程序已經寫完了,為了方便在以后項目中繼續使用這款加密芯片,於是把這個芯片的加密過程封裝成一個函數,以便繼續使用,本文中實現最基本的加密流程:
1、獲取芯片SN
2、發送Nonce命令,使IC生成隨機數並且更新TempKey,之后返回隨機數
3、發送Mac命令,使IC計算Mac碼
/*************************************************************************************** **************************************************************************************** * Project : ATSHA204A * FILE : atsha204a.c * Description : * * Copyright (c) 2017 by Han Jiawei. All Rights Reserved. * * History: * Version name Date Description * 0.01 Han Jiawei 2017/11/28 Initial Version * **************************************************************************************** ****************************************************************************************/ /*>>>>>>>>>>>>>> Section: Included Files <<<<<<<<<<<<<<*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "sha204_helper.h" #include "sha204_comm_marshaling.h" #include "atsha204a.h" /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*================================================================== * Function : MacSha204 * Description : Check Mac * Input Para : NULL * Output Para : NULL * Return Value : 0 : Check success other : Check fail ==================================================================*/ unsigned char MacSha204(void) { char stat = 0; // int i; struct sha204h_mac_in_out host_mac; //自己計算的Mac struct sha204h_nonce_in_out host_nonce; //自己計算的Nonce struct sha204h_temp_key temp_key; //tempkey //秘鑰 unsigned char secret_key[32] = { //“在這里填入你的秘鑰,必須為32位” }; //隨機數,你可以修改,但是一定要保證有32位 unsigned char challenge_key[32] = { 0x13, 0x68, 0x72, 0x20, 0x82, 0xde, 0xad, 0x8c, 0xe9, 0x14, 0x21, 0x87, 0xf5, 0x94, 0x24, 0xcd, 0xdd, 0xaa, 0x5c, 0xd5, 0x44, 0x3c, 0x08, 0x40, 0x35, 0xdf, 0xdb, 0x13, 0x67, 0x1b, 0xd3, 0x2f }; unsigned char Nonce_key[37] = {0}; //保存從IC獲取到的隨機數 unsigned char SN_Number[9] = {0}; //保存從IC獲取到的序列號 static unsigned char digest[32] = {0}; //保存MCU計算出來的摘要 unsigned char Mac_Slave[37] = {0}; //保存從IC獲取到的摘要 unsigned char Rand_out[32] = {0}; // //喚醒設備 unsigned char buf[1] = {0x00}; i2c_write(DEVICE_ADDR, buf, 1); delay_us(1000 * 2.5); //讀取設備喚醒后的返回值 unsigned char rbuf[5] = {0}; stat = i2c_read(DEVICE_ADDR, 0, rbuf, 4); if((rbuf[2] != 0x33) || (rbuf[3] != 0x43)) { return SHA204_WAKE_FAIL; } //發送讀取SN的命令 unsigned char command_buf[15] = {0}; command_buf[0] = 0x03; command_buf[1] = 0x07; command_buf[2] = 0x02; command_buf[3] = 0x00; command_buf[4] = 0x00; command_buf[5] = 0x00; sha204c_calculate_crc(5, &command_buf[1], &command_buf[6]); stat = i2c_write(DEVICE_ADDR, command_buf, 8); delay_us(1000 * 3); //讀取SN數據 第0~3位 memset(command_buf, 0, 15); stat = i2c_read(DEVICE_ADDR, 0, command_buf, 7); memcpy(SN_Number, command_buf + 1, 4); //發送讀取SN的命令 memset(command_buf, 0, 15); command_buf[0] = 0x03; command_buf[1] = 0x07; command_buf[2] = 0x02; command_buf[3] = 0x00; command_buf[4] = 0x02; command_buf[5] = 0x00; sha204c_calculate_crc(5, &command_buf[1], &command_buf[6]); stat = i2c_write(DEVICE_ADDR, command_buf, 8); delay_us(1000 * 3); //讀取SN數據 第4~7位 memset(command_buf, 0, 15); stat = i2c_read(DEVICE_ADDR, 0, command_buf, 7); memcpy(SN_Number + 4, command_buf + 1, 4); //發送讀取SN的命令 memset(command_buf, 0, 15); command_buf[0] = 0x03; command_buf[1] = 0x07; command_buf[2] = 0x02; command_buf[3] = 0x00; command_buf[4] = 0x03; command_buf[5] = 0x00; sha204c_calculate_crc(5, &command_buf[1], &command_buf[6]); stat = i2c_write(DEVICE_ADDR, command_buf, 8); delay_us(1000 * 3); //讀取SN數據 第8位 memset(command_buf, 0, 15); stat = i2c_read(DEVICE_ADDR, 0, command_buf, 7); memcpy(SN_Number + 8, command_buf + 1, 1); //檢測獲取SN是否成功 if((SN_Number[0] != 0x01) || (SN_Number[1] != 0x23)) { return SHA204_SN_FAIL; } //發送Nonce命令,並獲取隨機數 Nonce_key[0] = 0x03; Nonce_key[1] = 0x1B; Nonce_key[2] = 0x16; Nonce_key[3] = 0x01; Nonce_key[4] = 0x00; Nonce_key[5] = 0x00; memcpy(Nonce_key + 6, challenge_key, 20); sha204c_calculate_crc(25, &Nonce_key[1], &Nonce_key[26]); stat = i2c_write(DEVICE_ADDR, Nonce_key, 28); delay_us(1000 * 23); memset(Nonce_key, 0, 37); stat = i2c_read(DEVICE_ADDR, 0, Nonce_key, 37); //MCU根據隨機數以及SN計算Mac memcpy(Rand_out, Nonce_key + 1, 32); host_nonce.temp_key = &temp_key; //保存生成的TempKey host_nonce.mode = 0x01; //TempKey計算模式 host_nonce.num_in = challenge_key; //執行Nonce命令時輸入的隨機數 host_nonce.rand_out = Rand_out; //執行Nonce命令后返回的隨機數 stat = sha204h_nonce(&host_nonce); host_mac.mode = 0x41; //摘要的計算模式 host_mac.key_id = 0x00; //選擇秘鑰的槽 host_mac.temp_key = &temp_key; //參與計算的TempKey host_mac.sn = SN_Number; //參與計算的序列號 host_mac.response = digest; //保存生成的摘要 host_mac.key = secret_key; //參與計算的秘鑰 stat = sha204h_mac(&host_mac); //獲取芯片計算的mac command_buf[0] = 0x03; command_buf[1] = 0x08; command_buf[2] = 0x08; command_buf[3] = 0x41; command_buf[4] = 0x00; command_buf[5] = 0x00; command_buf[6] = 0x00; sha204c_calculate_crc(6, &command_buf[1], &command_buf[7]); stat = i2c_write(DEVICE_ADDR, command_buf, 9); if (stat < 0) { perror("Mac failed"); } delay_us(13 * 1000); stat = i2c_read(DEVICE_ADDR, 0, Mac_Slave, 37); //判斷是否讀取正確字節數的Mac值 if (Mac_Slave[0] != 0x23) { return SHA204_RX_FAIL; } //校驗認證 if(memcmp(digest, Mac_Slave + 1, 32) == 0) { return SHA204_SUCCESS; printf("mac success!\n"); } else { return SHA204_CHECKMAC_FAILED; printf("mac faile!\n"); } } /*************************************************************************************** * End of File: atsha204a.c ****************************************************************************************/
在頭文件中,需要配置I2C的讀寫函數、延時函數以及你需要用到的東西
如果你正好需要,在引用的同時,請記得標記代碼的出處!