👹
Carlos's Tech Blog
  • 🧔ECUs
    • ZYNQ_Documents
      • [ZYNQ] 构建ZYNQ的BSP工程
      • [ZYNQ] 启动流程
      • [ZYNQ] Secure Boot Flow
      • [ZYNQ] Provisioning Guideline
      • [ZYNQ] Decrypting Partition by the Decrypt Agent Using PUF key
      • [ZYNQ] enabling the cryptsetup on ramdisk
      • [ZYNQ] Encrypt external files based on file system using PUF key
      • [ZYNQ] Loading an Encrypted Linux kernel at U-Boot with a KUP Key
      • [ZYNQ] cross-compile the cryptsetup on Xilinx ZYNQ aarch64 platform
      • [ZYNQ] Linux Linaro系统镜像制作SD卡启动
    • S32G_Documents
      • [S32G] Going through the s32g hard/soft platform
      • [S32G] S32g247's Secure Boot using HSE firmware
        • S32g2 HSE key config
        • How S32g verify secure boot image
        • S32g secure boot signature generation
        • How to download and build S32g Secure boot image
        • [S32G] OTA with Secure Boot
    • RT117x_Documents
      • [RT-117x]IMX RT1170 Provisioning Guideline
      • [RT-117x] Going through the MX-RT1170 hard/soft platform
      • [RT-117x] i.MX-RT1170's Secure Boot
        • [RT-117x]Signing image with the HSM (SignServer)
    • LS104x_Documents
      • [LS104x] bsp project
      • [LS104x] boot flow
      • [LS104x] secure boot
      • [LS104x] Application Note, Using the PKCS#11 in TCU platform
      • [LS104x] 使用ostree更新rootfs
      • [LS104x] ostree的移植
      • [LS104x] Starting with Yocto
      • [LS104x] 使用FIT的kernel格式和initramfs
    • IMX6/8_Documents
      • [IMX6] Defining A U-Boot Command
      • NXP IMX6 嵌入式板子一些笔记
      • NXP-imx6 initialization
    • Vehicle_Apps
      • [SecOC] Tree
        • [SecOC] SecOC Freshness and MAC Truncation
  • 😾TECH
    • Rust Arm OS
      • ARMv7m_Using_The_RUST_Cross_Compiler
    • ARM
      • ARM-v7-M
        • 01_ARMv7-M_处理器架构技术综述
        • 02_ARMv7-M_编程模型与模式
        • 03_ARMv7-M_存储系统结构
        • 04_ARMv7-M_异常处理及中断处理
      • ARM-v8-A
        • 02_ARMv8_基本概念
        • 03_ARMv8_指令集介绍_加载指令集和存储指令集
        • 04_ARMv8_指令集_运算指令集
        • 05_ARMv8_指令集_跳转_比较与返回指令
        • 06_ARMv8_指令集_一些重要的指令
        • 0X_ARMv8_指令集_基于汇编的UART驱动
        • 07_ARMv8_汇编器Using as
        • 08_ARMv8_链接器和链接脚本
        • 09_ARMv8_内嵌汇编(内联汇编)Inline assembly
        • 10_ARMv8_异常处理(一) - 入口与返回、栈选择、异常向量表
        • 11_ARMv8_异常处理(二)- Legacy 中断处理
        • 12_ARMv8_异常处理(三)- GICv1/v2中断处理
        • 13_ARMv8_内存管理(一)-内存管理要素
        • 14_ARMv8_内存管理(二)-ARM的MMU设计
        • 15_ARMv8_内存管理(三)-MMU恒等映射及Linux实现
        • 16_ARMv8_高速缓存(一)cache要素
        • 17_ARMv8_高速缓存(二)ARM cache设计
        • 18_ARMv8_高速缓存(三)多核与一致性要素
        • 19_ARMv8_TLB管理(Translation Lookaside buffer)
        • 20_ARMv8_barrier(一)流水线和一致性模型
        • 21_ARMv8_barrier(二)内存屏障案例
      • ARM Boot Flow
        • 01_Embedded_ARMv7/v8 non-secure Boot Flow
        • 02_Embedded_ARMv8 ATF Secure Boot Flow (BL1/BL2/BL31)
        • 03_Embedded_ARMv8 BL33 Uboot Booting Flow
      • ARM Compiler
        • Compiler optimization and the volatile keyword
      • ARM Development
        • 在MACBOOK上搭建ARMv8架构的ARM开发环境
        • Starting with JLink debugger or QEMU
    • Linux
      • Kernel
        • 0x01_LinuxKernel_内核的启动(一)之启动前准备
        • 0x02_LinuxKernel_内核的启动(二)SMP多核处理器启动过程分析
        • 0x21_LinuxKernel_内核活动(一)之系统调用
        • 0x22_LinuxKernel_内核活动(二)中断体系结构(中断上文)
        • 0x23_LinuxKernel_内核活动(三)中断体系结构(中断下文)
        • 0x24_LinuxKernel_进程(一)进程的管理(生命周期、进程表示)
        • 0x25_LinuxKernel_进程(二)进程的调度器的实现
        • 0x26_LinuxKernel_设备驱动(一)综述与文件系统关联
        • 0x27_LinuxKernel_设备驱动(二)字符设备操作
        • 0x28_LinuxKernel_设备驱动(三)块设备操作
        • 0x29_LinuxKernel_设备驱动(四)资源与总线系统
        • 0x30_LinuxKernel_设备驱动(五)模块
        • 0x31_LinuxKernel_内存管理(一)物理页面、伙伴系统和slab分配器
        • 0x32_LinuxKernel_内存管理(二)虚拟内存管理、缺页与调试工具
        • 0x33_LinuxKernel_同步管理_原子操作_内存屏障_锁机制等
        • 01_LinuxDebug_调试理论和基础综述
      • Userspace
        • Linux-用户空间-多线程与同步
        • Linux进程之间的通信-管道(上)
        • Linux进程之间的通信-管道(下)
        • Linux进程之间的通信-信号量(System V)
        • Linux进程之间的通信-内存共享(System V)
        • Linux进程之间的通信-消息队列(System V)
        • Linux应用调试(一)方法、技巧和工具 - 综述
        • Linux应用调试(二)工具之coredump
        • Linux应用调试(三)工具之Valgrind
        • Linux机制之内存池
        • Linux机制之对象管理和引用计数(kobject/ktype/kset)
        • Linux机制copy_{to, from}_user
        • Linux设备树 - DTS语法、节点、设备树解析等
        • Linux System : Managing Linux Services - inittab & init.d
        • Linux System : Managing Linux Services - initramfs
      • Kernel Examples
        • Linux Driver - GPIO键盘驱动开发记录_OMAPL138
        • 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(一)之miscdevice和ioctl
        • 基于OMAPL138的Linux字符驱动_GPIO驱动AD9833(二)之cdev与read、write
        • 基于OMAPL138的字符驱动_GPIO驱动AD9833(三)之中断申请IRQ
        • Linux内核调用SPI驱动_实现OLED显示功能
        • Linux内核调用I2C驱动_驱动嵌套驱动方法MPU6050
    • OPTEE
      • 01_OPTEE-OS_基础之(一)功能综述、简要介绍
      • 02_OPTEE-OS_基础之(二)TrustZone和ATF功能综述、简要介绍
      • 03_OPTEE-OS_系统集成之(一)编译、实例、在QEMU上执行
      • 05_OPTEE-OS_系统集成之(三)ATF启动过程
      • 06_OPTEE-OS_系统集成之(四)OPTEE镜像启动过程
      • 07_OPTEE-OS_系统集成之(五)REE侧上层软件
      • 08_OPTEE-OS_系统集成之(六)TEE的驱动
      • 09_OPTEE-OS_内核之(一)ARM核安全态和非安全态的切换
      • 10_OPTEE-OS_内核之(二)对安全监控模式的调用的处理
      • 11_OPTEE-OS_内核之(三)中断与异常的处理
      • 12_OPTEE-OS_内核之(四)对TA请求的处理
      • 13_OPTEE-OS_内核之(五)内存和cache管理
      • 14_OPTEE-OS_内核之(六)线程管理与并发
      • 15_OPTEE-OS_内核之(七)系统调用及IPC机制
      • 16_OPTEE-OS_应用之(一)TA镜像的签名和加载
      • 17_OPTEE-OS_应用之(二)密码学算法和安全存储
      • 18_OPTEE-OS_应用之(三)可信应用的开发
      • 19_OPTEE-OS_应用之(四)安全驱动开发
      • 20_OPTEE-OS_应用之(五)终端密钥在线下发系统
    • Binary
      • 01_ELF文件_目标文件格式
      • 02_ELF文件结构_浅析内部文件结构
      • 03_ELF文件_静态链接
      • 04_ELF文件_加载进程虚拟地址空间
      • 05_ELF文件_动态链接
      • 06_Linux的动态共享库
      • 07_ELF文件_堆和栈调用惯例以ARMv8为例
      • 08_ELF文件_运行库(入口、库、多线程)
      • 09_ELF文件_基于ARMv7的Linux系统调用原理
      • 10_ELF文件_ARM的镜像文件(.bin/.hex/.s19)
    • Build
      • 01_Script_makefile_summary
    • Rust
      • 02_SYS_RUST_文件IO
    • Security
      • Crypto
        • 1.0_Security_计算机安全概述及安全需求
        • 2.0_Security_随机数(伪随机数)
        • 3.0_Security_对称密钥算法加解密
        • 3.1_Security_对称密钥算法之AES
        • 3.2_Security_对称密钥算法之MAC(CMAC/HMAC)
        • 3.3_Security_对称密钥算法之AEAD
        • 8.0_Security_pkcs7(CMS)_embedded
        • 9.0_Security_pkcs11(HSM)_embedded
      • Tools
        • Openssl EVP to implement RSA and SM2 en/dec sign/verify
        • 基于Mac Silicon M1 的OpenSSL 编译
        • How to compile mbedtls library on Linux/Mac/Windows
    • Embedded
      • eMMC启动介质
  • 😃Design
    • Secure Boot
      • JY Secure Boot Desgin
    • FOTA
      • [FOTA] Module of ECUs' FOTA unit design
        • [FOTA] Tech key point: OSTree Deployment
        • [FOTA] Tech key point: repositories role for onboard
        • [FOTA] Tech key point: metadata management
        • [FOTA] Tech key point: ECU verifying and Decrpting
        • [FOTA] Tech key point: time server
      • [FOTA] Local-OTA for Embedded Linux System
    • Provisioning
      • [X-Shield] Module of the Embedded Boards initialization
    • Report
