ATSHA204A校验方法库


之前的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的读写函数、延时函数以及你需要用到的东西

 

如果你正好需要,在引用的同时,请记得标记代码的出处!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM