1. HSM启动与初始化验证

HSM启动与初始化验证 学习卡片

任务说明

本案例面向RH850/U2A系列MCU的HSM(硬件安全模块)验证场景,目标是在上电后确认HSM能够完成启动与初始化流程。验证范围限定为:HSM时钟配置生效、安全启动流程正常推进、HSM固件成功加载并进入就绪状态。验证手段通过读取HSM状态寄存器与启动阶段标志完成,不涉及密码运算功能测试。

验证环境与依赖

  • 硬件:RH850/U2A评估板(HSM域供电正常)
  • 调试器:Lauterbach Trace32 或 Renesas E2 emulator(用于连接HSM调试接口)
  • 软件:Renesas CS+ 或 IAR Embedded Workbench for RH850
  • 依赖文件:HSM固件镜像(hsm_fw.bin,由Renesas安全包提供,需烧录至HSM专用Flash区域)

HSM启动状态寄存器说明

HSM启动流程分为三个阶段:时钟稳定、安全启动(引导ROM校验)、固件加载。每个阶段完成后,硬件会置位对应的状态标志位。验证程序通过读取HSM状态寄存器(HSM_STS)判断当前所处阶段,并检查各阶段是否在规定超时时间内完成。

状态位偏移含义置位条件
CLK_RDYbit0HSM时钟就绪HSM内部PLL锁定且时钟稳定
BOOT_DONEbit1安全启动完成引导ROM完成HSM固件签名校验
FW_LOADEDbit2固件加载完成HSM固件从Flash加载至SRAM并跳转执行
HSM_READYbit3HSM就绪固件完成自初始化,进入空闲等待命令状态

关键完整代码

以下代码实现HSM启动状态的轮询验证,包含超时保护与阶段判定逻辑。代码可直接编译运行于RH850/U2A主核(锁步核),通过系统总线访问HSM寄存器。

#include <stdint.h>
#include <stdbool.h>

/* HSM寄存器映射(基地址以实际芯片手册为准) */
#define HSM_BASE_ADDR      0xF0A00000UL
#define HSM_STS_REG        (*(volatile uint32_t*)(HSM_BASE_ADDR + 0x0000))
#define HSM_CTL_REG        (*(volatile uint32_t*)(HSM_BASE_ADDR + 0x0004))

/* 状态位掩码 */
#define STS_CLK_RDY        (1UL << 0)
#define STS_BOOT_DONE      (1UL << 1)
#define STS_FW_LOADED      (1UL << 2)
#define STS_HSM_READY      (1UL << 3)

/* 超时参数(基于主核时钟周期数,需按实际频率调整) */
#define TIMEOUT_CLK        1000000UL   /* 时钟稳定最长等待 */
#define TIMEOUT_BOOT       5000000UL   /* 安全启动最长等待 */
#define TIMEOUT_FW         5000000UL   /* 固件加载最长等待 */
#define TIMEOUT_READY      1000000UL   /* 固件自初始化最长等待 */

/* 启动阶段枚举 */
typedef enum {
    HSM_BOOT_CLK = 0,
    HSM_BOOT_SECURE,
    HSM_BOOT_FWLOAD,
    HSM_BOOT_READY,
    HSM_BOOT_FAIL
} hsm_boot_phase_t;

/* 轮询等待指定状态位置位,返回true表示成功 */
static bool wait_hsm_status(uint32_t mask, uint32_t timeout) {
    uint32_t elapsed = 0;
    while (elapsed < timeout) {
        if ((HSM_STS_REG & mask) == mask) {
            return true;
        }
        elapsed++;
    }
    return false;
}

/* HSM启动验证主函数 */
hsm_boot_phase_t hsm_verify_boot(void) {
    /* 阶段1:检查HSM时钟是否稳定 */
    if (!wait_hsm_status(STS_CLK_RDY, TIMEOUT_CLK)) {
        return HSM_BOOT_CLK;
    }

    /* 阶段2:等待安全启动完成(引导ROM校验固件签名) */
    if (!wait_hsm_status(STS_BOOT_DONE, TIMEOUT_BOOT)) {
        return HSM_BOOT_SECURE;
    }

    /* 阶段3:等待固件从Flash加载至SRAM并开始执行 */
    if (!wait_hsm_status(STS_FW_LOADED, TIMEOUT_FW)) {
        return HSM_BOOT_FWLOAD;
    }

    /* 阶段4:等待固件完成自初始化,进入就绪状态 */
    if (!wait_hsm_status(STS_HSM_READY, TIMEOUT_READY)) {
        return HSM_BOOT_READY;
    }

    return HSM_BOOT_READY;
}

/* 启动HSM(触发安全启动流程) */
void hsm_trigger_boot(void) {
    /* 写1到CTL寄存器的bit0,触发HSM复位释放并开始启动 */
    HSM_CTL_REG |= (1UL << 0);
}

/* 主函数入口 */
int main(void) {
    hsm_boot_phase_t phase;

    /* 触发HSM启动 */
    hsm_trigger_boot();

    /* 执行启动验证 */
    phase = hsm_verify_boot();

    /* 结果判定:仅当返回READY时验证通过 */
    if (phase == HSM_BOOT_READY) {
        /* 验证通过:HSM已完成全部启动流程 */
        return 0;
    } else {
        /* 验证失败:返回失败阶段编号(1~4对应各阶段) */
        return (int)phase + 1;
    }
}

编译与运行

  1. 在CS+或IAR中创建RH850/U2A工程,将上述代码添加至主程序文件。
  2. 将HSM固件镜像(hsm_fw.bin)烧录至HSM专用Flash区域(地址由Renesas安全包说明指定)。
  3. 编译工程,生成可执行文件后通过调试器下载至目标板。
  4. 全速运行程序,观察main函数返回值。

验证方法与判定标准

  • 通过条件:main函数返回0,表示HSM已完成时钟配置、安全启动、固件加载并进入就绪状态。
  • 失败定位:若返回值非0,根据返回值判断失败阶段:
    • 返回1:时钟稳定超时——检查HSM供电、外部晶振或PLL配置
    • 返回2:安全启动超时——检查HSM固件签名是否正确、引导ROM是否被意外禁用
    • 返回3:固件加载超时——检查HSM Flash区域烧录内容、加载地址配置
    • 返回4:固件自初始化超时——检查HSM固件版本与主核通信配置是否匹配
  • 辅助观察:在调试器中添加变量phase的实时监视,可观察启动过程推进到哪个阶段后停滞。

常见问题

  • HSM_STS寄存器始终为0:确认主核与HSM之间的总线访问权限已使能,部分型号需在复位后配置总线主控寄存器。
  • 时钟稳定标志一直不置位:检查HSM独立供电引脚电压是否在规格范围内,以及外部参考时钟是否稳定输出。
  • 固件加载后HSM复位:通常为固件校验失败触发安全机制,需重新生成并烧录签名正确的固件镜像。