Hi35xxVxxx 安全子系统使用说明
前言
与本文档相对应的产品版本如下。
本文档(本指南)主要适用于以下工程师:
- 技术支持工程师
- 软件开发工程师
概述
芯片提供丰富的安全特性,包括一系列硬件、固件和软件,以支持客户构建安全可信的设备。主要的安全特性如下:
- 支持One Time Programmable(OTP),用于存储包括设备安全启动验签的ECC 公钥哈希、多组对称根密钥、SoC安全相关的各种控制信息,以及用户自定义数据等。
- 支持基于OTP对称根密钥进行密钥派生。支持对烧录到OTP的根密钥的加扰保护;密钥派生过程中所有的明文密钥软件不可见。派生后的明文密钥可送给对称密码算法加速器进行安全的密码计算。
- 支持硬件真随机数。
- 支持RSA, ECC, SM2等非对称密码算法的加速。
- 支持AES, SM4等对称密码算法的加速。
- 支持SHA2, SM3等杂凑密码算法的加速。
- 支持基于硬件可信根的安全启动:支持安全镜像逐级校验;支持镜像加密可选择;支持TEE/REE信任链分离;安全启动镜像和非安全启动镜像格式统一,即安全启动没有使能的情况下,非加密的安全启动镜像也可以正常启动。
- 支持ARM TrustZone,支持安全、非安全内存地址隔离。客户可构建TEE安全方案。
- 支持JTAG分级保护。
OTP
简介
OTP是一种非易失性存储器,其主要特性是对应存储空间的内容由0写为1之后,或者写入后锁定,就不能再次更改。 OTP 包含如下几大区域:
-
存放SoC各种密钥的区域:包括存放安全启动的根公钥哈希值(受限可读),存放保护多个对称密码算法根密钥。密钥区域一旦发起写入操作,自行锁定不可再更改。
芯片可存放各组根公钥哈希值,用于安全启动校验。包括:芯片厂商根公钥哈希(已预置),OEM根公钥哈希和第三方双签名根公钥哈希。客户可根据产品实际需要,选择合适的根公钥(通过OTP选择)。
加解密根密钥:芯片预留OEM可烧写的对称密码根密钥OTP空间,如:Hi3516CV610 和 Hi3511CV100 中预留 oem_rootkey OEM可以利用这里面的一个或者多个根密钥,分别派生出不同的密钥保护密钥和工作密钥。这些密钥区域可以通过对应的OTP烧写接口烧写,一旦写入,硬件自行锁定,不可更改。写入的内容也不能通过软件方式或JTAG接口读取得到。
芯片预置一个芯片厂商TEE对称密码算法加解密的根密钥,用户可根据实际需要选择使用(通过OTP选择)。
-
SoC重要特性/功能开关控制区域(含单bit控制区域和多bit控制区域):SoC大多数重要的特性,都可以通过OTP来控制,以提高产品应用的灵活性。比如:安全启动使能,安全启动镜像是否加密,安全启动是否启动冗余备份,是否使能TEE等等。特性/功能开关控制区域,在烧写好目标值之后,都可以选择将其锁定,避免后续非法篡改。建议客户在最终产品发布前,将所有的特性/功能开关位对应的值设置好,并按需锁定。
-
用户自定义区域(仅Hi3519DV500支持):芯片集成了约25Kbit的用户自定义OTP区域,用以存放用户数据。
用户自定义区域还包含了一个128bit的版本控制区域:版本控制区域用于存放重要版本标识,防止版本回滚攻击。即防止攻击者利用有安全漏洞的老的合法镜像重新升级,实现重放攻击。版本控制区域不能锁定,每一个控制位都只能由0写到1,一旦写入1后,便不可再更改(one way 模式)。
在 SDK 包中,提供了OTP相关的读写接口。详细请参考本文“OTP字段定义”以及文档《安全子系统 API 参考》。
须知: - 所有的OTP控制位,无论默认值是否满足实际应用,请全部重新烧写锁定,保证设备安全。
- 文档中未列出的OTP控制位不代表是保留可用的,有可能已经被芯片厂商用于可靠量产等目的,不可随意烧写。
- OTP 仅在重新上电或看门狗复位后生效。U-Boot 下已提供看门狗复位命令即 dog_reset 命令。
OTP字段定义
OTP位域属性说明
LOCK属性说明
- Oneway属性:具有此属性的位域未烧写为1的bit都可以在下一次继续烧写,直到所有bit都烧为1;lock使能位不会锁定此属性的位域;
- lockable属性:lockable属性的相关位域在锁定前与oneway属性一致,烧写对应的lock位后,即使没烧写过的bit也不能再次烧写;建议lockable属性的位域,烧写值后对对应的位域进行锁定,防止被修改。
Load shadow属性说明
Y:芯片上电硬复位后OTP的值会自动加载到对应的寄存器(shadow寄存器);shadow寄存器区域有自己的基地址,而偏移地址与OTP fuse所在的OTP memory地址完全一致。每次烧写OTP后,必须重新上下电才能从shadow寄存器读到刷新后的值;
N:OTP位域无对应的shadow寄存器。
密钥、根公钥HASH区域
密钥区域软件不可访问,根公钥HASH区域可以通过下面OTP API接口访问:
td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data); td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data); td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data);
详细请参考《安全子系统API参考》
可锁定的控制区域
单比特控制的区域可以通过下面OTP API接口访问:
td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data); td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data); td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data);
详细请参考《安全子系统 API 参考》
单比特控制的区域,OTP对应的值,会在其对应的shadow寄存器中体现出来。
不可锁定的控制区域
TEE 调试JTAG(用于调试TEE CPU)模式控制,此控制仅在soc_tee_enable为非0x42(TEE使能)时有效。 |
|||||
多比特控制区域可通过如下OTP API访问:
td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data); td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data); td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data);
多比特控制区域可读可写。其中oneway属性的区域,不可锁定,通过API获得的锁定状态无意义。
用户自定义区域
用户自定义区域可通过如下OTP API访问:
td_s32 ot_mpi_otp_read_word(td_u32 offset, td_u32 *data); td_s32 ot_mpi_otp_read_byte(td_u32 offset, td_u8 *data); td_s32 ot_mpi_otp_write_byte(td_u32 offset, td_u8 data);
用户自定义区域可写可读,其中oneway属性的区域,不可锁定,通过API获得的锁定状态无意义。
须知:
配置JTAG安全模式时,请注意以下事项:
- jtag_prt_mode字段为oneway属性(为0的bit可以烧写为1,直到所有bit都为1),其他字段只要写过一次即锁定;
- jtag_prt_mode可以向更高密级配置:JTAG OPEN →JTAG PASSWORD → JTAG CLOSE。
shadow寄存器
shadow寄存器基址为0x101E_0000,偏移地址与OTP地址一致。
举例说明:比如soc_tee_enable这个OTP位域,其OTP地址为0x12,shadow属性为Y,即表示会上电自动加载到shadow寄存器,因此shadow寄存器的地址为0x101E_0010 的bit[23:16]。
shadow寄存器为只读寄存器,不支持直接通过写shadow寄存器来烧写对应的OTP。
硬件真随机数
TRNG
TRNG模块能够生成真随机数。产生的真随机数符合AIS-31和SP800、GMT 0005-2012的随机测试规范。
TRNG具体应用方法,请参考文档《安全子系统 API 参考》
密钥管理
Hi3519DV500:
密钥管理分为三级,分别为RKP、一级KLAD、二级KLAD,增强了密钥安全强度。密钥经三级密钥管理后,生成明文的工作密钥,并送给加解密引擎(SPACC),实现对最终的数据加解密运算。明文的工作密钥不会出现在内存中,确保不会被泄露。
Hi3516CV610、Hi3511CV100:
密钥管理只有一级RKP,生成明文的工作密钥,并送给加解密引擎(SPACC),实现对最终的数据加解密运算。明文的工作密钥不会出现在内存中,确保不会被泄露。
KDF
Hi3519DV500:
KDF模块从OTP中获取对称根密钥,并对根密钥做一次解混淆。驱动根据用户输入的派生材料派生ROOT KEY,并将ROOT KEY传递给一级KLAD。ROOT KEY存储在硬件中,不会泄露。KDF的具体规格:
- 使用RFC 8018 PBKDF2作为派生算法,PRF使用HMAC-SHA256。
- 支持从OTP中获取对称根密钥。
- 支持对称根密钥解混淆。
- 支持根据不同的使用场景派生不同的ROOT KEY。
Hi3516CV610、Hi3511CV100:
KDF模块从OTP中获取对称根密钥。驱动根据用户输入的派生材料派生ROOT KEY,并将ROOT KEY作为工作密钥。ROOT KEY存储在硬件中,不会泄露。KDF的具体规格:
- 使用RFC 8018 PBKDF2作为派生算法,PRF使用HMAC-SHA256。
- 支持从OTP中获取对称根密钥。
- 支持根据不同的使用场景派生不同的ROOT KEY。
一级KLAD
说明:
Hi3516CV610、Hi3511CV100不支持一级KLAD。
一级KLAD从RKP模块中获取ROOT KEY,并将受保护的一级密钥解密,传递给二级KLAD。解密后的一级密钥存储在硬件中,不会泄露。一级KLAD的具体规格:
- 支持AES 128 ECB算法。
- 支持受保护的一级密钥长度为128bits。
二级KLAD
说明:
Hi3516CV610、Hi3511CV100不支持二级KLAD。
二级KLAD从一级KLAD获取解密后的密钥,并将受保护的二级密钥解密(明文的工作密钥),传递给加解密引擎(SPACC)。明文的工作密钥存储在硬件中,不会泄露。二级KLAD的具体规格:
- 支持AES 128 ECB算法。
- 支持受保护的二级密钥长度为128/256bits。
为详细了解密钥管理中RKP、一级KLAD、二级KLAD与OTP、SPACC之间的关系,请参考图1。