由 GitBook 提供支持
在本页
  • 1. Secure Storage High-Level Design
  • 1.1 一般性的安全存储业务模式(非ZYNQ)
  • 1.2 ZYNQ的Secure Storage设计
  • 2. Secure Storage Low-Level Design
  • 2.1 eFUSE/OTP Provisioning
  • 2.2 eFUSE layout
  • 2.2 PUF
  • 3.1 Provisioning
  • 3.2 PUF Enc/Dec demo
  • Ref
  1. ECUs
  2. ZYNQ_Documents

[ZYNQ] Encrypt external files based on file system using PUF key

上一页[ZYNQ] enabling the cryptsetup on ramdisk下一页[ZYNQ] Loading an Encrypted Linux kernel at U-Boot with a KUP Key

最后更新于1年前

如果使用Zynq® UltraScale+™设备,大部分数据是存储在设备的外面的(NVM),如果想增强数据的保密性,则需要启动Secure Storage来保护数据。保护数据的算法使用ZYNQ内置的GCM-AES硬件引擎,那么同样,对于GCM-AES来说确保Key的可信是最重要和最根本的事情。eFUSE/OTP保存着Secure Boot和Secure Storage使用的加密的Key,而且内置的PUF(physically unclonable function)对Key的保密性进行了增强。Key的写入eFUSE/OTP和配置PUF的过程叫做Provisioning,也只有在Provisioning之后,Secure Storage和Secure Boot才能使用RSA和GCM-AES保密与认证功能。

