ATSHA204A加密芯片是ATMEL公司研发的一款高安全性的,功能丰富的加密IC,使用SHA-256算法进行加密操作,内置16*32字节的slot(EEPROM)可以存储用户数据和秘钥,唯一的9字节序列号用于区分其他芯片,还有512bits的OTP区用于保存一些固定信息。芯片对外有2中通信方式,分别是单bus和i2c方式,本文所演示的全部使用I2C方式,但所有功能使用单bus方式也可以实现。
芯片管脚图非常简单,如下
这个是ATSHA204A的SOIC封装,只需要电源,地,I2C的SCL和SDA这4根线即可,SCL和SDA需要上拉电阻。
首先我先讲一下SHA-256到底是个什么东东。
安全散列算法SHA(Secure Hash Algorithm)是美国国家安全局 (NSA) 设计,美国国家标准与技术研究院(NIST) 发布的一系列密码散列函数,包括 SHA-1、SHA-224、SHA-256、SHA-384 和 SHA-512 等变体。主要适用于数字签名标准(DigitalSignature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA),
SHA算法最主要的特点就是,任意长度的输入能生成固定长度的输出,并且从输出的结果中不能还原输入的内容,而且要找到不同两个输入导致相同输出的情况在计算上不能实现。
ATSHA204A使用的SHA256算法,能输出32字节(256位)的固定长度输出,基于SHA算法的特性,我们完全可以做到程序启动的秘钥验证,或者服务端和客户端的秘钥验证来保护我们产品。
废话说了一些,以下看一下如何使用I2C操作这款芯片,本文是假设已经对芯片进行默认配置的情况下来进行操作的,默认配置为如下,
秘钥保存在slot0,SlotConfig0.Bit12 = 0(表示在运行DeriveKey Command时,使用目标slot区的秘钥进行SHA256计算而不是使用指定的parentkey)。然后对芯片的锁定,锁定后不能再对配置区进行修改,而数据区可根据配置来使用其他命令更新,详细请见下篇——配置篇。
对ATSHA204A操作时,首先要对设备进行唤醒操作,唤醒操作如下
SDA线保持低电平60us,芯片退出休眠状态,然后再等待2.5ms后,才能开始接受命令。
在发送I2C数据的时候,发送完设备地址后,应该发送一个word_address来指示这个包有何用处。如下
在芯片手册中已经注明了其他命令的作用,对芯片的操作主要使用command,即0x03来操作。
command有很多种,在验证秘钥的时候往往需要使用几种命令。
一般来说,我们用到的有这几个
DerriveKey:更新一个slot区中的秘钥命令。
Nonce:使用随机数来更新TempKey中的值
CheckMAC:验证一个摘要是否计算正确,返回的是Bool值类型(0是正确,1是错误)
MAC:使用SHA-256计算并返回一个摘要。
Read:读取芯片区域中的数据。
Write:写入芯片区域中的数据。(这个命令一般用在配置时)
其他命令相对来说使用比较少,而且其他有些命令也相对简单好理解,但并不意味它们是没有作用的,因篇幅问题,本文介绍几个命令。
从字面命令上来理解,这里是随机命令的意思,的确如此。这个命令目的在于更新芯片中的TempKey值,什么是TempKey,可以这样理解,TempKey就类似于我们程序中的临时变量,来保存一些中间结果用的,但这个TempKey值不能被访问,只能芯片内部自己使用。
首先介绍Nonce命令也因为它是其他多数命令执行前都要执行的一个命令。
Nonce命令如上
比较关注于Param1 mode,其他都是固定的值
mode介绍如下
好理解,0或者1的时候,需要我们输入一个20字节的随机数,然后更新芯片内的seed,更新seed能使内部产生的随机数质量更高。2值不被允许,3的话就要求输入32字节的随机数,直接写在TempKey中。
我们配置如下
opcode = 0x16,
mode = 0x01,
zero = 0x0000,
numin = 20字节随机数
当命令正确执行的时候
将返回32字节的由芯片产生的randout随机数,如果mode = 0x03,只返回Bool值。
使用MAC命令可以让ATSHA204生成一个摘要。
如图
比较关注的是Param1 mode
好像很复杂,不用担心,复杂的问题我们把他简化就好了。
mode.bit0控制的是使用Tempkey计算还是直接使用Data中的Challenge来计算返回的digest。
mode.bit1控制的是使用slot区中的值计算还是Tempkey中的值来计算返回的digest。
mode.bit2如果bit0或bit2设置了,那么此位要匹配Tempkey.sourceflag位匹配。也就是说,使用了nonce命令的话,如果nonce命令中的nonce.mode == 0x00 或者0x01,这里就等于0, 如果nonce.mode == 0x03,这里就等于1。
mode.bit3 = 0
mode.bit4和mode.bit5 是选择是否使用OTP中的的值来参与计算,个人觉得意义不大而且增加了配置时的复杂程度。设置为0就好了。
mode.bit6是使用序列号来参与计算,可以设置。
mode.bit7 = 0
本人设置如下
opcode = 0x08
mode = 0x01|0x06
slotid = 0
challenge = 0
发送过去后,如果执行正常,会返回一个32字节的digest结果,这个结果的计算如下
芯片内部会根据一系列的值去计算这个32字节的digest。
有什么用?
看到这里大家可能有这个疑问,返回这个值有什么用?我要拿来做什么?
别急,我为大家讲一个防程序拷贝的流程措施。
假设我们很辛苦的开发了程序,但是又不想被别人盗用劳动成果(执行文件被拷出来,抄个板继续使用)。我们就要在启动的时候验证一下是否通关,不通关就不往下走。流程如下:
首先我们ATSHA204A芯片的slot0中写入一个32字节的秘钥,设置为不可读。这个秘钥只有几个人知道,并且不外泄,主控MCU与芯片相连,在启动时候,首先我们要获取芯片序列号,为后面计算MAC。然后我们发送一个nonce命令给ATSHA204A,让其更新内部的TempKey中的值,MCU内部也根据nonce的模式计算一下Tempkey的值,我们称之为host_tempkey,如果一切正常,那么Tempkey和host_tempkey中的值是一致的,接下来MCU自己就可以根据host_tempkey、序列号、以及秘钥计算,出一个摘要digest,我们称之为digest1,接下来给ATSHA204A发送MAC命令,ATSHA204A根据存储在slot区域中的秘钥来计算digest2并返回给MCU,MCU判断digest1和digest2是否匹配,不匹配将程序挂起即可。
有几个关键点要注意一下:
1、在I2C总线上并没有传送秘钥,而是传送根据秘钥和一些列的值计算出来的digest,因此在总线上截获秘钥不可实现。
2、在自己的MCU上也存了秘钥,别人获取了16进制文件后是否有可能得到秘钥,我只能说,的确存了,但是对于一个庞大的程序hex文件中寻找一个32字节的秘钥,岂不是大海捞针?
3、在MCU上自己也要使用SHA-256算法计算摘要,怎么实现,这个问题放心,在ATMEL官网上有已经实现好的库,可以直接使用,但是这个库在移植上有些问题需要改一下,本人已经移植好了基于stm32f103的版本,完全正常使用,并且带有中文注释,移植只需要修改几个接口即可,有想业务合作的可以私信。
4、在使用nonce时,要发送一个随机数给ATSHA204A,如果担心随机数质量不好,可以使用ATSHA204A的Random命令,就可以返回一个32字节的高质量的随机数来使用,也可以用作其他用途。
5、是否有破解的可能?对于一些小单片机(51之类的),的确好破,反汇编后,跳过验证步骤即可,但是stm32之类的强大功能单片机就不是那么回事,首先如果你能反汇编,也得找出验证步骤在哪里,其次,我也不知道stm32有没人做过反汇编,因此,只要秘钥不泄露,要破解起来个人觉得也很难。毕竟这个可是军方用过的东西。
这个命令与MAC命令几乎一样。只不过使用的算法不一致,而且根据芯片手册上介绍,效率也低。因此这里不在论述。
这个命令也是带有验证功能的,简单来讲,就是让你计算好digest,发给ATSHA204A,然后ATSHA204A告诉你这个digest算的对不对,返回bool值
如下
看了之前命令介绍,这里大家都应该很明白了,
为了方便起见,例子如下
mode = 0
SlotID = 0
ClientChal = 32字节,这里MCU可以发送一个32字节的随机数
ClientResp = 32字节,这里就是MCU自己计算好的digest,发给ATSHA204
OtherData = 13字节如下
不使用OTP,有关OTP的参数全部给0就好了
ClientResp 的计算要依据下面
在官方库里面也封装好了相关操作,直接拿来用即可。
如果一切正常,ATSHA204A返回的0,计算digest不对就返回1。
这个CheckMAC命令的作用,我个人觉得其中一个作业就是是去验证密码。比如有一个主设备,它把秘钥存在slot0里面,有一些从设备,要输入正确的密码才能使用主设备提供的服务,就可以用这种方式,这种方式在总线上也不会传输密码,而且把密码存在ATSHA204A里面更安全(其他诸如flash,eeprom容易被盗取)。
这个命令从字面上理解,就是变化Key的命令意思,的确,可以通过这个命令去更新slotid中的key。
这个命令内容简单,但是理解起来比较费劲,根据手册,介绍如下
简单讲,就是slot.slotconfig[TargetKey].bit13要设置成1,否则DeriveKey将返回错误,然后如果slot.slotconfig[TargetKey].bit12为0
要更新的秘钥值将是TempKey和原先的秘钥值计算出来的,slot.slotconfig[TargetKey].bit12为1,则是TempKey和slot.slotconfig[TargetKey].WriteKey中指定的SlotID的值计算出来的。
另外,如果SlotConfig[TargetKey].bit15设置了的话,还需要输入
一个MAC摘要,即如下
以上都是配置阶段配置好的,不能修改,而发送这个命令时带如下参数即可,
因为要用到TempKey,所以Nonce在DeriveKey命令执行前,需要被正确的执行,才能更新到TempKey中的值。
新的秘钥由以下计算出来。
而MCU自己也可以计算出这个新的秘钥作为使用。
当我们原有的秘钥泄露的时候,可以使用这个命令来产生新的秘钥继续使用。
另外如果slot.slotconfig[TargetKey].bit12为1和SlotConfig[TargetKey].Bit15为1还有SlotConfig[ParentKey].SingleUse为1的时候(ParentKey为slot.slotconfig[TargetKey].WriteKey),则UseFlag[ParentKey]为0的时候,DeriveKey将返回失败,也就是说,我个人理解UseFlag[ParentKey]就是指示剩余使用的次数,一旦这个次数为0,那么将不能使用这个ParentKey去生成其他TargetKey。
这两个命令在配置阶段用的较多,这两个命令在我的下一篇,配置篇将会讲到。
配置篇地址为:http://blog.csdn.net/a5882230/article/details/52214845
至此,ATSHA204A芯片的基本使用也介绍完毕,基于这么多种命令,我们可以把这个芯片用在很多地方,如防抄板,密码验证,消耗产品的匹对等等,当然还有其他一些功能这篇文章没有介绍到,感兴趣的朋友可以去完整的读一遍datesheet,不过现在只有英文版的。
因个人工作原因,本人制作的烧录器已不再卖,如果任何使用的问题均可以联系我。