KM具体应用方法,请参考文档《安全子系统 API 参考》。
硬件非对称密码算法
PKE
注意:
- RSA2048及PKCS#1 V1.5填充为弱密码算法,建议正式商用的产品不使用
- NIST FIPS 186 - 4 P 256/384/521曲线算法为弱密码算法,建议正式商用的产品不使用
- Hi3516CV610、Hi3511CV100不支持RFC 8032 - ED25519和RFC 7748 - Curve25519。
PKE模块实现了RSA算法,ECC算法和SM2算法,同时提供密钥协商功能,椭圆曲线上点的验证功能与大数运算功能。
-
RSA是一种非对称密码算法,通过模幂计算实现加解密,常用于对数据进行数字签名和签名验证。PKE模块支持RSA2048/3072/4096,算法实现符合PKCS#1 V1.5/2.1标准。具体规格:
- 支持2048bit、3072bit和4096bit的密钥位宽。
- 2048密钥位宽公钥加解密性能最低为10 bps。
- 支持RSA内部密钥RAM、报文RAM和结果RAM清零。
-
ECC算法是一种椭圆曲线非对称密码算法,常用于对数据进行签名验签。具体规格:
- 支持 RFC 5639 - Brainpool 256/384/512、NIST FIPS 186 - 4 P 256/384/521 和 RFC 8032 - ED25519(即EDDSA)的私钥签名和公钥验签。
- 支持密钥位宽256/384/512(521)。
-
支持GM/T 0010-2012 - SM2算法。
-
密钥协商功能支持公私钥对的生成、由给定的私钥生成对应的公钥以及密钥交换(ECDH)。具体规格:
- 支持RFC 5639 - Brainpool 256/384/512、NIST FIPS 186 - 4 P 256/384/521、RFC 7748 - Curve25519、 RFC 8032 - ED25519(即EDDSA)的公私钥对生成,及由给定的私钥生成其对应的公钥。
- 支持RFC 5639 - Brainpool 256/384/512、NIST FIPS 186 - 4 P 256/384/521、RFC 7748 - Curve25519的密钥交换(ECDH)。
-
曲线上点的验证功能支持验证给定的点是否在对应的曲线上。具体规格:
支持RFC 5639 - Brainpool 256/384/512、NIST FIPS 186 - 4 P 256/384/521和SM2的点是否在曲线上的验证。
-
大数运算功能支持多种算子的大数运算。具体规格:
- 支持256/384/521/2048/3072/4096位的模加、模减、模乘和模运算。
- 支持256/384/521的模逆、乘法运算;支持密钥位宽为256位的Curve25519蒙哥马利点乘。
- 支持密钥位宽为256位的ED25519 ED点乘。
- 支持密钥位宽为256/384/521位的ED点加(Uranus ES不支持)。
- 支持密钥位宽为256/384/521位的ECC点乘、点加、倍点运算。
- 支持2048/3072/4096位的模幂运算。
-
PKE具体应用方法,请参考文档《安全子系统 API 参考》。
对称密码算法和HASH算法
SPACC
注意:
- AES ECB模式及TDES算法为弱密码算法,建议正式商用的产品不使用。
- Hi3519DV500不支持密钥长度为192的算法。
- Hi3516CV610、Hi3511CV100只支持SHA256和SM3哈希算法。
SPACC模块实现了TDES对称密码算法、AES对称密码算法、国密算法和HASH摘要算法。
AES算法的实现符合FIPS 197 标准;AES 的工作模式符合NIST special800-38a 标准。
SHA算法实现符合FIPS180-2标准,HMAC_SHA算法实现符合RFC2104标准。
具体规格:
- 支持AES ECB/CBC/OFB/CFB/CTR/CCM/GCM。
- 支持AES128/192/256。
- 支持国密算法SM4 ECB/CBC/OFB/CFB/CTR。
- 支持SHA256、HMAC-SHA256、SHA384、HMAC-SHA384、SHA512、HMAC-SHA512。
-
支持国密算法SM3、HMAC-SM3
-
AES算法和HMAC算法支持基于硬件根密钥派生工作密钥进行加解密(如二级KLAD)
- SPACC模块的具体应用方法,请参考文档《安全子系统 API 参考》。
密钥衍生算法
PBKDF2
说明:
Hi3516CV610、Hi3511CV100只支持SHA256、SM3算法。
密钥衍生模块实现了PBKDF2算法。PBKDF2常用于对密码进行加密。具体规格:
支持使用HMAC-SHA256、HMAC-SHA384、HMAC-SHA512进行散列
PBKDF2算法的具体应用方法,请参考文档《安全子系统 API 参考》。
安全启动
Hi35xxVxx 支持基于芯片硬件可信根的安全启动。支持对U-Boot,TEE OS进行验签,加解密。内核镜像和文件系统的验签和加解密可在U-Boot中定制化修改。支持OEM和第三方双签名。芯片OTP中存储public key的hash值作为安全启动签名校验的起点(可信根)。OTP中的可信根以及数据加解密根密钥完全由客户自行管理并烧录,并受硬件保护,软件不可读写。
安全启动流程分为两部分,一部分固化在芯片内,称为BOOTROM;一部分在软件中实现,称为Secure BOOT或GSL。BOOTROM流程不可篡改。GSL由BOOTROM验签,GSL流程安全性由BOOTROM保证。GSL负责实现对后续镜像的验签功能,进而保证全部启动通路的安全性。
强烈建议在产品开发中使用安全启动。安全启动更详细的信息,请参考文档《Hi35xxVxx 安全启动使用指南》。
Linux 启动后快速补充熵池
Linux启动后,内核熵池处于未满的状态,此时读取/dev/random节点会发生阻塞,读取/dev/urandom节点的随机数质量又可能无法保证,这将导致一些依赖“内核熵池已满”条件的操作无法执行,此处提供一种在Linux内核启动后快速为内核熵池高质量补充熵的操作示例。
-
编译内核:以musl工具链为例。
-
开启内核硬件随机数模块编译选项:
cd third_party/linux/linux-5.10.y
make ARCH=arm CROSS_COMPILE=arm-v01c02-linux-musleabi- menuconfig //使能Hardware Random Number Generator Core support
-
进入配置选择页面,依次进入Device Drivers->Character devices->Hardware Random Number Generator Core support,按Y选中保存并退出
- make ARCH=arm CROSS_COMPILE=arm-v01c02-linux-musleabi- savedefconfig //生成defconfig文件
- cp defconfig arch/arm/configs/hi35xxvxx_new_defconfig //将生成的defconfig文件拷贝为新的defconfig文件
-
编译内核
cd boards/dmeb
make KERNEL_CFG=hi35xxvxx_new_defconfig kernel DEBUG=1 -j
-
烧录uImage镜像,启动后单板上应可见/dev/hwrng设备节点。
-
-
编写增熵用的用户态程序。以下为伪代码实现流程,是一种通用的增熵方法,如有其他高质量熵源,同样可以使用类似的方法为内核快速补熵:
/* The value can be obtained by reading the /proc/sys/kernel/random/poolsize file, and its unit is in bits. */ Define constant MAX_ENTROPY_POOL_SIZE as 256 /* Please ensure that this value multiplied by 8 is greater than or equal to MAX_ENTROPY_POOL_SIZE, and the unit of this value is in bytes. */ Define constant MAX_RANDOM_BUF_SIZE as 32 Define structure entropy { Integer variable entropy_count Integer variable buf_size Byte buffer pointer buf } Function main() { Define integer variables ret, hwrng_fd, rand_fd Define integer variable rd Define structure variable ent Define byte buffer buf[with size MAX_RANDOM_BUF_SIZE] Set ent.entropy_count to MAX_ENTROPY_POOL_SIZE Set ent.buf_size to MAX_RANDOM_BUF_SIZE Set ent.buf to the address of buf Open file "/dev/random" in write mode, store file descriptor in rand_fd If rand_fd < 0, then { Output error "Failed to open /dev/random!" Exit the program } Open file "/dev/hwrng" in read mode, store file descriptor in hwrng_fd If hwrng_fd < 0, then { Output error "Failed to open /dev/hwrng!" Close rand_fd Exit the program } Read MAX_RANDOM_BUF_SIZE bytes from hwrng_fd into buffer buf, save the number of bytes read into rd If rd < 0, then { Output error "Failed to read /dev/hwrng!" Close rand_fd Close hwrng_fd Exit the program } Perform ioctl operation, add bytes from buffer buf to the entropy pool, command is RNDADDENTROPY If ret < 0, then { Output error "Failed to add entropy to the pool!" Close rand_fd Close hwrng_fd Exit the program } Close hwrng_fd Close rand_fd Output "Entropy added successfully." Return 0 }上述伪代码的工作流程可概括为两步,第一步从/dev/hwrng节点获取高质量熵,第二步通过对/dev/random节点进行IOCTL将熵补充进熵池。以下为伪代码的一种参考示例:
#include <linux/random.h> #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <sys/ioctl.h> /* The value can be obtained by reading the /proc/sys/kernel/random/poolsize file, and its unit is in bits. */ #define MAX_ENTROPY_POOL_SIZE 256 /* Please ensure that this value multiplied by 8 is greater than or equal to MAX_ENTROPY_POOL_SIZE, and the unit of this value is in bytes. */ #define MAX_RANDOM_BUF_SIZE 32 typedef struct entropy { int entropy_count; int buf_size; unsigned char *buf; } entropy; int main() { int ret, hwrng_fd, rand_fd; ssize_t rd; struct entropy ent; unsigned char buf[MAX_RANDOM_BUF_SIZE]; ent.entropy_count = MAX_ENTROPY_POOL_SIZE; ent.buf_size = MAX_RANDOM_BUF_SIZE; ent.buf = buf; rand_fd = open("/dev/random", O_WRONLY); if (rand_fd < 0) { perror("Failed to open /dev/random!\n"); exit(1); } hwrng_fd = open("/dev/hwrng", O_RDONLY); if (hwrng_fd < 0) { perror("Failed to open /dev/hwrng!\n"); close(rand_fd); exit(1); } // read MAX_RANDOM_BUF_SIZE bytes from /dev/hwrng rd = read(hwrng_fd, buf, MAX_RANDOM_BUF_SIZE); if (rd < 0) { perror("Failed to read /dev/hwrng!\n"); close(rand_fd); close(hwrng_fd); exit(1); } // add bytes to the entropy pool ret = ioctl(rand_fd, RNDADDENTROPY, &ent); if (ret < 0) { perror("Failed to add entropy to the pool!\n"); close(rand_fd); close(hwrng_fd); exit(1); } close(hwrng_fd); close(rand_fd); printf("Entropy added successfully.\n"); return 0; } -
编译sample,以musl工具链为例:
将上述文件命名为sample.c
arm-v01c02-linux-musleabi-gcc sample.c -o sample //编译sample
-
启动流程添加执行sample文件操作:将编译得到的可执行文件sample拷贝到/usr/bin目录下,并在启动文件/etc/init.d/S00devs文件尾部添加“sample”,保存后退出。
完成上述四个步骤后,重新启动Linux,启动后系统将会自动执行sample文件将内核熵池填充至可用。
须知:
- 此操作需要root权限。
- 若用户需要进一步增加内核熵池的随机性,可将MAX_RANDOM_BUF_SIZE值进一步调大。
- 这种方法不仅仅可以用于启动阶段增加内核可用熵,在启动完成后,执行sample可执行文件也可以达到更新内核熵池,增加熵池随机性的效果。
- Hi3516CV610/Hi3516CV608/Hi3511CV100 只支持 musl 工具链。
MbedTLS 开源软件硬化加速
MbedTLS 开源软件是一款开源的轻量级加密库,其提供了一系列密码学和安全协议的实现,包括对称加密、非对称加密、散列函数、消息认证码、数字签名、密钥交换、安全套接层(SSL/TLS)以及 X.509 证书管理等。MbedTLS 具有简洁、可移植和易于使用的特点,具备高度优化的性能和低资源消耗,被广泛应用于资源受限的嵌入式设备和应用程序中。Hi35xxVxx 基于 MbedTLS 开源软件提供了一些安全算法的硬件实现,其底层调用安全子系统驱动和专用硬件进行硬化加速,提供高算法计算性能的同时,减少了 CPU 的计算开销。该硬化方案提供的接口和MbedTLS原生接口一致,无附加学习成本。
如需使用,需自行安装开源软件至服务器。
Linux Crypto硬化加速
Linux Crypto是linux内核中用于提供加密、解密、哈希计算、消息认证码(MAC)生成等密码学相关操作的子系统。它为用户空间程序和内核自身的组件提供了统一的密码学接口,使得在 Linux 系统中能够方便、安全地使用各种密码学算法。通过内核提供的注册接口,将硬件驱动对接到linux crypto框架,提供高算法计算性能的同时,减少了 CPU 的计算开销。当前支持AES-CBC、CTR、CCM、GCM模式和SHA256(Hi3519DV500支持SHA384/SHA512)的硬化加速。
利用开源软件cryptodev-linux可将内核加解密接口导出到用户态,供应用程序使用。如何使用请参考security_subsys/hardware_cryptodev目录下的readme_cn.txt。
须知:
- ccm工作模式下,iv固定16字节,首字节数值限制在1-7之间。
- debug模式下需要修改hard_crypto_debug值,修改路径:security_subsys/hardware_cryptodev/ot_reg.c。
支持安全、非安全内存地址隔离
TZASC
Hi35xxVxx 提供TZASC模块,支持对内存地址空间进行隔离控制,使CPU和其他SoC组件在处于安全模式和非安全模式等不同特权模式下,对内存的访问权限进行硬件级别的控制。这是实现基于ARM TrustZone 下的TEE、REE隔离的基础。
TZASC全称是TrustZone Address Space Controller,它是Advanced Microcontroller Bus Architecture(AMBA)兼容的SoC外围组件,可对接AMBA AXI和AMBA APB接口。
Hi3519DV500的TZASC模块提供了16个区域,其中15个区域可配(region1~region15)。region0固定使能,无法配置访问属性,大小覆盖除了region1~region15区域以外的所有内存区域。任何组件(无论是安全还是非安全)都无法访问region0覆盖的内存。
其余内存区域的访问属性,可以根据需要,选择下面四个属性单元的组合:
- 安全可读属性
- 安全可写属性
- 非安全可读属性
- 非安全可写属性
TZASC模块的bypass属性控制着模块是否使能:
- 默认bypass属性使能,TZASC模块处于失能状态,内存访问不受限制;
- 设置bypass属性失能,TZASC模块将会使能,各内存区域的访问属性生效。
TZASC控制的参考代码,请参考发布包GSL源代码根目录下drivers/tzasc/tzasc.c,该代码在boot/checkup.c中调用。
须知:
- bypass属性使能被锁定之后,在系统复位前无法再次使能鉴权功能。
- TZASC的配置,建议客户在系统启动之后,只做一次配置,不要多次动态调整,以避免处理不当导致其他异常。
- Hi3511CV100不涉及TZASC。
TZASC寄存器
TZASC寄存器偏移地址中变量的取值范围和含义如表1所示。
表 1 TZASC寄存器偏移地址变量表
说明:
以下寄存器描述中未特殊说明的时钟周期皆为DDRC时钟周期。
表 2 TZASC寄存器概览(基址是0x0_1114_1000)
SEC_BYPASS
SEC_BYPASS为安全功能使能。
Offset Address: 0x004 Total Reset Value: 0x0000_00a5
SEC_LOCKDOWN_SELECT
SEC_LOCKDOWN_SELECT为锁定安全属性相关配置寄存器。
Offset Address: 0x010 Total Reset Value: 0x0000_0000
SEC_LOCKDOWN_SELECT2
SEC_LOCKDOWN_SELECT2为锁定安全属性相关配置寄存器2。
Offset Address: 0x014 Total Reset Value: 0x0000_0000
SEC_INT_MSK_WMID
SEC_INT_MSK_WMID为写MID的中断屏蔽寄存器。
Offset Address: 0x018 Total Reset Value: 0x0000_0000
SEC_INT_MSK_RMID
SEC_INT_MSK_RMID为读MID的中断屏蔽寄存器。
Offset Address: 0x01C Total Reset Value: 0x0000_0000
SEC_INT_EN
SEC_INT_EN为中断使能寄存器。
Offset Address: 0x020 Total Reset Value: 0x0000_0001
SEC_INT_STATUS
SEC_INT_STATUS为中断状态寄存器。
Offset Address: 0x024 Total Reset Value: 0x0000_0000
SEC_INT_CLEAR
SEC_INT_CLEAR为中断清除寄存器。
Offset Address: 0x028 Total Reset Value: 0x0000_0000
SEC_FAIL_CMD_INF_0
SEC_FAIL_CMD_INF_0为首个越权命令的信息0。
Offset Address: 0x080 Total Reset Value: 0x0000_0000
SEC_FAIL_CMD_INF_1
SEC_FAIL_CMD_INF_1为首个越权命令的信息1。
Offset Address: 0x084 Total Reset Value: 0x0000_0000
SEC_FAIL_CMD_INF_2
SEC_FAIL_CMD_INF_2为首个越权命令的信息2。
Offset Address: 0x088 Total Reset Value: 0x0000_0000
SEC_RGN_MAP
SEC_RGN_MAP为地址区域映射寄存器。
Offset Address: 0x100+0x10*sec_regions Total Reset Value: 0x0000_0000
SEC_RGN_ATTRIB
SEC_RGN_ATTRIB为各地址区域的权限属性设置寄存器。
Offset Address: 0x104+0x10*sec_regions Total Reset Value: 0x0000_0000
SEC_MID_WR
SEC_MID_WR为写命令匹配MasterID及其掩码。
Offset Address: 0x108+0x10*sec_regions Total Reset Value: 0xffff_ffff
SEC_MID_RD
SEC_MID_RD为读命令匹配MasterID及其掩码。
Offset Address: 0x10C+0x10*sec_regions Total Reset Value: 0xffff_ffff
SEC_RGN_MAP_EXT
SEC_RGN_MAP_EXT设置当前区域的大小。
Offset Address: 0x200+0x10*sec_regions Total Reset Value: 0x0000_0000
SEC_MID_WR_EXT
SEC_MID_WR_EXT为写命令匹配MasterID及其掩码。(高32个MID)。
Offset Address: 0x204+0x10*sec_regions Total Reset Value: 0xffff_ffff
SEC_MID_RD_EXT
SEC_MID_RD_EXT为读命令匹配MasterID及其掩码。(高32个MID)。
Offset Address: 0x208+0x10*sec_regions Total Reset Value: 0xffff_ffff
SEC_MASTER_TYPE1_EXT
SEC_MASTER_TYPE1_EXT为master的写命令鉴权类型1(高32个MID)。
Offset Address: 0x21C Total Reset Value: 0x0000_0000
|
0:mid为n的安全写访问到非共享区域中的某个地址区域时,该地址区域是允许安全写,则允许访问; 1:mid为n的安全写访问到非共享区域中的某个地址区域时,该地址区域必须是允许安全写且不允许非安全读的属性,则允许访问。 |
SEC_MASTER_TYPE1
SEC_MASTER_TYPE1为master的写命令鉴权类型1。
Offset Address: 0x310 Total Reset Value: 0x0000_0000
|
0:mid为n的安全写访问到非共享区域中的某个地址区域时,该地址区域是允许安全写,则允许访问; 1:mid为n的安全写访问到非共享区域中的某个地址区域时,该地址区域必须是允许安全写且不允许非安全读的属性,则允许访问。 |
SEC_INT_MSK_WMID
SEC_INT_MSK_WMID为写MID的中断屏蔽。
Offset Address: 0x330 Total Reset Value: 0x0000_0000
SEC_INT_MSK_RMID
SEC_INT_MSK_RMID为读MID的中断屏蔽。
Offset Address: 0x334 Total Reset Value: 0x0000_0000
SEC_ITCRG
SEC_ITCRG为集成测试控制寄存器。
Offset Address: 0x3C0 Total Reset Value: 0x0000_0000
SEC_ITOP
SEC_ITOP为集成测试输出寄存器。
Offset Address: 0x3C8 Total Reset Value: 0x0000_0000
OP-TEE
OP-TEE(Open-source Portable Trusted Execution Environment)是一个开源工程,完整的实现了一个可信执行环境。该项目最初由意法-爱立信所发起并由ST半导体拥有和维护,2014年Linaro开始与意法半导体合作将这个专有的TEE解决方案转换成一个开源的TEE解决方案。
说明:
Hi3511CV100不涉及OP-TEE。 Hi3516CV610生态版本暂未开发OP-TEE。
NPU 安全特性
说明:
Hi3516CV610、Hi3511CV100不涉及NPU。
NPU特性包括NPU的模型安全和NPU的数据安全。NPU 模型安全功能可以保证 NPU 模型的机密性,支持在NPU上运行加密后的模型。模型数据安全依赖TEE环境。模型输出数据存放在TEE安全内存,可防止数据泄露、恶意篡改。模型tmpbuf使用安全内存,可用于防止运行过程数据泄露、恶意篡改。使用方法请参考SVP_NPU 《安全开发指南》。
安全Debug
FUNC JTAG
说明:
Hi3516CV610不支持FUNC JTAG密码保护模式。 FUNC JTAG即为功能JTAG,用于在功能模式下调试SoC的JTAG接口。
芯片的FUNC JTAG调试接口可以通过OTP进行打开模式、密码模式、永久关闭模式的切换,默认为打开模式。OTP烧写的具体操作方法,请参照本文“OTP字段定义”和文档《安全子系统 API 参考》。
通过JTAG调试接口对SoC进行调试,需要配套的调试板和PC对应的软件工具。
JTAG的模式由OTP中的func_jtag_mode来控制。
- 0x42:打开,即无需任何权鉴即可连通JTAG;此状态为芯片出厂的状态。
- 0x63:密码保护模式,需要输入正确的芯片唯一JTAG密码才可连通JTAG;JTAG密码为一机一密,由硬件KDF自动根据obfu_mrk1和die_id派生,obfu_mrk1由OEM生成并管理,其值仅OEM可知;输入JTAG 密码前需要获取芯片的die_id,再使用KDF派生工具即可派生出对应的JTAG密码。
- 其他:jtag关闭,即不可用。
注意:
func_jtag_mode具有oneway属性,即一旦烧写为密码保护状态或者关闭状态,就永久不能回退到打开状态,也就意味着永久将JTAG调试功能禁用,烧写前需要注意。 FUNC JTAG保持打开会给最终产品引入严重的安全风险,强烈建议在最终出厂前烧写为密码保护模式或者关闭模式。
DFT JTAG
说明:
Hi3516CV610不支持DFT JTAG密码保护模式。 DFT JTAG即为测试JTAG,用于在测试模式下对SoC灌入测试向量,执行芯片筛片测试和失效分析测试的JTAG接口。
芯片的DFT JTAG调试接口可以通过OTP进行打开模式、密码模式、永久关闭模式的切换,默认为打开模式。OTP烧写的具体操作方法,请参照本文“OTP字段定义”和文档《安全子系统 API 参考》。
通过JTAG调试接口对SoC进行调试,需要配套的调试板和PC对应的软件工具。
JTAG的模式由OTP中的dft_test_jtag_mode来控制。
- 0x42:打开,即无需任何权鉴即可连通JTAG;此状态为芯片出厂的状态。
- 0x63:密码保护模式,需要输入正确的芯片唯一JTAG密码才可连通JTAG;JTAG密码为一机一密,由硬件KDF自动根据obfu_mrk0和die_id派生,obfu_mrk0由芯片厂商生成并管理,其值仅芯片厂商可知;输入JTAG 密码前需要获取芯片的die_id,再使用KDF派生工具即可派生出对应的JTAG密码。
- 其他:jtag关闭,即不可用。
注意:
dft_test_jtag_mode具有oneway属性,即一旦烧写为密码保护状态或者关闭状态,就永久不能回退到打开状态,也就意味着永久将芯片失效分析测试功能禁用,烧写前需要注意。 DFT JTAG保持打开会给最终产品引入一定的安全风险,考虑到DFT JTAG保护密码和DFT JTAG向量仅由芯片厂商掌握,因此其安全风险没有FUNC JTAG高,但仍建议OEM在明确没有复测需求的场景下将DFT JTAG烧写为关闭模式。