本文参考:

  • (AN) Secure Storage Application Note [^1]

  • (Provisioning) - Programming BBRAM and eFUSEs Application Note [^2]

  • (TRM) Zynq UltraScale+ Device Technical Reference Manual (UG1085) - Security [^3]

1. Secure Storage High-Level Design

1.1 一般性的安全存储业务模式(非ZYNQ)

本节借助文献[^4]的根文件系统保护和应用程序数据保护来阐述以下对于Secure Storage的业务需求。

  • 全盘级别加密:

    • 加密:

    • 认证:

    • 完整性:

  • 目录级别:

    • 加密:

    • 认证:

在台式机或手机上,用于加密文件系统的密钥来自交互式输入的用户密码。物联网和嵌入式设备通常没有这样丰富的操作流程。因此,需要在设备上存储和保护密钥。以下是一些保护机制:

  • 使用 SoC 机制加密密钥,ARM的使用方法

  • 使用外部可信平台模块 (TPM) 芯片

  • 远程证明

我们来看一下加密过程:

  • 使用加密的方法保护文件系统;

  • 需要加密上述加密的密钥;

如上图所示:

  • 先对文件系统进行加密,使用的密钥就是文件加密的密钥key0;

  • 再对key0进行加密(调用HSM或者Linux内核安全程序或者自己编写安全服务程序,需要保证解密方也能被调用)

  • 解密过程就是先call安全系统HSM或者Linux内核安全程序或者安全应用解密密钥,拿到密钥之后解密文件系统。

这个就是一般的文件系统的加密模型。

1.2 ZYNQ的Secure Storage设计

在上述的加密模型中,需要引入HSM或者Linux内核安全服务程序用来对文件系统加密的密钥进行加解密。在ZYNQ中可以使用PUF硬件来满足加密的需求。PUF硬件根据物理工艺不同,可以对写入eFUSE的密钥进行加扰和解扰(也算是一种加密手段),因此使实际存储在eFUSE上的每个设备的black key都是不一样的。

我们可以对一批设备假定1万台,管理员生成一个红密钥作为文件系统加密的密钥,管理员需要为每台设备Provisioning这个红密钥到eFUSE上,并启动PUF功能。这一万台设备的实际存储的黑密钥都是不一样的。这就能够抵御侧信道攻击,即便是有人用功率分析,分析出eFUSE的密钥,拿到的也是黑密钥,没有任何的实际用处。

PUF可以理解为一个函数,这个函数输入红密钥、IV、ID等信息,输出一个AES-GCM加密的key blob结果,包含了tag、密文等。当我们要使用密钥解密文件系统的时候,则需要先把key blob输入进去,此时,ZYNQ读取到key blob则对输入的tag和密文解密,解密之后就可以拿到真实的红密钥,也会对tag进行验证,tag验证通过,红密钥才可信,解密者拿红密钥对文件系统进行解密。ZYNQ只是对密钥加密和解密做了封装,而文件系统的加密解密需要自己的应用程序来做。

1.2.1 加密解密High-Level角度过程

Alice的加密

我们来看看Alice加密过程,Alice产生一个Red Key,用于真实文件系统加密,Alice把Red Key注入FPGA中,得到了密文的Key Blob。与此同时,Alice使用Red Key对文件加密,得到加密了的文件系统。

Bob的解密

FPGA内部提供了AES-256-GCM加速引擎来完成加密及认证的AEAD操作。Bob拿到Key Blob之后喂给FPGA,FPGA会输出Red Key和一个GCM的AUTH结果(tag),如果AUTH结果(tag对比)通过,那么Bob可以使用红密钥对加密的文件进行解密,最后拿到解密后的文件。

FPGA在这里充当的角色是对Red Key进行加解密验证。

1.2.2 FPGA SoC内部过程

如图所示,为Alice加密和Bob解密在External Memory以及FPGA SoC内部的加解密全过程:

在FPGA SoC内部,主要是利用PUF的物理特性,产生一个PUF Key,用做内部数据加密的密钥。FPGA内部依旧使用AES-GCM-256来完成加密操作。Alice和Bob可以在External Memory协商数据加密的方式。

在FPGA内部,生成的黑色密钥是被写入到eFUSE中的,正因为每一个PUF的物理工艺不同导致的即便是数据一致,也会让每个设备驻留在eFUSE内部的数据不一致。这就达到了防止DPA的目的。

