3. 密钥管理基础

密钥管理基础 学习卡片

任务目标

在RH850 U2A的HSM(硬件安全模块)中实现对称密钥的完整生命周期管理:生成密钥、安全存储、导出验证,以及密钥的更新与撤销操作。本案例聚焦于HSM固件侧的关键逻辑,通过HSM内部API完成密钥管理操作,并提供主机侧调用接口示例。

环境与依赖

  • 硬件:RH850/U2A(HSM核运行HSM固件)
  • 软件:HSM固件开发环境(基于C语言),主机侧驱动库(CSHE或类似接口)
  • 依赖:HSM密码库(提供AES、TRNG等原语),密钥槽管理驱动

核心实现

以下代码实现HSM内部的密钥管理逻辑,包括密钥生成(写入密钥槽)、导出(读取验证)、更新(覆盖写入)和撤销(清除密钥槽)。密钥槽0为当前活动密钥,槽1为更新用临时密钥。

/* hsm_key_management.h */
#ifndef HSM_KEY_MGMT_H
#define HSM_KEY_MGMT_H

#include <stdint.h>
#include <stddef.h>

#define KEY_SLOT_ACTIVE    0u
#define KEY_SLOT_UPDATE    1u
#define KEY_SLOT_COUNT     2u
#define AES_KEY_SIZE       16u   /* AES-128 */

typedef enum {
    KEY_OP_OK = 0,
    KEY_OP_ERR_PARAM,
    KEY_OP_ERR_SLOT_EMPTY,
    KEY_OP_ERR_SLOT_FULL,
    KEY_OP_ERR_UPDATE_PENDING
} key_op_result_t;

/* HSM内部API */
key_op_result_t hsm_key_generate(uint8_t slot);
key_op_result_t hsm_key_export(uint8_t slot, uint8_t *out, size_t *len);
key_op_result_t hsm_key_update(void);
key_op_result_t hsm_key_revoke(uint8_t slot);

#endif /* HSM_KEY_MGMT_H */

/* hsm_key_management.c */
#include "hsm_key_management.h"
#include <string.h>

/* 模拟密钥槽存储(实际为HSM安全存储区) */
static uint8_t key_storage[KEY_SLOT_COUNT][AES_KEY_SIZE];
static uint8_t slot_valid[KEY_SLOT_COUNT] = {0u, 0u};
static uint8_t update_pending = 0u;

/* 硬件TRNG接口(由平台提供) */
extern void hsm_trng_get_bytes(uint8_t *buf, size_t len);

/* 安全存储读写接口(由平台提供) */
extern void hsm_secure_write(uint8_t slot, const uint8_t *data);
extern void hsm_secure_read(uint8_t slot, uint8_t *data);
extern void hsm_secure_erase(uint8_t slot);

static key_op_result_t validate_slot(uint8_t slot) {
    if (slot >= KEY_SLOT_COUNT) return KEY_OP_ERR_PARAM;
    return KEY_OP_OK;
}

key_op_result_t hsm_key_generate(uint8_t slot) {
    key_op_result_t rc = validate_slot(slot);
    if (rc != KEY_OP_OK) return rc;
    if (slot_valid[slot]) return KEY_OP_ERR_SLOT_FULL;

    uint8_t new_key[AES_KEY_SIZE];
    hsm_trng_get_bytes(new_key, AES_KEY_SIZE);

    hsm_secure_write(slot, new_key);
    memcpy(key_storage[slot], new_key, AES_KEY_SIZE);
    slot_valid[slot] = 1u;
    return KEY_OP_OK;
}

key_op_result_t hsm_key_export(uint8_t slot, uint8_t *out, size_t *len) {
    key_op_result_t rc = validate_slot(slot);
    if (rc != KEY_OP_OK) return rc;
    if (!slot_valid[slot]) return KEY_OP_ERR_SLOT_EMPTY;
    if (out == NULL || len == NULL || *len < AES_KEY_SIZE) {
        return KEY_OP_ERR_PARAM;
    }

    hsm_secure_read(slot, key_storage[slot]);
    memcpy(out, key_storage[slot], AES_KEY_SIZE);
    *len = AES_KEY_SIZE;
    return KEY_OP_OK;
}

