ATSHA204A在OBD产品中的防克隆应用

该博客介绍了ATSHA204A安全芯片在车载OBD产品中的应用,如何利用其防止软硬件克隆。文章详细阐述了ATSHA204A的功能,与Microchip的PIC18F25K80 MCU的接口,以及如何通过SHA256身份验证实现防克隆机制。还提到了单总线通信的实现细节和软件实现SHA256算法的挑战。
摘要由CSDN通过智能技术生成

ATSHA204A在OBD产品中的防克隆应用

随着行业的技术发展和需求,车载OBD产品中有部分会增加蓝牙BLE和手机APP联系。兼于总体成本和成熟度的综合因素,目前市面上的OBD产品大都使用Microchip的PIC18F25K80。

基本框图如下所示:
在这里插入图片描述
PIC18F25K80是Microchip高性能的8位MCU,内置了ECAN模块,支持超低功耗模式。集成了常用的UART, SPI, I2C等接口,用于和外围器件通信。
详见如下链接:
https://www.microchip.com/wwwproducts/en/PIC18F25K80

由于目前国内对知识产权保护方面仍然不够完善,各个公司之间都是互相借鉴甚至直接克隆软硬件,使真正投入资源开发这类产品的公司遭受了巨大的损失。
我们知道,单纯依靠MCU本身的Flash锁定位来防止别人读出Flash中的内容已不足以防止别人的抄袭,此时只能依靠外部增加硬件的安全芯片来保护自己的设计不被非法克隆。
Microchip的ATSHA204A可以满足些类需求,详细资料可以在下面的链接中找到。
https://www.microchip.com/wwwproducts/en/ATSHA204A
ATSHA204A是支持硬件保护的安全芯片,能提供安全的存贮区域来保护用户的密钥和其它重要数据,并且支持SHA256的硬件加速引擎来完成身份验证等功能。是实现软硬件防克隆,IP保护,配件耗材管控的理想方案。
为了方便客户的硬件设计,ATSHA204A提供了丰富的封装选项,从最通用的SOIC8到最小尺寸的UDFN8(2*3mm)。
UDFN8, SOIC8, TSSOP8, SOT323, 3 PADS contact
在这里插入图片描述
和MCU的接口支持通用的I2C接口或单总线接口,占用MCU的脚位非常少。
ATSHA204A支持很宽的工作电压范围,2.0V~5.5V,和MCU的接口电压从1.8V到5.5V。可以非常方便地适配到大部分的系统中。

ATSHA204A内部有16个Slot可以存放数据,每个Slot都可以根据需要做不同的配置。由于这里只是演示简单的身份验证过程,只需要用一个Slot来保存密钥。可以使用ACES和CK101来对204做Provision,Slot 0用来保存密钥,所以需要设置成不可读,不可写。配置如下,
在这里插入图片描述
其它的Slot可以配置成可读可写的,这样就可以当作E2PROM来保存用户数据。

把配置区锁定后,就可以向Slot0中写入密钥。之后再把数据区锁定。
只有配置和数据区都锁定以后才能正常执行验证的完整过程。

AN_8834 - ATSHA204 Authentication Modes 中可以了解使用SHA256做身份验证的基本过程
在这里插入图片描述
上图是可以把Alice理解成MCU,Bob理解成外加的ATSHA204A安全芯片。
预先会在SHA204A中写入密钥,如上图中的Shared Key;
在现场验证时,MCU会产生一个随机数,将随机数发给ATSHA204A做Crypto Hash运算(实际上就是对密钥和随机数来做了SHA256的运算,产生一个HASH值);
同时MCU也会用代码做同样的运算(对密钥和随机数执行软件的SHA256运算,也会产生一个HASH值)
MCU等待一段时间后读取SHA204A的运算结果,和自己的结果做对比;
如果一致就可以认为外部的SHA204A是合法的,程序可以正常运行。否则就不运行。
所以,这里有两点需留意:

  1. MCU中需要保存密钥
  2. MCU中需要用软件来实现SHA256的算法

由于MCU中有保存密钥,所以密钥最好不要以明文形式存在,可以打散放置或做一些转化,如用位或非操作等。在需要验证前现场恢复密钥。
如果MCU中没有好的随机数生成器,可以用SHA204A来生成随机数Rm。为防止重复质询攻击,MCU需要对随机数Rm做一些处理,增加一些随机因子。比如用ADC来采样的数据替换Rm中的某些字节。再做一次SHA256运算得到Hm,用结果Hm来发起质询验证。

