痞子衡嵌入式:SNVS Master Key仅在i.MXRT10xx Hab关闭时才能用于DCP加解密
大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT系列中数据协处理器DCP使用SNVS Master Key加解密的注意事项。
i.MXRT不仅仅是处理性能超强的MCU,也是安全等级极高的MCU。如果大家用过痞子衡开发的一站式安全启动工具 NXP-MCUBootUtility,应该会从其 用户手册 3.3节中了解到i.MXRT支持的几种安全启动等级,其中HAB加密启动方式和BEE/OTFAD加密启动方式中都提及了一种神秘的密钥 - SNVS Master Key,今天痞子衡就跟大家聊聊这个密钥用于DCP模块的注意事项(文中仅以i.MXRT1060为例,其他RT10xx型号或许有微小差别)。
一、DCP模块简介
先来给大家科普下DCP模块,DCP是Data Co-Processor的简称,从名字上看是个通用数据协处理器。在i.MXRT1060 Security Reference Manual中有一张系统整体安全架构简图,这个简图中标出了DCP模块的主要功能 :CRC-32算法、AES算法、Hash算法、类DMA数据搬移。
看到DCP支持的功能,你就能明白其模块命名的由来了。本质上它就是一个数据处理加速器,如果说CRC-32/Hash算法只是算出一个结果(下图中Mode3),而AES算法则是明文数据到密文数据的转换(存在数据迁移,下图中Mode2),DMA式数据搬移则更明显了(下图中Mode1),DCP内部集成了memcopy功能,可以实现比普通DMA方式效率更高的内存到内存数据块搬移,memcopy功能还支持blit模式,支持传输矩形数据块到frame buffer用于LCD显示。
我们今天主要是聊DCP的AES加解密功能,其支持AES-128算法,包含Electronic Code Book (ECB)和Cipher Block Chaining (CBC)模式,算法标准符合 NIST US FIPS PUB 197 (2001)规范,AES运算的最小单元是16字节。
二、DCP-AES密钥来源
对于加解密而言,一个很重要的特性就是密钥管理。DCP的AES密钥(长度均为128bits)来源很丰富,按性质可分成四类:
- SRAM-based keys: 用户自定义的存放于SRAM中的密钥,最终会被写入DCP的KEY_DATA寄存器中,最多四组。
- Payload key: 用户自定义的跟加解密数据放一起的密钥,操作时DCP直接解析。
- eFuse SW_GP2 key: 用户烧录到eFuse SW_GP2区域的密钥,可锁定住让软件无法访问,但DCP可通过内置专用途径获取到。
- SNVS Master key: 芯片出厂时预存的唯一密钥,密钥值无法获知,DCP可通过内置专用途径获取到。
选用SRAM-based keys和Payload key仅需要在DCP模块内部配置即可,而选用eFuse SW_GP2 key和SNVS Master key则要在如下IOMUXC_GPR寄存器中额外设置。
IOMUXC_GPR_GPR10寄存器用于选择Key是来自eFuse SW_GP2还是SNVS Master Key:

IOMUXC_GPR_GPR3寄存器用于选择Key是来自SNVS Master Key(总256bits)的低128bit还是高128bit(注意此寄存器对eFuse SW_GP2其实不生效,因为SW_GP2仅128bits):

三、什么是SNVS Master Key?
SNVS全称Secure Non-Volatile Storage,它既是DCP的配套模块,也是芯片系统的安全事务监测中心。它能够提供一个独特的Master Key给DCP模块,这个Master Key可有三种产生方式(在SNVS_LPMKCR中设置):