加密过程

如图,注,这里的New Data指的就是Alice的Red Key。

  1. Alice把明文Red Key喂给FPGA;

  2. FPGA产生一个PUF使用的Key(PUF物理工艺差异产生的数,不同芯片不一致,同一个芯片就是一致的),用于把Red Key加密成为一个Black Key,并写入eFUSE;

  3. FPGA输出Black Key和TAG值,到外部内存;

  4. FPGA读回Black Key和TAG值,组成Key Blob;

  5. FPGA对Black Key进行解密,解密得到一个TAG1的值;

  6. FPGA对比TAG1和TAG是否一致,以此检验是否加密成功;若不一致,进入“惩罚”流程,比如烧写FUSE的User Data,告知解密失败过。

1.2.3 解密过程

解密的过程:

  1. Bob把Key Blob输入到FPGA内部;

  2. FPGA读取到Key Blob分离出black key和TAG;

  3. FPGA重新让PUF产生一个Key(PUF物理工艺差异产生的数,同一个设备,这个值必然一致);

  4. FPGA使用PUF产生的Key解密black key成为red key,并输出TAG1;

  5. FPGA校验TAG1和Key Blob输入的TAG是否一致,若一致则解密成功并输出Red Key。

1.2.2 FPGA的安全角度考量

防重放攻击

防重放攻击的设计体现在,Alice对于Red Key的输入不光是有 Red Key和IV这些成分,除此之外还有ID放入到OTP的256bits长度的User Data里面。Alice产生Key之后,可以增加ID,在解密的时候,除了要验证解密的信息的GCM的TAG之外,还要对比解析出来的ID信息,和OTP/eFUSE上的ID进行对比。这样很可能就可以有效的抵御重放攻击。

id在bootgen的时候通过以下方法指定:

功率分析攻击(DPA)

PUF Key是直接加载到SoC内部的加密引擎中的。为了防止eFUSE中的Key被分析出来,ZYNQ给了两个建议:

  • 尽量让User Data短。PUF Key在SoC中不是对所有的数据加密,而是加密第一部分,因此存在没有加密的部分。如果User Data过长,就难保后面的数据的保密性。入侵者Mallory很可能使用DPA功率分析分析出后面User Data的数据;

  • 如果User Data不得不做的很长。ZYNQ推荐使用Rolling Key/OP Key的方式,进行加密;

Operational Key (OP Key)

实际上在boot中也不希望使用私密的key频繁加密,以下是提供了OP Key方法来帮忙减少使用私密的key:

bootgen在生成image的时候,会把op key放到image header里面,还包含了IV这类的信息。当需要进行解密的时候,使用私密的key对第一个块进行解密,从解密的信息中读取OP key,然后利用该key解下一个块,以此类推。这样私密的Key只使用了一次。

Note, DPA功率分析,可以通过频谱分析出eFUSE上的数据。

Keys Rolling

以下为Key Rolling的过程:

FIPS Legay的key审查

使用SoC PUF产生的加密数据,也就是Block Key,如果作为Key的话,处于密码学安全边界之外,换句话说,此密钥不符合FIPS-legal KEK标准。因此我们需要在产生Red Key阶段就产生一个符合FIPS标准的Key,这样加密出来的Key就会处于密码学安全边界内。

2. Secure Storage Low-Level Design

2.1 eFUSE/OTP Provisioning

eFUSE array包含一个256的块,在这个块里面提供GCM-AES-256的key给加解密引擎。eFUSE的key可以存储为明文形式(red key),混淆模式(gray key),或者是加密模式(black key)。

在一些老的ZYNQ设计中是支持读回操作来验证写入的eFUSE数据是否正确。在一些eFUSE的SoC设计中,有驱动接口是支持读出eFUSE上面值的。以前我们在做Provisioning工具的时候,都是先利用写接口写入eFUSE数据,然后再通过读接口读回数据,对比写入和读出的数据来判断是否真的写成功eFUSE。但对于现阶段的ZYNQ来说具备很高的风险性,所以这个途径已经被关闭读回了。取而代之的是,写入eFUSE之后同时会返回CRC32,可以通过对比返回的CRC来确定值是否正确。

从安全角度来看,无法确定“一次性”的功能给eFUSE带来多少的增益。但是要注意,确保电压稳定,否则可能导致eFUSE写入失败。在烧录eFUSE的时候,一定要确保电压、温度这些条件稳定。否则可能使eFUSE烧写发生错误。写eFUSE的时候不要用SPA对密钥进行分析,SPA是通过接入不同电压,静态分析eFUSE的功率变化。所以在烧录eFUSE时候为了保持稳定电压,xilinx建议不要这个时候做SPA分析。

HRoTS

ZYNQ的HRoTS基于RSA-4096认证,而且需要基于两类的public key:

Primay的2个公钥,一个需要存储在外部的内存中,一个需要把其hash值存入eFUSE;因此,Primay的pk hash是一个根凭证。

最小需要做Provisioning的信息如上。

2.2 eFUSE layout

在FPGA系统中,逻辑和处理单元是分开的两部分:

  • PS: 处理系统 (Processing System) :就是与FPGA无关的ARM的SoC的部分。

  • PL: 可编程逻辑 (Progarmmable Logic): 就是FPGA部分。

