嵌入式产品硬件加密芯片的工作原理总结

date
Aug 6, 2024
slug
2024-08-06-Security-Chips-in-Embedded-System
status
Published
tags
嵌入式
加密技术
type
Post
AI summary
嵌入式产品的硬件加密芯片通过加密算法和密钥存储区保护敏感信息,确保系统安全。工作流程包括密钥写入、随机码生成、加密和验证。高级加密芯片如MicroChip的ATECC608提供更全面的安全功能,包括密钥管理和Secure Boot。使用独立加密硬件可防止敏感信息被破解,成为IoT产品的标准配置。ATECC608的应用逻辑涵盖了在嵌入式MCU和Linux平台上的集成,提供了安全的加解密操作。
summary
本文对嵌入式产品中经常使用的防抄板类型的加密芯片和更高级的加密通信和身份验证的加密芯片做了总结。并且以广泛使用的ATECC608加密芯片为例,通过网络资料的学习,整理了该加密芯片方案在嵌入式MCU和Linux系统中的应用逻辑和大体流程。
基本上,硬件加密芯片在嵌入式产品中的应用主要包含以下两种类型:
  • 初级的防抄板应用。
  • 更高级的加解密、硬件身份验证方面的应用。
本文简单介绍前者的完整工作原理和流程,把主要的篇幅放在对于后者,也就是更高级的加解密与身份验证类型的加密芯片的学习和总结上。

防抄板加密芯片的工作流程和原理

对于市场上简单的防抄板应用类型的加密芯片而言,市场上可以选择的芯片非常多,国产的占了很大一部分,价格在几毛和几块钱之间。主要提供的功能就是,在一个相对比较简单的产品上,增加一个防抄板的加密芯片,避免有人完整的拷贝这个产品的软件和硬件。
这种类型的产品应用,主要是在硬件设计上加一个I2C或者串口、SPI等接口加密芯片,在系统SOC中的软件运行时,系统SOC与这个加密芯片通过以上接口通信,交换一些数据,由系统SOC的软件运行逻辑来检测加密芯片的存在以及内部烧写密钥的正确性,系统SOC只有与加密芯片之间的交互流程验证通过后才会正常运行,否则就会直接关机。
因为加密芯片内部烧写的密钥信息无法提取出来,这样的话,即使有人能够成功硬件抄板以及把flash里面的固件镜像文件完整读出来并写入自己抄的板子上,在缺乏加密芯片支持的情况下,系统SOC在启动和初始化过程中会因为检测加密芯片失败而无法正常运行,由此提供了对这个产品软硬件的保护。
从工作原理的本质上看,这类防抄板的加密芯片实际上就是一个包含加密算法和密钥存储区的简单芯片而已。加密算法一般就是共享密钥的加密算法,例如AES等,算法的加密密钥与FW代码验证流程所使用的密钥一致,一旦写入加密芯片,既不可读出也不可修改。加密芯片和FW端的验证算法使用相同的密钥对每次启动随机生成的字符串信息进行加密然后比较,由此来验证加密芯片的存在以及其中写入密钥的正确性。
大体上,这类防抄板的加密芯片的工作流程流程大致如下:
  • 首先在生产过程中需要向加密芯片写入一个密钥,这个密钥会在加密芯片和FW的代码里面共同使用。**注意,加密芯片的密钥一旦写入就不可更改,所以这一步的写入非常关键,一旦写错就只能报废了。**
  • 主控芯片生成随机码,一般是基于当前时间信息所生成的动态随机码
  • 主控芯片把以上随机码的明文通过两者之间的接口发给加密芯片
  • 加密芯片通过其内部的加密算法硬件,配合出场之前烧写的生产密钥,对随机码明文进行加密生成密文
  • 加密芯片返回密文给主控芯片
  • 主控芯片对加密芯片返回的密文,利用加密芯片供应商的加解密库以及自己的生产密钥,进行解密生成明文
  • 主控芯片对解密后的明文与之前明文随机码进行对比, 比较值一致则认证通过,认证不通过则进行关机操作