key_op_result_t hsm_key_update(void) {
    /* 将更新槽密钥提升为活动密钥 */
    if (!slot_valid[KEY_SLOT_UPDATE]) return KEY_OP_ERR_SLOT_EMPTY;
    if (!slot_valid[KEY_SLOT_ACTIVE]) return KEY_OP_ERR_SLOT_EMPTY;

    /* 实际场景:此处应使用旧密钥解密更新数据块,此处简化为直接切换 */
    hsm_secure_erase(KEY_SLOT_ACTIVE);
    hsm_secure_write(KEY_SLOT_ACTIVE, key_storage[KEY_SLOT_UPDATE]);

    memcpy(key_storage[KEY_SLOT_ACTIVE], key_storage[KEY_SLOT_UPDATE], AES_KEY_SIZE);
    slot_valid[KEY_SLOT_ACTIVE] = 1u;

    /* 清除更新槽 */
    hsm_secure_erase(KEY_SLOT_UPDATE);
    memset(key_storage[KEY_SLOT_UPDATE], 0, AES_KEY_SIZE);
    slot_valid[KEY_SLOT_UPDATE] = 0u;
    update_pending = 0u;
    return KEY_OP_OK;
}

key_op_result_t hsm_key_revoke(uint8_t slot) {
    key_op_result_t rc = validate_slot(slot);
    if (rc != KEY_OP_OK) return rc;
    if (!slot_valid[slot]) return KEY_OP_ERR_SLOT_EMPTY;

    hsm_secure_erase(slot);
    memset(key_storage[slot], 0, AES_KEY_SIZE);
    slot_valid[slot] = 0u;
    return KEY_OP_OK;
}

/* 主机侧调用示例(通过HSM命令接口) */
/* 以下为命令分发函数,实际通过CSHE消息触发 */
key_op_result_t hsm_cmd_dispatch(uint8_t cmd, uint8_t slot,
                                 uint8_t *buf, size_t *len) {
    switch (cmd) {
        case 0x01: return hsm_key_generate(slot);
        case 0x02: return hsm_key_export(slot, buf, len);
        case 0x03: return hsm_key_update();
        case 0x04: return hsm_key_revoke(slot);
        default:   return KEY_OP_ERR_PARAM;
    }
}

运行与验证

  1. 编译HSM固件:将上述代码与平台驱动(TRNG、安全存储)链接编译,生成HSM固件镜像。
  2. 主机侧调用序列:
    • 生成密钥:发送命令0x01,槽位0 → 预期返回KEY_OP_OK
    • 导出验证:发送命令0x02,槽位0,缓冲区≥16字节 → 返回KEY_OP_OK且len=16,数据非全零
    • 更新密钥:先向槽1发送0x01生成新密钥,再发送0x03 → 返回KEY_OP_OK;再次导出槽0,数据与更新前不同
    • 撤销密钥:发送0x04,槽位0 → 返回KEY_OP_OK;再次导出槽0 → 返回KEY_OP_ERR_SLOT_EMPTY
  3. 通过标准:上述每个步骤的返回值与数据变化均符合预期,且重复执行撤销后导出操作稳定返回KEY_OP_ERR_SLOT_EMPTY,即判定通过。

关键说明

  • 密钥更新采用双槽机制:新密钥先写入更新槽,确认后再切换为活动密钥,避免更新中途断电导致密钥丢失。
  • 实际产品中,密钥导出通常受策略限制(如仅允许导出到安全通道),本案例为演示密钥管理流程,直接返回明文密钥用于验证。
  • 安全存储接口hsm_secure_write/read/erase在真实HSM中对应硬件安全存储区访问,需由平台驱动实现。