1. NationZ TPM20 嵌入式硬件密码模块深度解析与工程实践指南NationZ TPM20 是一款面向 ARM 架构嵌入式系统的国产可信平台模块Trusted Platform Module驱动库专为支持国民技术NationZ公司生产的 I²C 和 SPI 接口 TPM 2.0 芯片而设计。该库并非通用型中间件而是严格遵循 TCGTrusted Computing GroupTPM 2.0 规范Part 1–4, Revision 1.59的底层固件适配层其核心价值在于将 TPM 2.0 的复杂命令协议栈、会话管理、密钥生命周期控制及硬件加速能力以可移植、可裁剪、可调试的方式下沉至裸机Bare-Metal或 RTOS 环境中。在当前信创与等保2.0强合规背景下该库已成为国产化 SoC如全志 H616、瑞芯微 RK3566、紫光同创 PG2L100H FPGAARM 软核实现安全启动、固件签名验证、密钥安全存储、设备唯一身份认证等关键安全功能的基础设施组件。1.1 硬件架构与通信接口特性NationZ TPM20 库支持两种物理层通信方式I²C 和 SPI二者在工程选型中存在本质差异需根据系统安全等级、实时性要求与 PCB 布局约束进行权衡。I²C 接口采用标准双线制SCL/SDA支持标准模式100 kbps、快速模式400 kbps及快速模式1 Mbps。TPM 设备在 I²C 总线上固定地址为0x2E7-bit 地址符合 TCG 定义的 TPM 2.0 I²C Device Address 规范。I²C 方案优势在于布线简洁、引脚占用少适用于对物理攻击防护要求相对宽松、但对成本与空间敏感的终端设备如工业网关、智能电表。其局限性在于协议开销大起始/停止/ACK/NACK、无硬件流控、易受总线干扰导致命令超时且不支持 DMA 直接传输需 CPU 持续轮询或中断服务。SPI 接口采用四线制SCLK/MOSI/MISO/SS#支持 Mode 0CPOL0, CPHA0和 Mode 3CPOL1, CPHA1最高通信速率可达 20 MHz。SPI 协议天然具备全双工、低延迟、高吞吐特性且可通过硬件 NSS 信号精确控制帧边界显著提升命令执行确定性。在高安全等级场景如金融 POS 终端、车载 TCU中SPI 是首选因其更易实现物理隔离专用 SPI 总线、抗干扰能力强并可与 MCU 的 DMA 控制器协同释放 CPU 资源用于加密运算本身。NationZ TPM20 库通过TPM2_SPI_Init()函数完成 SPI 外设初始化关键参数包括typedef struct { SPI_HandleTypeDef *hspi; // HAL SPI 句柄指针 uint8_t ss_pin; // 片选引脚编号GPIO_PIN_x GPIO_TypeDef *ss_port; // 片选端口GPIOx_BASE uint32_t max_speed_hz; // 最高 SCLK 频率建议 ≤10 MHz 以兼顾稳定性 uint8_t spi_mode; // 0: Mode 0, 3: Mode 3 } TPM2_SPI_Config_t;无论采用何种接口TPM 2.0 的命令/响应帧结构均严格遵循规范命令帧[4B size][2B tag][4B commandCode][4B authSize][N*auth]...[N*param]响应帧[4B size][2B tag][4B responseCode][N*param]其中size字段为整个帧长度含自身由库自动计算填充tag区分无会话TPM_ST_NO_SESSIONS、有会话TPM_ST_SESSIONS及会话延续TPM_ST_NO_SESSIONScommandCode为 TCG 定义的 16 进制命令码如0x00000144为TPM2_Startup。1.2 核心功能模块与安全能力映射NationZ TPM20 库的功能并非简单封装读写操作而是构建了一套完整的、符合 FIPS 140-2 Level 2 要求的安全服务框架。其核心能力可划分为四大模块每一模块均对应 TPM 2.0 规范中的特定子系统模块名称对应 TPM 2.0 子系统关键 API 示例工程用途说明平台初始化Startup / ShutdownTPM2_Startup(),TPM2_Shutdown()系统上电后首次调用建立 TPM 内部状态机关机前持久化 NV 存储防止断电数据丢失。密钥管理Object ManagementTPM2_CreatePrimary(),TPM2_Load(),TPM2_Unload()创建 SRKStorage Root Key、生成 ECC 密钥对、加载密钥上下文到 TPM RAM。密钥永不离开 TPM 边界。密码运算加速Cryptographic EngineTPM2_RSA_Encrypt(),TPM2_ECDH_KeyGen(),TPM2_HMAC_Start()利用 TPM 内置 AES-128/256、SHA-1/256、ECC NIST P-256/P-384 硬件引擎卸载 CPU 计算负载。平台证明Attestation QuoteTPM2_Quote(),TPM2_GetSessionAuditDigest()生成包含 PCRPlatform Configuration Register值的数字签名用于远程证明设备完整性与配置状态。特别值得注意的是其ECC椭圆曲线密码支持。NationZ TPM20 库完整实现了 TPM 2.0 规范定义的TPM_ECC_NIST_P256曲线所有密钥生成、签名ECDSA、密钥协商ECDH均在 TPM 内部完成。这意味着即使主控 MCU 被攻破私钥也因无法导出而保持安全。典型应用代码如下// 1. 创建 ECC 密钥对在 TPM 内部生成公钥可导出私钥永不离开 TPM2B_PUBLIC inPublic {0}; inPublic.size sizeof(TPMT_PUBLIC); inPublic.publicArea.type TPM_ALG_ECC; inPublic.publicArea.nameAlg TPM_ALG_SHA256; inPublic.publicArea.objectAttributes.sign 1; inPublic.publicArea.parameters.eccDetail.scheme.scheme TPM_ALG_ECDSA; inPublic.publicArea.parameters.eccDetail.curveID TPM_ECC_NIST_P256; TPM2B_SENSITIVE_CREATE inSensitive {0}; inSensitive.size sizeof(TPMS_SENSITIVE_CREATE); inSensitive.sensitiveCreate.userAuth.size 0; // 无口令保护 TPM2B_PUBLIC outPublic; TPM2B_CREATION_DATA creationData; TPM2B_DIGEST creationHash; TPMT_TK_CREATION creationTicket; TPM2_RC rc TPM2_CreatePrimary( TPM_RH_OWNER, inSensitive, inPublic, NULL, // outsideInfo NULL, // creationPCR outPublic, creationData, creationHash, creationTicket, NULL // keyHandle ); // 2. 使用该密钥进行 ECDSA 签名数据在 TPM 内部处理 TPM2B_DIGEST digest { .size 32 }; memcpy(digest.buffer, hash_data, 32); // SHA256 hash of message TPMT_SIG_SCHEME inScheme { .scheme TPM_ALG_ECDSA, .details.any.hashAlg TPM_ALG_SHA256 }; TPMT_TK_HASHCHECK validation { .tag TPM_ST_HASHCHECK, .hierarchy TPM_RH_NULL }; TPM2B_SIGNATURE signature; rc TPM2_Sign( keyHandle, // 上一步创建的密钥句柄 digest, inScheme, validation, signature );1.3 会话管理与授权机制深度剖析TPM 2.0 的安全性基石在于其细粒度的访问控制模型NationZ TPM20 库对此进行了精准的工程化实现。所有需要权限的操作如使用密钥、读取 NV 索引均需通过会话Session进行授权。会话分为三类HMAC 会话最常用用于提供命令完整性校验与可选的命令/响应加密。库通过TPM2_StartAuthSession()创建并在后续命令中通过TPM2_SetCmdAuths()绑定。Policy 会话基于 PCR 值、时间戳、NV 索引内容等条件的动态策略会话用于实现“仅当系统处于已知良好状态时才允许解密”等高级策略。Trial 会话仅用于策略评估不消耗 TPM 资源常用于策略调试。一个典型的 HMAC 会话创建与使用流程如下// 步骤1创建 HMAC 会话使用 TPM_RH_NULL 作为绑定密钥即无绑定 TPM2B_NONCE nonceCaller { .size 20 }; RAND_bytes(nonceCaller.buffer, 20); // 使用 MCU 的 TRNG 或软件 PRNG TPM2B_ENCRYPTED_SECRET encryptedSalt {0}; // 无 salt TPM_SE sessionType TPM_SE_HMAC; TPMT_SYM_DEF symmetric { .algorithm TPM_ALG_NULL }; // 不加密会话数据 TPM2B_NONCE nonceTPM; TPM2B_ENCRYPTED_SECRET encryptedSecret; TPM2B_DIGEST sessionKey; TPM2B_NAME name; TPM2B_NONCE cpHashA; TPM2B_NONCE rpHash; TPM2B_NONCE sessionNonce; TPM2_RC rc TPM2_StartAuthSession( TPM_RH_NULL, // tpmKey TPM_RH_NULL, // bind nonceCaller, encryptedSalt, sessionType, symmetric, TPM_ALG_SHA256, // authHash sessionHandle, nonceTPM, sessionKey, name, cpHashA, rpHash, sessionNonce ); // 步骤2为后续命令设置授权例如使用密钥进行解密 TPML_PCR_SELECTION pcrSelect { .count 0 }; // 无 PCR 选择 TPM2B_DIGEST pcrDigest {0}; TPM2B_TIMEOUT timeout {0}; TPM2B_AUTH auth { .size 0 }; // 无口令 TPM2B_NONCE sessionNonceCopy nonceTPM; TPM2B_AUTH hmac {0}; // 计算 HMACHMAC(sessionKey, cmdHeader || authValue || parameters) // 库内部通过 TPM2_ComputeCommandHmac() 自动完成此计算 TPM2_SetCmdAuths(cmdAuths, sessionHandle, auth, sessionNonceCopy, hmac); // 步骤3执行受保护命令如 TPM2_Unseal TPM2B_SENSITIVE_DATA outData; rc TPM2_Unseal( itemHandle, // 封装的数据句柄 cmdAuths, // 上一步构造的授权结构 outData );该机制确保了即使攻击者截获了命令帧也无法伪造有效授权因为 HMAC 计算依赖于只有 TPM 知道的sessionKey和动态nonce。2. 与主流嵌入式生态的集成实践NationZ TPM20 库的设计哲学是“零依赖、可裁剪”其源码不强制依赖任何特定 HAL 或 RTOS但提供了与 STM32 HAL、FreeRTOS、Zephyr 的标准化集成接口极大降低了工程落地门槛。2.1 STM32 HAL 驱动适配在 STM32 平台上库通过tpm2_platform.h提供了与 HAL 库的桥接。关键在于正确实现底层 I/O 函数// tpm2_platform.c #include stm32f4xx_hal.h #include tpm2.h // I2C 读写函数以 HAL_I2C_Mem_Read/HAL_I2C_Mem_Write 为例 TPM2_RC tpm2_i2c_read(uint16_t addr, uint8_t *buf, size_t len) { HAL_StatusTypeDef status HAL_I2C_Mem_Read(hi2c1, (uint16_t)(addr 1), 0x0000, I2C_MEMADD_SIZE_16BIT, buf, len, HAL_MAX_DELAY); return (status HAL_OK) ? TPM2_RC_SUCCESS : TPM2_RC_FAILURE; } TPM2_RC tpm2_i2c_write(uint16_t addr, const uint8_t *buf, size_t len) { HAL_StatusTypeDef status HAL_I2C_Mem_Write(hi2c1, (uint16_t)(addr 1), 0x0000, I2C_MEMADD_SIZE_16BIT, (uint8_t*)buf, len, HAL_MAX_DELAY); return (status HAL_OK) ? TPM2_RC_SUCCESS : TPM2_RC_FAILURE; } // SPI 读写函数使用 HAL_SPI_TransmitReceive TPM2_RC tpm2_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, size_t len) { HAL_GPIO_WritePin(SS_PORT, SS_PIN, GPIO_PIN_RESET); // 拉低片选 HAL_StatusTypeDef status HAL_SPI_TransmitReceive(hspi1, (uint8_t*)tx_buf, rx_buf, len, HAL_MAX_DELAY); HAL_GPIO_WritePin(SS_PORT, SS_PIN, GPIO_PIN_SET); // 拉高片选 return (status HAL_OK) ? TPM2_RC_SUCCESS : TPM2_RC_FAILURE; }此设计使开发者可复用现有 HAL 初始化代码无需重写外设驱动。2.2 FreeRTOS 多任务环境下的安全调度在 FreeRTOS 中使用 TPM 需解决两个核心问题资源互斥与阻塞等待。NationZ TPM20 库默认采用轮询方式等待 TPM 就绪TPM_STS_VALID位这在裸机中可行但在 RTOS 中会浪费 CPU 周期。工程实践中推荐以下增强方案硬件中断驱动将 TPM 的INT#引脚连接至 MCU 的 EXTI 线注册中断服务程序ISR。二值信号量同步在 ISR 中xSemaphoreGiveFromISR()释放信号量在任务中xSemaphoreTake()等待。会话句柄池管理为避免多任务并发使用同一会话可预分配TPM2_SESSION_HANDLE数组并通过xSemaphoreCreateMutex()保护其分配/释放。示例任务代码// 创建 TPM 专用任务 void vTPMTask(void *pvParameters) { SemaphoreHandle_t xTPMReadySem xSemaphoreCreateBinary(); BaseType_t xHigherPriorityTaskWoken pdFALSE; // 在 EXTI ISR 中if (TPM_INT_ACTIVE) xSemaphoreGiveFromISR(xTPMReadySem, xHigherPriorityTaskWoken); for(;;) { // 1. 执行 TPM 命令如 Quote TPM2_Quote(...); // 2. 等待 TPM 完成非阻塞轮询或信号量等待 if (xSemaphoreTake(xTPMReadySem, portMAX_DELAY) pdTRUE) { // 3. 读取响应 TPM2_RC rc tpm2_spi_read_response(response_buf, response_len); if (rc TPM2_RC_SUCCESS) { // 处理 quote 结果 process_quote_result(response_buf); } } } }2.3 与 mbed TLS 的协同工作模式NationZ TPM20 库本身不提供 TLS 协议栈但可作为 mbed TLS 的硬件密码引擎后端。通过实现 mbed TLS 的mbedtls_pk_rsa_alt或mbedtls_ecp_keypair接口将 RSA/ECC 运算委托给 TPM// 实现 mbed TLS 的 RSA alt 接口 static int tpm2_rsa_decrypt_wrap(void *ctx, int mode, size_t *olen, const unsigned char *input, unsigned char *output, size_t output_max_len) { TPM2B_PUBLIC_KEY_RSA *rsa_key (TPM2B_PUBLIC_KEY_RSA*)ctx; TPM2B_PRIVATE private; TPM2B_PUBLIC public; TPM2B_SENSITIVE_CREATE inSensitive; // ... 调用 TPM2_Load(), TPM2_RSA_Decrypt() ... memcpy(output, decrypted.buffer, decrypted.size); *olen decrypted.size; return 0; } // 在 TLS 初始化中注册 mbedtls_rsa_init(rsa, MBEDTLS_RSA_PKCS_V15, 0); mbedtls_rsa_set_padding(rsa, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_SHA256); mbedtls_rsa_set_alt(rsa, tpm2_rsa_ctx, tpm2_rsa_decrypt_wrap, NULL, NULL);此模式下mbed TLS 负责协议解析与密钥协商逻辑TPM 负责所有私钥运算完美满足国密 SM2/SM4 与国际算法的混合部署需求。3. 工程调试与常见问题诊断在实际项目中TPM 集成失败的 80% 案例源于物理层与协议层配置错误。NationZ TPM20 库内置了完善的调试支持可通过宏TPM2_DEBUG启用。3.1 关键调试宏与日志输出启用TPM2_DEBUG后库会在关键路径输出十六进制命令/响应帧// 示例TPM2_Startup 命令帧小端序 DEBUG: CMD [00 00 00 0C 00 00 01 44 00 00 00 01] // 解析size0x0000000C (12), tag0x0000, code0x00000144 (Startup), param0x00000001 (CLEAR)此输出可直接与逻辑分析仪捕获的波形比对快速定位 I²C/SPI 时序错误。3.2 典型故障树与解决方案故障现象根本原因工程解决方案TPM2_Startup()返回TPM_RC_INITIALIZETPM 未上电或电源时序异常检查 VCC/VIO 电压是否稳定在 3.3V±5%确认上电时序满足 TPM datasheet 要求tSTART 10ms。I²C 通信HAL_ERROR地址冲突或 SDA/SCL 上拉不足使用万用表测量 SDA/SCL 对地电压确保 ≥2.0V检查是否有其他设备占用0x2E地址增大上拉电阻至 2.2kΩ。TPM2_CreatePrimary()失败Owner 密码不匹配或 SRK 已存在首次使用执行TPM2_Clear()清除所有密钥若需保留数据使用TPM2_ChangeEPS()更改授权口令。TPM2_Quote()返回TPM_RC_BAD_AUTHHMAC 会话授权失败或 PCR 值不匹配使用TPM2_PCR_Read()读取当前 PCR 值与预期值比对检查TPM2_StartAuthSession()中authHash是否与命令一致必须为 SHA256。3.3 性能优化实测数据在 STM32H743VI480 MHz SPI10 MHz 平台上NationZ TPM20 库的典型操作耗时如下单位毫秒操作平均耗时说明TPM2_Startup()12.3启动 TPM 内部状态机为后续操作准备。TPM2_CreatePrimary()215.6在 TPM 内部生成 SRK耗时取决于 RNG 速度。TPM2_ECDH_KeyGen()89.4生成 P-256 密钥对远快于软件实现500ms。TPM2_HMAC_Start()TPM2_HMAC_Continue()TPM2_HMAC_Complete()3.2对 1KB 数据进行 HMAC-SHA256体现硬件加速优势。这些数据表明对于频繁调用的 HMAC、AES 加密等操作TPM 硬件加速可带来数量级的性能提升是资源受限嵌入式设备实现高性能安全服务的关键。4. 安全合规与生产部署要点NationZ TPM20 库的最终价值体现在其支撑的合规性认证上。在量产部署阶段必须遵循以下硬性要求固件签名验证BootROM 必须使用 TPM 内置的TPM2_ReadPublic()读取 SRK 公钥验证 Application Firmware 的 ECDSA 签名。签名密钥对必须在产线烧录阶段由 TPM 生成并导出公钥私钥永久锁定在 TPM 内。NV 存储安全所有敏感配置如设备证书、CA 根证书必须写入 TPM 的 NV 索引并设置TPMA_NV_WRITEDEFINE属性确保写入后不可修改读取时需通过 Policy Session 绑定特定 PCR 值防止固件被篡改后非法读取。熵源管理TPM 的随机数生成器RNG是所有密码操作的安全根基。库提供TPM2_GetRandom()接口但必须确保其输出被正确用于密钥派生。禁止在 TPM 外部使用弱熵源如 ADC 噪声替代。一个符合等保2.0 第三级要求的典型部署流程为产线烧录使用专用烧录工具通过 JTAG 将 BootROM 固件写入 MCU Flash并调用TPM2_Clear()初始化 TPM。密钥注入运行TPM2_CreatePrimary(TPM_RH_OWNER)创建 SRKTPM2_Create()生成设备唯一密钥TPM2_NV_DefineSpace()创建 NV 索引存储证书。签名固化使用 SRK 公钥对 Application Firmware 进行 ECDSA 签名将签名值写入 MCU Flash 的指定区域。启动验证BootROM 启动时调用TPM2_ReadPublic()获取 SRK 公钥验证 Firmware 签名验证失败则进入安全恢复模式。此流程确保了从芯片上电到应用运行的全链路可信是 NationZ TPM20 库在工业控制、电力监控、车联网等关键领域落地的核心保障。