为了支持以上操作,一般情况下加密芯片的供应商需要提供:
  • 未烧录密钥的加密芯片,及其参考设计。
  • FW端的加密算法库。如果使用通用加密算法的话,也可以不提供,直接使用开源的算法实现即可。
  • 加密芯片密钥的烧录器。加密芯片也可以设计一次性写入密钥的I2C指令时序,工厂端在生产时由产测软件按照时序写入,这样就不需要专门的烧录器了。

高级加密芯片

这类所谓的高级加密芯片,除了能够支持基本的防抄板方面的功能以外,还提供了比较完整的加解密算法、密钥/证书管理、硬件随机数产生器、Secure Boot等支持,从而为嵌入式产品SOC端实现更完整的安全保护提供硬件方面的支持。
以MicroChip的ATECC608为例,这个使用非常广泛的安全芯片方案提供的功能如下:
notion image
总结起来就是:
  • 密钥存储区,最多可以存储16组独立的密钥、证书和其他需要加密的数据
  • 配合SOC端软件的接口和执行流程,可以实现非对称算法加解密、认证、临时密钥管理乃至完整TLS的功能
  • 硬件加密算法:AES128,SHA256等
  • Secure boot支持
  • 硬件的随机数产生器
首先要搞清楚一个问题,我们的嵌入式产品中,为什么要通过这类专门的加密硬件来进行保护?可能有很多人会认为,如何我们在嵌入式软件的设计中,采用了AES、RAS、ECC这类国际标准的高强度加密算法对于我们的通信内容以及数据进行保护,这个保护强度就足够了,而且不少SOC本身已经内置了AES加解密硬件的支持,所以在一个性能性能相对比较强大的处理器面前,直接在SOC的硬件中执行这些标准加密算法并不会成为系统的瓶颈所在,那额外的增加成本去使用独立的加密硬件的意义何在?
原因是,无论我们的嵌入式产品使用的是对称性加密算法还是基于公私钥体系的加密算法,这些密钥如何保存是系统安全性设计最大的问题。AES、RAS这类国际标准的加解密算法强度当然是足够的,但是与这里算法匹配使用的共享密钥、公钥私钥对、证书文件等内容需要保存到一个安全的地方,才能保证产品的安全性设计无懈可击。但是如果没有独立的硬件加密芯片,绝大多数系统设计都是把这类敏感信息写入Flash使用自定义加密的方式进行保存,这样实际上存在极大的安全性隐患。黑客完全可以拆解flash,读取其中保存的这类敏感信息(共享密钥,私钥证书文件等),就可以对产品的通信内容进行解密。这就是对于一个完善的安全性设计的系统而言,需要增加额外的独立加密芯片的原因,把所有的敏感信息全部存入不可被破解和读取的硬件加密芯片中,甚至连加解密的操作也都是这个独立的加密硬件中执行,加密硬件和系统SOC之间所传输的都是加密后的密文,黑客想要轻易破解就成为不可能完成的任务。
因此,通过这类高级的加密芯片对于嵌入式产品的安全敏感信息进行保护,逐渐成为市场上IoT产品的标配,这也是Google、Amazon、Microsoft这类IoT云平台供应商所推荐的方式。IoT产品接入这类云平台,会针对每一台接入设备生成公私钥对,这个公私钥对应该写入IoT产品的独立硬件加密芯片中进行安全保护,后续的加密通过就全部由硬件加密芯片与IoT Cloud之间进行交互,既简化了系统的安全性设计,又提高了系统整体设计的安全强度。
当然增加额外的加密硬件,肯定会增加系统的BOM成本和软硬件开发调试的工作量,但是具体是否要加,就要看产品对于安全性的要求来进行判断。

ATECC608A在产品中的应用逻辑