因此,存在两类eFUSE,一个是256-PS的eFUSEs,还有是128-PL的eFUSEs。 PL的eFUSEs顾名思义,是给可编程逻辑 (Progarmmable Logic)使用的,我们用不到。我们更关心处理系统 (Processing System) 的侧的eFUSE,也就是存储密钥之类的eFUSE。

Size

Name

Description

MACRO define

32

USER_{0:7}

256 user defined eFUSEs:Note: In the input.hfile (see text), write data in the XSK_EFUSEPS_USER{0:7}_FUSES macro and execute the write by setting the XSK_EFUSEPS_USER{0:7}_FUSE macro = True.

USER{0:7}_FUSE

1

USER_WRLK

8 user-defined eFUSE locks.USER_WRLK columns:0: Locks USER_0,1: Locks USER_1,...7: Locks USER_7,Note: Each eFUSE permanently locks the entire corresponding user-defined USER_{0:7} eFUSE row so it cannot be changed.

USER_WRLK_{0:7}

1

LBIST_EN

Enables logic BIST to run during boot.

LBIST_EN

3

LPD_SC

Enables zeroization of registers in low power domain (LBD) during boot.Note: Any of the eFUSE programmed will perform zeroization. Xilinx recommends programming all of them.

LPD_SC_EN

3

FPD_SC

Enables zeroization of registers in full power domain (FBD) during boot.Note: MGTs must be powered to perform zeroization of the FPD.Note: Any of the eFUSE programmed will perform zeroization. Xilinx recommends programming all of them.

FPD_SC_EN

3

PBR_BOOT_ERROR

When programmed, boot is halted on any PMU error.

PBR_BOOT_ERR

32

CHASH

PUF helper data(参考:2.2.1 PUF Helper Data)

N/A - handled by PUF registration software directly.

24

AUX

PUF helper data: ECC vector

N/A - handled by PUF registration software directly.

1

SYN_INVLD

Invalidates PUF helper data stored in eFUSEs.

XSK_PUF_SYN_INVALID

1

SYN_LOCK

Locks PUF helper data from future programming.

XSK_PUF_SYN_WRLK

1

REG_DIS

Disables PUF registration.

XSK_PUF_REGISTER_DISABLE

1

AES_RD

Disables the AES key CRC integrity check for eFUSE key storage.

AES_RD_LOCK

1

AES_WR

Locks AES key from future programming.

AES_WR_LOCK

1

When programmed, all partitions are required to be encrypted. Xilinx recommends using this only if security is required and the hardware root of trust (RSA_EN) is not used.

ENC_ONLY

1

BBRAM_DIS

Disables the use of the AES key stored in BBRAM.

BBRAM_DISABLE

1

ERR_DIS

Prohibits error messages from being read via JTAG (ERROR_STATUS register).Note: The error is still readable from inside the device.

ERR_DISABLE

1

Disables JTAG. IDCODE and BYPASS are the only allowed commands.

JTAG_DISABLE

1

Disables design for test (DFT) boot mode.

DFT_DISABLE

3

PROG_GATE

When programmed, these fuses prohibit the PROG_GATE feature from being engaged. If any of these are programmed, the PL is always reset when the PS is reset.Note: Only one eFUSE needs to be programed to prohibit the PROG_GATE feature from being engaged. Xilinx recommends programming all three.

PROG_GATE_DISABLE

1

SEC_LK

When programmed, the device does not enable BSCAN capability while in secure lockdown.

SECURE_LOCK

15

When any one of the eFUSEs is programmed, every boot must be authenticated using RSA. Xilinx recommends programming all 15 eFUSEs.

RSA_ENABLE

1

PPK0_WR

Primary public key write lock. When programmed, this prohibits future programming of PPK0.

PPK0_WR_LOCK

2

PPK0_INVLD

When either of the eFUSEs are programmed, PPK0 is revocated. Xilinx recommends programming both eFUSEs when revocating PPK0.

PPK0_INVLD

1

PPK1 WR

Primary public key write lock. When programmed this prohibits future programming of PPK1.

PPK1_WR_LOCK

2

PPK1_INVLD

When either of the eFUSEs are programmed, PPK1 is revocated. Xilinx recommends programming both eFUSEs when revocating PPK1.

PPK1_INVLD

32

SPK_ID

Secondary public key ID.Note: Write the SPK ID bits into the XSK_EFUSEPS_SPK_ID eFUSE array and set XSK_EFUSEPS_SPKID = True.

SPK_ID

256

AES

User AES keyNote: Write data in the XSK_EFUSEPS_AES_KEY macro and execute the write by setting the XSK_EFUSEPS_WRITE_AES_KEYmacro = True.

AES_KEY

384

PPK0

User primary public key0 HASHNote: Write data in the XSK_EFUSEPS_PPK0_HASH macro. To program 256 bits, use the LSBs and set XSK_EFUSEPS_PPK0_IS_SHA3 = False. To program 384 bits, set XSK_EFUSEPS_PPK0_IS_SHA3 = True. Execute the write by setting the XSK_EFUSEPS_WRITE_PPK0_HASH macro = True.

PPK0_HASH

384

PPK1

User primary public key1 HASHNote: Write data in the XSK_EFUSEPS_PPK1_HASH macro. To program 256 bits, use the LSBs and set XSK_EFUSEPS_PPK1_IS_SHA3 = False. To program 384 bits, set XSK_EFUSEPS_PPK1_IS_SHA3 = True. Execute the write by setting the XSK_EFUSEPS_WRITE_PPK1_HASH macro = True.

PPK1_HASH

N/A

PUF_HD