- OTPMK:这种就是直接使用eFuse里出厂预烧录的OTPMK(256bits),这个OTPMK是每个芯片唯一的,并且被锁住了软件不可访问。
- ZMK:这种是利用存在SNVS_LP ZMKRx寄存器组中的密钥,该秘钥可由用户写入,此密钥在芯片主电源断掉时会继续保留(因为在LP域可由纽扣电池供电),在芯片受到安全攻击时密钥会被自动擦除。
- CMK:前两者组合后的Key,即OTPMK和ZMK的异或结果。
一般来说,使用最多的SNVS Master Key就是默认的OTPMK。
四、两种DCP驱动
关于DCP模块的驱动,在下载的芯片SDK包里有两种:
- ROM版本:\SDK_2.x.x_EVK-MIMXRT1060\devices\MIMXRT1062\drivers\fsl_dcp.c
- SDK版本:\SDK_2.x.x_EVK-MIMXRT1060\middleware\mcu-boot\src\drivers\dcp\fsl_dcp.c
middleware里的DCP驱动是ROM team负责的,他们是在芯片Tapeout之前写的,属于早期驱动;device包里的DCP驱动才是SDK team负责的,是芯片Tapeout之后写的,是正式版本。
两版驱动都实现了AES加解密,不过代码风格不同。比如ROM版本驱动的dcp_aes_ecb_crypt()函数同时支持加密和解密模式,而在SDK版本驱动里则分成两个函数:DCP_AES_EncryptEcb() - 加密 、DCP_AES_DecryptEcb() - 解密。
五、DCP正确获取SNVS Master Key
前面铺垫了那么多,终于来到正题了。DCP模块如何拿到正确的SNVS Master Key?让我们以\SDK_2.x.x_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\dcp 例程来做个测试。
这个dcp例程演示了五种DCP工作模式,我们就测试第一种TestAesEcb(),将宏DCP_TEST_USE_OTP_KEY改为1,即使用OTPMK低128bits作为DCP的密钥:
#define DCP_TEST_USE_OTP_KEY 1 /* Set to 1 to select OTP key for AES encryption/decryption. */
int main(void)
{
dcp_config_t dcpConfig;
// ...
/* Initialize DCP */
DCP_GetDefaultConfig(&dcpConfig);
#if DCP_TEST_USE_OTP_KEY
/* Set OTP key type in IOMUX registers before initializing DCP. */
/* Software reset of DCP must be issued after changing the OTP key type. */
DCP_OTPKeySelect(kDCP_OTPMKKeyLow);
#endif
/* Reset and initialize DCP */
DCP_Init(DCP, &dcpConfig);
/* Call DCP APIs */
TestAesEcb();
// ...
}
在初始芯片状态(Hab Open)下,使用J-Link下载工程进RAM直接单步调试看一看,在执行完DCP_AES_EncryptEcb()函数后查看cipher[]数组,可以看到其值为0xCF, 0x2E, 0xA3...,好吧我们根本不知道SNVS Master Key到底是多少,所以这个密文是否正确也无从知晓。
既然无法得知SNVS Master Key,那我们做个小实验,使用SRAM-based keys来做一次加密,密钥姑且设个全0吧,再看一下结果,你发现了什么,cipher[]的值是不是很熟悉?跟之前SNVS Master Key加密的结果一致,难道这颗芯片的SNVS Master Key是全0?想想不可能,肯定是流程哪里出了问题!
现在让我们再回忆 MCUBootUtility 用户手册里关于测试HAB加密以及BEE/OTFAD加密使用SNVS Master Key的前提条件,是的,芯片状态需要先设置为Hab Close,好,让我们现在在eFuse里将SEC_CONFIG[1:0]设为2'b10(Hab Close),然后再次使用J-Link调试进去看一看,怎么回事?cipher[]值依旧是0xCF, 0x2E, 0xA3...
上面的测试对TestAesEcb()函数做了一个简单的修改,将cipher[]值通过串口打印出来,那我们就将程序通过NXP-MCUBootUtility下载到Flash里由ROM来启动运行吧(退出调试状态),我们再来看串口打印,哈哈,终于值变了,这意味着DCP终于拿到了正确的SNVS Master Key(非0)。
总结一下,SNVS Master Key仅在芯片Hab状态是Close并且非调试状态下才能被DCP正常获取,否则DCP获取到的是全0的假Key。
至此,i.MXRT系列中数据协处理器DCP使用SNVS Master Key加解密的注意事项痞子衡便介绍完毕了,掌声在哪里~~~
欢迎订阅
文章会同时发布到我的 博客园主页、CSDN主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:SNVS Master Key仅在i.MXRT10xx Hab关闭时才能用于DCP加解密的更多相关文章
- 痞子衡嵌入式:利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是利用i.MXRT1xxx系列内部DCP引擎计算Hash值时需特别处理L1 D-Cache. 关于i.MXRT1xxx系列内部通用数据协处 ...
- 痞子衡嵌入式:对比MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MbedTLS算法库纯软件实现与i.MXRT上DCP,CAAM硬件加速器实现性能差异. 近期有 i.MXRT 客户在集成 OTA SBL ...
- 痞子衡嵌入式:i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计. 痞子衡之前两篇文章 <在SBL项目实战中妙用i ...
- 痞子衡嵌入式:i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同. 因为 i.MXRT 全系列 ...
- 痞子衡嵌入式:恩智浦MCU安全加密启动一站式工具NXP-MCUBootUtility用户指南
NXP MCU Boot Utility English | 中文 1 软件概览 1.1 介绍 NXP-MCUBootUtility是一个专为NXP MCU安全加密启动而设计的工具,其特性与NXP M ...
- 痞子衡嵌入式:语音处理工具Jays-PySPEECH诞生记(5)- 语音识别实现(SpeechRecognition, PocketSphinx0.1.15)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是语音处理工具Jays-PySPEECH诞生之语音识别实现. 语音识别是Jays-PySPEECH的核心功能,Jays-PySPEECH借 ...
- 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU外设那些事(2)- 善变的FlexRAM
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的FlexRAM外设. 本文是外设系列第二篇,上一篇讲的是离内核最近的高速缓存L1 Cache, ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(4)- 可重定向文件(.o/.a)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的relocatable文件(object, library). 前三节课里,痞子衡都是在给大家介绍嵌入式开发中的input文 ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(6)- 可执行文件(.out/.elf)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的executable文件(elf). 第四.五节课里,痞子衡已经给大家介绍了2种output文件,本文继续给大家讲proje ...
随机推荐
- 虚拟机 VMware 设置VMWARE通过桥接方式使用主机无线网卡上网
环境:WIN7旗舰版,台式机,U盘无线上网卡. 虚拟软件:VMware9.0,虚拟系统:CentOS6.4 需要实现虚拟机以独立机形式工作和上网. 先介绍一下VMware网络设置的三种方式 1 Hos ...
- BERT的前世今生
Transformer Transformer来自论文: All Attention Is You Need 别人的总结资源: 谷歌官方AI博客: Transformer: A Novel Neura ...
- 小师妹学JVM之:java的字节码byte code简介
目录 简介 Byte Code的作用 查看Byte Code字节码 java Byte Code是怎么工作的 总结 简介 Byte Code也叫做字节码,是连接java源代码和JVM的桥梁,源代码编译 ...
- Python实用笔记 (13)函数式编程——返回函数
函数作为返回值 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): ax = 0 for n in args: ax = ax + n ret ...
- RocketMQ入门到入土(二)事务消息&顺序消息
接上一篇:RocketMQ入门到入土(一)新手也能看懂的原理和实战! 一.事务消息的由来 1.案例 引用官方的购物案例: 小明购买一个100元的东西,账户扣款100元的同时需要保证在下游的积分系统给小 ...
- 教你如何开发一个完败Miracast的投屏新功能
手机与电视,是陪伴在我们生活最常见,陪伴最长久的智能设备.迅猛发展的移动终端与通信技术,赋予了手机更广阔多元的应用生态,大屏电视则以大视野和震撼影音,弥补了手里方寸带来的视觉局限.而今,手机的延伸 ...
- JavaScript基础初始时期分支(018)
Init-Time Branching初始时期分支是一种用做优化的模式.如果某些条件在程序启动后就不再改变,那么我们就只需要在初始时期检查一次就可以了,而不是在每次 需要用到这些条件的时候都检查一次. ...
- HTML重构与网页常用工具
下面这张思维导图,是我对全书大体内容的一个概括性总结: 工具 本书推荐的工具主要包含的是自动化测试,但是我觉得现行的开发环节当中实际用到的会比较少.这里就推荐一下其他方面的优秀工具: 1. YSlow ...
- STL初步学习(queue,deque)
4.queue queue就是队列,平时用得非常多.栈的操作是只能是先进先出,与栈不同,是先进后出,与之后的deque也有区别.个人感觉手写队列有点麻烦,有什么head和tail什么的,所以说 STL ...
- AcWing 走廊泼水节 题解
这道题大致题意就是让一棵树任意两点有连边(也就是完全图),但是补完后最小生成树是一开始的那棵树,问最小加的边权之和是多少. 了解题意后,我们可以想到用Kruskal(废话),当每两个集合合并的时候,除 ...