客户这个案子使用的是SOT23封装的单总线接口的ATSHA204A, 所以大部分的工作都是在实现MCU和SHA204A的单总线通信。
单总线的时序需求非常严格,逻辑位0和逻辑位1是通过不同的脉冲来区分的。如果开发过红外遥控的编解码程序应该对这种不会陌生。
在这里插入图片描述
在这里插入图片描述

MCU中实现单总线有两种方式:

  1. 使用7位UART, 230400bps 来模拟单总线时序。这种方式需要MCU支持7位数据模式,PIC18系列刚好不支持。当时花了很长时间验证,发现只能从MCU发送到204A, 204A发给MCU的数据不能正常接收。后来就改用I/O口模拟的方式。(实际上UART也是可以正常接收的,需要将接收时的波特率提高到300000bps以上,稳定性待验证)
    在这里插入图片描述
  2. I/O口模拟。MCU的发送很简单,使用Nop延时即可。难的是接收部分,后面再详细讲。

MCU使用4MHz外部晶振,通过PLL倍频到16MHz。为了提高检测脉冲宽度的精度,使用TMR1来对SWI的脉宽测量,最小宽度63nS, 最大测试宽度为4ms,可以满足要求。
在这里插入图片描述

和时序相关的延时函数如下,都是通过等待TMR1的超时中断位来实现的:

void delay(uint16_t delay)
{
    // Clearing IF flag.
    PIR1bits.TMR1IF = 0;
    TMR1H = (delay >> 8);
    TMR1L = delay & 0xFF;
    T1CONbits.TMR1ON = 1;
    while(!PIR1bits.TMR1IF);
    PIR1bits.TMR1IF = 0;
    T1CONbits.TMR1ON = 0;    
}

void delay_ms(uint16_t ms)
{
    while(ms --)
    {
        // Clearing IF flag.
        PIR1bits.TMR1IF = 0;
        TMR1H = 0xC1;
        TMR1L = 0xA0;
        T1CONbits.TMR1ON = 1;
        while(!PIR1bits.TMR1IF);
    }

    T1CONbits.TMR1ON = 0;
    PIR1bits.TMR1IF = 0;
}

204A在每次操作之前都必须唤醒Wake,具体做法是将数据线拉低超过60uS即可,直接调用delay来实现。由于TMR1为累加到0xFFFF时就会产生溢出中断,所以实际延时周期是0xFFFF-X:

void swi_wake_token()
{
    SDA_OUTPUT();
    SDA_LOW();
    delay(0xFFFF - 1000);
    SDA_HIGH();
}

由于时序的要求,发送数据中途不能被中断打扰,所以必须关掉全局中断。MCU发送数据串的函数如下:

void swi_send_bytes(uint8_t count, uint8_t *buffer)
{
    uint8_t i, bit_mask;

    INTERRUPT_GlobalInterruptDisable();

    for(i = 0; i < count; i++)
    {
        for(bit_mask = 1; bit_mask > 0; bit_mask <<= 1)
        {
            if(bit_mask & buffer[i])    //!< Send Logic 1 (7F)
            {
                SDA_LOW();
                delay(0xFFFF - 2);
                SDA_HIGH();
                delay(0xFFFF - 410);    //310
            }
            else     //!< Send Logic 0 (7D)
            {
                SDA_LOW();
                delay(0xFFFF - 2);
                SDA_HIGH();
                delay(0xFFFF - 2);
                SDA_LOW();
                delay(0xFFFF - 2);
                SDA_HIGH();
                delay(0xFFFF - 310);    //225
            }
        }
    }
    INTERRUPT_GlobalInterruptEnable();
}

MCU接收部分就比较复杂,每检测到SDA脚上有电平变化时就开始TMR1计时,等到下次变化时对计时做出有效性判断。为了提高容错性,可以对判断的范围适当放宽一点。如果产生了超时中断,则说明收到逻辑1或者超时出错了:

ATCA_STATUS swi_receive_bytes(uint8_t *buffer, uint8_t length)
{
   
    ATCA_STATUS status = ATCA_SUCCESS;
    uint8_t i;
    uint8_t bit_mask;
    uint8_t pulse_count;
    uint16_t pulse_length;

    SDA_INPUT();
    INTERRUPT_GlobalInterruptDisable();

    PIR1bits.TMR1IF = 0; 
    TMR1H = 0;
    TMR1L = 0;
    T1CONbits.TMR1ON = 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值