注:因为手头上缺乏必要的测试硬件,以下信息来源于对网络资料的学习和总结,可能存在不确切的误导信息,仅供系统设计层面上的参考使用。
说到目前在嵌入式产品上所使用的广泛的高级加密芯片,MicroChip的ATECC608系列几乎是绕不开的。甚至国内做这类加密芯片的厂家,都已经做出来在硬件可以与ATECC608 pin2pin兼容,甚至软件上也可以直接复用CryptoAuthLib的国产替代品(例如国产的Mod8ID),这样就大大降低了之前之前ATECC608加密方案切换的难度和工作量。
所以以ATECC608为例,搞清楚了这类高级加密芯片在嵌入式产品开发中的应用逻辑,基本上也就对这类高级加密芯片在产品设计中如何使用来提供更高强度的安全保护,有了比较系统和完整的理解。
为了支持ATECC系列的开发和应用,MicroChip专门在Github上维护了一个支持这个安全芯片系列的跨平台C语言编程库cryptoauthlib,链接地址为:。无论是对嵌入式MCU还是基于嵌入式Linux的软件开发,最终都是要基于这个cryptoauthlib来执行对加密芯片硬件的直接访问。

对加密芯片的配置

与以上防抄板类型的加密芯片使用一样,在应用程序逻辑中真正使用加密芯片进行安全防护之前,首先要按照自己应用的需求,对加密芯片内部的配置信息和敏感数据信息(例如各种密钥、证书文件以及其他敏感信息)进行写入操作并且锁定芯片。同样的,一旦芯片的内部配置信息写入并锁定以后,其中的配置信息就不能再更改,所以在调试中需要当心。
对于ATECC608芯片内部配置和安全数据信息的写入操作,同样是通过调用cryptoauthlib库中的API接口来进行。
ATECC608的内部数据存储区包含两个两个部分:配置部分(Config Zone),数据部分(Data Zone)。
  • 其中Config zone部分固定为128个字节,其中前16个字节是不可写入的,配置区的信息主要用于配置Data Zone中各个slot中保存的数据。因此配置区的信息理解上相对比较负责,建议是直接在官方提供的config数据模板上根据自己的要求进行修改,避免出错。
  • Data Zone部分则包含16个slot,每个slot可以根据Config Zone对应的配置信息指定其中存储的安全信息内容。各个slot中可以存放的数据类型如下,例如一般使用slot 9存放AES key。
notion image
以上的Config Zone和Data Zone信息确定以后,可以调用cryptoauthlib库中的atcab_write_bytes_zone或者atcab_write_zone函数写入加密芯片。写入以上信息并且锁定芯片(锁定操作通用是通过调用cryptoauthlib里面的atcab_lock_config_zone以及atcab_lock_data_zone等API)以后,加密芯片在硬件上就做好准备了。
加密芯片配置和安全数据的写入,应该是在产品出厂之前在产测阶段,通过调用cryptoauthlib库中的API接口来完成。

ATECC608在嵌入式MCU产品中的应用逻辑

参考文档3中提供了一个基于Arduino平台使用ATECC608实现系统硬件加密的方案设计,以下为对该文档的学习笔记总结。
在参考文档3中有一个使用加密芯片进行AES加密的例子,当前使用加密芯片进行AES加密的前提是在前一步<对加密芯片的配置>中已经完成了对AES Key的写入并锁定了芯片。
接下来在MCU中进行AES加密的操作就比较简单了,大体流程是:
  • 初始化:调用ATCA_STATUS atcab_init (ATCAIfaceCfg *cfg)进行初始化
  • 初始化设置AES算法:调用ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv)选择加密要使用的AES key在哪个slot(在key_id指定),这个slot所存放的第几个16字节AES key(在key_block指定),以及加密执行需要的初始向量iv。
  • AES128加密:调用ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext)进行AES128的加密。因为ATECC608只支持AES算法128bit的加密,所以每次调用送入的明文plaintext固定是16字节,得到的密文ciphertext也就是固定的密文16字节。需要加密的数据多于128字节的话,就需要自行在应用层进行分拆成多次调用。
  • AES128解密:调用ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext)进行AES128解密。传递参数与加密一样,都是只能一次性处理固定的16字节。
