2. HSM 固件启动流程分析与调试

任务目标

在RH850 U2A的HSM(硬件安全模块)上实现安全启动流程:启动时对主核Flash中的启动镜像进行完整性校验(HMAC-SHA256)与真实性认证(基于非对称签名的RSA-PSS验证),校验通过后才允许主核跳转执行。本案例聚焦HSM侧固件的核心验证逻辑与主核侧的触发/获取结果流程。

环境与依赖

  • 硬件:RH850/U2A(HSM核与主核共享Flash,HSM拥有独立RAM与加密引擎)
  • 软件:CS+ for CC(或GHS MULTI),HSM固件使用RH850系列编译器
  • 依赖:HSM驱动库(提供HSM_Init、HSM_ReadFlash、HSM_WriteMailbox等底层接口);主核侧需包含HSM通信头文件(hsm_api.h)

实现方案

安全启动分为两级:HSM自启动(HSM核上电后首先执行,完成自身完整性校验)与主镜像认证(HSM校验主核启动镜像)。本案例实现主镜像认证部分:主核在跳转前通过Mailbox向HSM发送启动请求,HSM从Flash读取镜像,依次执行HMAC完整性校验与RSA-PSS签名验证,将结果通过Mailbox返回。密钥(HMAC密钥与RSA公钥)预置于HSM专用安全Flash区域,启动时由HSM内部硬件机制保护,不经过总线暴露。

关键完整代码

/* hsm_secure_boot.c - HSM侧安全启动核心实现 */
#include "hsm_platform.h"
#include "hsm_crypto.h"
#include "hsm_mailbox.h"

#define IMAGE_BASE_ADDR      0x00100000u   /* 主核镜像起始地址 */
#define IMAGE_MAX_SIZE       0x00080000u   /* 镜像最大512KB */
#define HMAC_KEY_SLOT       0x01u          /* HMAC密钥存储槽位 */
#define RSA_PUBKEY_SLOT     0x02u          /* RSA公钥存储槽位 */
#define BOOT_MAGIC          0xA5A5A5A5u

typedef struct {
    uint32_t magic;
    uint32_t image_size;
    uint32_t reserved[2];
} boot_header_t;

static uint8_t work_buffer[1024];

/* HMAC-SHA256完整性校验 */
static int verify_integrity(uint32_t addr, uint32_t size) {
    hmac_ctx_t ctx;
    uint32_t offset = 0;
    uint8_t calc_mac[32];
    uint8_t ref_mac[32];
    
    /* 从安全Flash读取参考HMAC值(镜像末尾附加的32字节) */
    if (hsm_secure_read(HMAC_KEY_SLOT, ref_mac, 32) != HSM_OK) {
        return HSM_ERR_KEY_ACCESS;
    }
    
    hmac_sha256_init(&ctx, HMAC_KEY_SLOT);
    while (offset < size) {
        uint32_t chunk = (size - offset > sizeof(work_buffer)) ? 
                         sizeof(work_buffer) : (size - offset);
        hsm_flash_read(addr + offset, work_buffer, chunk);
        hmac_sha256_update(&ctx, work_buffer, chunk);
        offset += chunk;
    }
    hmac_sha256_final(&ctx, calc_mac);
    
    return (memcmp(calc_mac, ref_mac, 32) == 0) ? HSM_OK : HSM_ERR_INTEGRITY;
}

/* RSA-PSS签名验证(真实性认证) */
static int verify_authenticity(uint32_t addr, uint32_t size) {
    rsa_pss_ctx_t ctx;
    uint8_t hash[32];
    uint8_t signature[256];
    uint32_t sig_offset;
    
    /* 签名位于镜像头部固定偏移处 */
    sig_offset = sizeof(boot_header_t);
    hsm_flash_read(addr + sig_offset, signature, sizeof(signature));
    
    /* 计算镜像内容(不含头部与签名)的SHA-256哈希 */
    sha256_compute(addr + sig_offset + sizeof(signature), 
                   size - sig_offset - sizeof(signature), hash);
    
    rsa_pss_init(&ctx, RSA_PUBKEY_SLOT);
    return rsa_pss_verify(&ctx, hash, sizeof(hash), 
                          signature, sizeof(signature));
}

/* 主入口:接收主核启动请求并执行验证 */
int hsm_secure_boot_process(void) {
    boot_header_t header;
    uint32_t img_addr = IMAGE_BASE_ADDR;
    uint32_t img_size;
    int result;
    
    /* 读取镜像头部 */
    hsm_flash_read(img_addr, (uint8_t*)&header, sizeof(header));
    if (header.magic != BOOT_MAGIC) {
        hsm_mailbox_send_result(HSM_ERR_HEADER);
        return HSM_ERR_HEADER;
    }
    img_size = header.image_size;
    
    if (img_size > IMAGE_MAX_SIZE) {
        hsm_mailbox_send_result(HSM_ERR_SIZE);
        return HSM_ERR_SIZE;
    }
    
    /* 第一步:HMAC完整性校验 */
    result = verify_integrity(img_addr + sizeof(header), 
                              img_size - sizeof(header));
    if (result != HSM_OK) {
        hsm_mailbox_send_result(result);
        return result;
    }
    
    /* 第二步:RSA-PSS签名验证 */
    result = verify_authenticity(img_addr, img_size);
    hsm_mailbox_send_result(result);
    
    return result;
}

主核侧触发代码

/* main_core_boot.c - 主核启动流程中调用HSM验证 */
#include "hsm_api.h"

int main_core_secure_boot(void) {
    uint32_t result;
    
    /* 通过Mailbox发送启动验证请求 */
    hsm_send_command(HSM_CMD_SECURE_BOOT);
    
    /* 等待HSM完成验证(带超时保护) */
    if (hsm_wait_result(&result, 1000) != HSM_OK) {
        return -1;  /* 通信超时 */
    }
    
    if (result == HSM_OK) {
        /* 验证通过,跳转到镜像入口 */
        jump_to_image(IMAGE_BASE_ADDR);
        return 0;
    }
    
    /* 验证失败,进入错误处理 */
    handle_boot_failure(result);
    return -1;
}

运行与验证

  1. 构建HSM固件:将hsm_secure_boot.c编译链接为HSM核可执行文件,烧录至HSM专用Flash。
  2. 构建主核程序:主核程序包含main_core_boot.c,编译后生成带签名与HMAC的镜像(需使用配套的签名工具,将RSA私钥签名与HMAC值附加到镜像指定位置)。
  3. 执行流程:系统上电→HSM核先启动并等待Mailbox命令→主核运行至安全启动点,发送验证请求→HSM执行上述验证→返回结果。

通过判定标准:

  • 使用正确签名的镜像启动时,主核能正常跳转执行(观察LED或串口日志输出“Boot Success”);
  • 篡改镜像任意一个字节(如修改0x100100处的数据)后重新烧录,启动应停在错误处理函数中(日志输出“Boot Failed: 0xNN”);
  • 使用错误密钥签名的镜像,同样应被拒绝启动。

常见问题

  • Mailbox通信超时:检查HSM是否已完成初始化(hsm_platform_init),以及中断优先级配置是否正确。
  • HMAC校验总失败:确认参考HMAC值存储位置与代码中HMAC_KEY_SLOT一致,且计算范围(不含头部)与签名工具生成时使用的范围完全相同。
  • RSA验证失败:确认公钥槽位已正确烧录,且签名算法参数(模长2048位、PSS盐长度)与签名工具一致。