Syndrome of PUF HD. These eFUSEs are programmed using Xilinx provided software, Xilskey

N/A - handled by PUF registration software directly.

这个表,很关键,eFUSE会影响到ZYNQ处理器的工作状态、安全信息,配置错了之后,Xilinx已经声明不接受要求eFUSE复原的返厂件。在操作这些位的时候,尤其是Provisioning的时候,会影响其他非安全的测试。

IMPORTANT: THESE INSTRUCTIONS MODIFY THE EFUSES ON THE ZCU102 DEVELOPMENT BOARD AND MAY LIMIT FUTURE USE OF THE DEVELOPMENT BOARD FOR NON-SECURE TESTING AND DEBUGGING!

2.2 PUF

2.2.1 PUF Helper Data

PUF使用大约4Kb的辅助数据来帮助PUF在正确的寿命、规定的工作温度和电压范围内重新创建原始KEK值。辅助数据由Syndrome值、Aux值和Chash值组成(请参见表:PUF辅助数据)。助手数据可以存储在eFUSE或引导映像中。

PUF Helper Data Field

Size (Bits)

Description

Syndrome

4060

鉴于环形振荡器在温度、电压和时间上的微小变化,这些比特有助于PUF恢复正确的PUF特征

Aux

24

这是一个汉明码,允许PUF对PUF签名执行某种程度的纠错。

Chash

32

•如果CHASH未被编写,则只要使用(bh_auth或rsa_en),就可以使用boot-header black key。

•如果对CHASH进行了编写,则只要(使用bh_auth或rsa_en)且eFUSE的Syndrome数据未失效,就可以使用eFUSE的black key。

•如果对CHASH进行了编写,则只要使用(bh_auth或rsa_en)且efuse的Syndrome数据无效,就可以使用boot-header black key。

生成puf helper data的过程参考:

2.2.2 PUF operations

只有CSU可以访问PUF,所以PUF的初始化包括黑密钥的产生,必然是在CSU阶段完成。PUF暴露出以下接口供CSU操作:

Command

Description

Registration

产生一个新的KEK并且关联helper data

Re-registration

产生一个新的KEK并且关联新的helper data

Reuse

使用已经存在的KEK进行加解密,并且关联helper data

当一个设备上电的时候,CSU bootROM会检测已经校验过的boot header,确认以下信息:

  • 是否使用了PUF;

  • 加密的密钥存储在哪里?(eFUSE 或者 boot image)

  • helper data存储在哪里?(eFUSE 或者 boot image)

接着CSU初始化PUF,并且加载helper data,最后产生KEK,这个过程叫做regeneration。一旦KEK产生成功,CSU bootROM使用它来解密剩下boot image需要的key。

2.2.3 PUF Control eFUSEs

eFUSE也给PUF留了一些功能接口:

Command

Description

REG_DIS

屏蔽PUF的注册

SYN_INVALID

使存在eFUSE上的helper data无效

SYN_LOCK

屏蔽修改eFUSE上的helper data的功能

Xilinx也做了PUF的强度分析,包含加密,安全强度KEK,过温过压的测试的数据报告,需要联系FAE或者销3. Example售才可以拿到这个报告。

3.1 Provisioning

Provisioning是所有安全机制的基础。其目的是把根凭证写入eFUSE或者其他存储密钥的敏感介质。包含RSA的根密钥,也包含GCM的Key。

在ZYNQ中我们需要Provisioning的内容:

  • PPK HASH (主引导Primary Public Key Hash)

  • GCM-AES Key (用于image解密)

  • PSK ID (写入key的id信息,作为PUF解密时候比对,参考'防重放攻击'一节)

在调试阶段为了不伤害eFUSE。对于PPK HASH,zynq提供了bh_boot模式,即可以绕过eFUSE的PPK HASH检测,直接使用AC中的hash值。

同样,为了不伤害eFUSE。对于GCM-AES key,我们可以不使用eFUSE,而把Key烧录到BBRAM中。

在调试阶段,推荐配置为:

  • ppk hash,对于验证,使用bh_boot(不需要包含到Provisioning过程中)

  • gcm aes key,对于验证,使用bbram (需要包含到Provisioning过程中)

  • id

  • ID,对于验证,在bootgen阶段选择spk_id = 0,不需要包含到Provisioning中。

在产品阶段,必须配置为: ppk hash 和 gcm aes key都需要在eFUSE中。

我们可以把完整的Provisioning过程总结为:

  • 手动产生两对RSA密钥,产生gcm-aes-key;

  • 使能PUF eFUSE的配置;

  • 使用写入寄存器的方法写入eFUSE。

可以通过JTAG烧录eFUSE(这种方法数据操作互动型,具备一定的危险性,eFUSE烧录不可撤销),因此建议使用配置寄存器的方法烧录eFUSE。

3.1.1 Gen Key

密钥生成主要是需要以下材料:

  • AES Key Generation

    • 输出nky文件(包含key和iv)

  • RSA Asymmetric Key Generation

    • 输出1:psk0.pem

    • 输出2:ssk0.pem

  • Generate SHA3 of Public RSA Asymmetric Key

    • 输出是:sha3.txt

3.1.2 PUF eFUSE config

PUF eFUSE的配置需要使用Vitis建立AP的工程,使用ZYNQ上面的AP来完成PUF的配置。非常重要的提示:这一步会修改eFUSE上面的内容!

