之前的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的读写函数、延时函数以及你需要用到的东西
如果你正好需要,在引用的同时,请记得标记代码的出处!