以上完整的AES加解密的流程就完全在ATECC608的加密芯片硬件中完成,使用I2C传递明文进去,然后再使用I2C读出密文,解密也是相同的道理。加密算法和密钥都在硬件加密芯片上,整个产品的安全性就无懈可击。
当然,要能够在嵌入式MCU中执行以上流程,前提是能够把cryptoauthlib库移植到嵌入式MCU硬件上正常运行起来,不过cryptoauthlib库是跨平台的纯C代码,已经针对目前市场上所使用的各种MCU有了大量的移植案例,具体移植库的操作可以参考官方文档和网络搜索的资料。

ATECC608在嵌入式Linux平台产品中的应用逻辑

参考文档4和5中提供了一个基于树莓派平台和Linux使用ATECC608实现系统硬件加密的方案设计,以下为对该文档的学习笔记总结。
在嵌入式Linux系统上使用ATECC安全方案,与在嵌入式MCU的使用全然不同的操作逻辑。不同于嵌入式MCU直接调用cryptoauthlib库中的加解密接口,在嵌入式Linux系统中,这类硬件安全解决方案一般都是要结合OpenSSL这类通用的软件安全方案一起来进行使用,利用ATECC系列芯片为OpenSSL的运行提供独立硬件上运行的加解密运算、密钥管理和存储、随机数产生等方面的支持。
如前所述,如果没有硬件加密芯片的存在,使用OpenSSL进行加密通信时,不可避免地就要把私钥、证书、共享密钥这类信息保存在Flash的某个文件系统中的位置,这方面存在的隐患是纯软件的安全解决方案最大的漏洞所在。使用ATECC这类独立的硬件方案,则可以给OpenSSL的运行提供安全便捷的硬件基础,密钥等敏感信息不再是保存至Flash中,而是直接保存在加密芯片里面,硬件加密芯片通过各种编译和配置后,只是给OpenSSL的运行提供安全硬件的基础,用户层的应用程序仍然是在OpenSSL运行,这样的安全架构对于应用层程序是无感的,无论是使用软件还是硬件的加密方案,或者使用哪一家的硬件加密芯片,只要通过配置后能够与OpenSSL配合使用,应用层的程序就不需要做任何修改,这种模式自然是受产品开发商的欢迎。
以上所描述的OpenSSL与硬件加密芯片之间的标准接口就是PKCS#11。所幸的是,Microchip在cryptoauthlib的设计上已经做了不少事情,来方便的实现这个PKCS#11接口,以建立与OpenSSL等的无缝通信,也就是说经过适当的配置和交叉编译以后,cryptoauthlib实际上可以作为一个标准的PKCS #11 Provider来使用。
在嵌入式Linux平台下使用ATECC608的大致流程是:
  • 交叉编译cryptoauthlib库,使能ATCA_OPENSSL、ATCA_PKCS11等编译选项,编译后生成动态链接库libcryptoauth.so,并安装到/usr/lib/下。
  • 交叉编译libp11第三方库并安装。
  • 修改cryptoauthlib库的配置文件,在/var/lib/cryptoauthlib目录下<slot number>.conf。在这个配置文件中定义ATECC608加密芯片的I2C器件地址,以及各个data slot的配置信息内容位置:即私钥、证书文件、公钥等所在的slot number。
  • 使用gnutls-bin中的p11tool工具尝试与libcryptoauth.so及其硬件加密信息通信,读取当前的加密芯片信息配置是否正确:
    • $ p11tool --provider /usr/lib/libcryptoauthlib.so --list-all
  • 修改OpenSSL的配置文件openssl.cnf,修改其使用PKCS#11接口(即指定前面libp11编译所生成的libpkcs11.so所在的位置)以及设置其中的PKCS #11 provider为libcryptoauth.so。
  • 至此OpenSSL-PKCS#11-cryptoauthlib的整体配置就完成了,后续的OpenSSL的操作就可以直接访问到硬件加密芯片了。后续就可以调用OpenSSL的命令行工具生成密钥以及进行一些双向加密认证测试方面的验证了。此时基于OpenSSL的应用程序也就可以正常工作了。

参考文档:

 

© Pavel Han 2020 - 2024