需要配置的项目是:

  • XSK_PUF_INFO_ON_UART

  • XSK_PUF_PROGRAM_EFUSE

  • XSK_PUF_PROGRAM_SECUREBITS

  • XSK_PUF_SYN_WRLK

  • XSK_PUF_AES_KEY

  • XSK_PUF_IV

XSK_PUF_AES_KEY是用户指定的,而且这个XSK_PUF_IV和AES Key Generation中的IV不相关。这个IV是用于PUF KEK的red key加密。

3.1.3 RSA eFUSE config

这一步是配置RSA相关的信息到eFUSE上面,非常重要的提示:这一步会修改eFUSE上面的内容!

  • XSK_EFUSEPS_RSA_ENABLE

  • XSK_EFUSEPS_PPK0_WR_LOCK

  • XSK_EFUSEPS_WRITE_PPK0_HASH

  • XSK_EFUSEPS_PPK0_HASH

3.1.4 RSA Key Revocation Support

RSA密钥提供了撤销一个分区的secondary密钥(SPK)的能力,而无需撤销所有分区的密钥。这是通过使用新的BIF参数spk_select利用USER_FUSE0到USER_FUSE7 位域实现(如果这些位域没有用于表示其他信息,只用于表示密钥的id,最多可以撤销256个SPK,如图所示)。

下图表示ZYNQ使用SPK_ID进行SPK revocation的过程。

以下是使用辅助密钥创建经过身份验证的映像的步骤:

  • 使用bootgen生成RSA密钥对。

  • 我们在步骤1中生成了一个辅助密钥(SSK)。如果需要更多的SSK,请重复步骤1以创建SSK密钥。

  • 使用bootgen和下面的bif文件模板生成经过验证的引导映像。下面的模板假设bootloader和u-boot使用[sskfile]标记提供的密钥进行了验证,并且该密钥根据eFUSE中存储的SPK_ID进行了验证;PMU FW和ATF images使用sskfile提供的密钥进行验证,并根据存储在USER_eFUSE中的SPK_ID bitmap 验证该密钥。(确保在生成映像时使用命令行参数–efuseppkbits<path_to_sha_txt_file>命令bootgen生成PPK哈希。)

  • 写入在第三步创建的PPK的SHA-3 hash 到eFUSE的PPK0 hash位域。

确保在生成image时使用命令行参数–efuseppkbits<path_to_sha_txt_file>命令bootgen生成PPK hash。

模板示例: image header和FSBL使用不同的SSK进行身份验证(分别为ssk1.pem和ssk2.pem),用以下bif文件:

the_ROM_image: {
[auth_params]ppk_select = 0
[pskfile]psk.pem
[sskfile]ssk1.pem
[bootloader, authentication = rsa, spk_select = spk-efuse, spk_id = x00000001, sskfile = ssk2.pem]zynqmp_fsbl.elf
[destination_cpu =a53-0, authentication = rsa, spk_select = user-efuse,spk_id = 0x1, sskfile = ssk3.pem]Application1.elf
[destination_cpu =a53-0, authentication = rsa, spk_select = spk-efuse, spk_id = 0x00000001, sskfile = ssk4.pem]Application2.elf
}

相同的SSK将作用于image header和FSBL(ssk2.pem):

the_ROM_image: {
[auth_params]ppk_select = 0 [pskfile]psk.pem
[bootloader, authentication = rsa, spk_select = spk-efuse, spk_id = 0x00000001, sskfile = ssk2.pem]zynqmp_fsbl.elf
[destination_cpu =a53-0, authentication = rsa, spk_select = user-efuse, spk_id = 1, sskfile = ssk3.pem]Application1.elf
[destination_cpu =a53-0, authentication = rsa, spk_select = spk-efuse, spk_id = 0x00000001, sskfile = ssk4.pem]Application2.elf
}

注意:

  • spk_select = spk-efuse 表示 指定的分区将会使用spk_ideFUSE位域。

  • spk_select = user-efuse 指示 指定的分区将会使用user eFUSE位域,而CSU ROM总是使用spk_ideFUSE位域。

3.2 PUF Enc/Dec demo

完成上面PUF的注册,我们假定eFUSE和PUF的配置已经OK了,现在我们需要编写APU(Application Processor Unit)的固件(bare-mental程序),来使用PUF的加密和解密功能。

该固件是在xilinx的vitis ide上完成的,vitis已经集成了ZYNQ所用的bsp驱动包,并提供了相应的操作key、加密解密、访问寄存器、控制外设等接口。

打开vitis ide创建工程:

选择bsp包:

选择processor为APU (Application Processor Unit):CortexA53_0:

导入bare-mental的源码(下面就是源码核心):

源码进行编译:

最后生成BOOT.BIN文件,将其复制到SD卡的boot分区。启动即可运行。

3.2.1 加密

对于一个PUF加密过程的程序:

