加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

DCP如何正确获取神秘的SNVS Master Key?

2020/07/17
167
阅读需 13 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是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-MIMXRT1060devicesMIMXRT1062driversfsl_dcp.c

 

SDK 版本:SDK_2.x.x_EVK-MIMXRT1060middlewaremcu-bootsrcdriversdcpfsl_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-MIMXRT1060boardsevkmimxrt1060driver_examplesdcp 例程来做个测试。

 

这个 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 加解密的注意事项痞子衡便介绍完毕了,掌声在哪里~~~

相关推荐

电子产业图谱

硕士毕业于苏州大学电子信息学院,目前就职于恩智浦(NXP)半导体MCU系统部门,担任嵌入式系统应用工程师。痞子衡会定期分享嵌入式相关文章