void puf_encrypt(u8 *Iv, u8 *Dst, u8 *Src, u32 Size) {

	XCsuDma_Config *Config;
	XCsuDma_Configure ConfigurValues = {0};

    /* Configure PUF configuration 0 and configure the shutter. */
	XilSKey_WriteReg(XSK_ZYNQMP_CSU_BASEADDR, XSK_ZYNQMP_CSU_PUF_CFG0,
                    XSK_ZYNQMP_CSU_PUF_CFG0_DEFAULT);
	XilSKey_WriteReg(XSK_ZYNQMP_CSU_BASEADDR, XSK_ZYNQMP_CSU_PUF_SHUT,
                    XSK_ZYNQMP_CSU_PUF_SHUT_DEFAULT);


	// Spin up the PUF and connect the key to the AES engine
	XilSKey_WriteReg(XSK_ZYNQMP_CSU_BASEADDR, XSK_ZYNQMP_CSU_PUF_CMD,
                    XSK_ZYNQMP_PUF_REGENERATION);

    /* Wait for the PUF regeneration to complete. */
	usleep(PUF_REGEN_TIME_US);

	/* Initialize & configure the DMA */
	Config = XCsuDma_LookupConfig(XSK_CSUDMA_DEVICE_ID);
	XCsuDma_CfgInitialize(&CsuDma, Config, Config->BaseAddress);

	/* Initialize AES engine */
	XSecure_AesInitialize(&AesInstance, &CsuDma, XSK_PUF_DEVICE_KEY, (u32 *) Iv, NULL);

	/* Set the data endianess for IV */
	XCsuDma_GetConfig(&CsuDma, XCSUDMA_SRC_CHANNEL,
				&ConfigurValues);
	ConfigurValues.EndianType = 1U;
	XCsuDma_SetConfig(&CsuDma, XCSUDMA_SRC_CHANNEL,
					&ConfigurValues);

	/* Enable CSU DMA Dst channel for byte swapping.*/
	XCsuDma_GetConfig(&CsuDma, XCSUDMA_DST_CHANNEL,
			&ConfigurValues);
	ConfigurValues.EndianType = 1U;
	XCsuDma_SetConfig(&CsuDma, XCSUDMA_DST_CHANNEL,
			&ConfigurValues);

	/* Request to encrypt the AES key using PUF Key	 */
	XSecure_AesEncryptData(&AesInstance, (u8 *) Dst, (u8 *) Src, Size);

   /* Clear the PUF key. */
	XilSKey_WriteReg(XSK_ZYNQMP_CSU_BASEADDR, XSK_ZYNQMP_CSU_PUF_CMD,
                    XSK_ZYNQMP_PUF_RESET);
}

3.2.2 解密

Ref

将密钥存储在提供安全存储的外部加密或安全芯片(例如:)中

我们只来阐述第一种使用 SoC 机制加密密钥,ARM的使用方法。很多外部安全芯片如TPM容易受到I2C。如果可能的话最好利用主处理器的安全存储功能。安全存储的最核心的业务逻辑就是:如何保护好密钥。

在NXP 上面,每个设备都有一个不同的主密钥(通过PUF,PUF是根据每个设备的物理工艺不同,可以实现每个设备的黑密钥差异的硬件设备),该密钥被SoC内部的加解密引擎访问。因此,就可以编写安全应用程序,例如Linux内核安全驱动程序或者HSM系统,读取该唯一密钥,在HSM程序内部对密钥进行加密,输出一个key blob用于解密方解密。

Note,CAAM driver:

在ZYNQ内部,有很多安全关键因素在设计中被考虑到,我们应该熟悉其背后的设计逻辑,明白他们的设计意图。一种是对于防重放攻击的抵御,一种是防DPA,除此之外还有对black KEY 考量的因素。(PUF key的来源是因为每个设备工艺不一致生成的一串数据,这串数据是不符合标准的。生成key的需要真随机数或者DRBG才能达到生成key的质量。如果想要black key达到质量,我们则需要让加密前的数据达到质量,这样加密后的数据就达到了key的质量要求。)

eFUSE的写入过程叫做Provisioning。通过PJTAG(on MIO)使RPU或者APU处理器写寄存器的方式完成Provisioning。 .

最后,请注意通过总线,可以加载Key到 key update register 中。这个设计主要是为了boot阶段使用了rolling key,对不同块加密的时候要频繁的换key。就是通过这个寄存器实现。

参考:

ENC_ONLY

JTAG_DIS

DFT_DIS

RSA_EN

helper data 简单的说是帮助生成PUF key时候所需要的材料(Syndrome,Aux)。如图所示,生成PUF key及调用AES引擎的过程。PUF原数据复原的算法,可以参考:[Helper Data Algorithms for PUF-Based Key Generation: Overview and Analysis]() (有点专业和复杂。。) 特征值(Syndrome)和Aux(汉明距)是算法需要的输入。汉明距是实现比特纠错码的一种手段,可以参考,文献:[ ]。

使能RSA认证通过设定 “RSA_EN” 在eFUSE上. 参考

🧔
dm-crypt
dm-verity
dm-integrity
ext4
ubifs
eCryptfs
IMA/EVM
ATECC508A
总线攻击
I.MX
https://mcuxpresso.nxp.com/api_doc/dev/721/group__caam__driver.html
FIPS legal KEK
Ref, Programming BBRAM and eFUSEs Application Note (XAPP1319)
APB
https://docs.xilinx.com/r/dqE2tE0k~iMhpEDoQwXIKg/2Ubsx6RiXaJnAO2rAuCVYA?section=XREF_67790_Zynq_UltraScale
https://lirias.kuleuven.be/retrieve/334181
https://blog.csdn.net/weixin_45783996/article/details/116203267
Programming BBRAM and eFUSEs Application Note (XAPP1319)
External Secure Storage Using the PUF Application Note
Programming BBRAM and eFUSEs Application Note (XAPP1319)
Zynq UltraScale+ Device Technical Reference Manual (UG1085) - Security
secure-boot-encrypted-data-storage
^(1)^
^(2)^
^(1)^
^(1)^
^(1)^
^(2)^
Use Secure Boot Features to Protect Your Design — Embedded Design Tutorials 2021.1 documentation