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;
}
}
运行与验证
- 编译HSM固件:将上述代码与平台驱动(TRNG、安全存储)链接编译,生成HSM固件镜像。
- 主机侧调用序列:
- 生成密钥:发送命令
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
- 生成密钥:发送命令
- 通过标准:上述每个步骤的返回值与数据变化均符合预期,且重复执行撤销后导出操作稳定返回
KEY_OP_ERR_SLOT_EMPTY,即判定通过。
关键说明
- 密钥更新采用双槽机制:新密钥先写入更新槽,确认后再切换为活动密钥,避免更新中途断电导致密钥丢失。
- 实际产品中,密钥导出通常受策略限制(如仅允许导出到安全通道),本案例为演示密钥管理流程,直接返回明文密钥用于验证。
- 安全存储接口
hsm_secure_write/read/erase在真实HSM中对应硬件安全存储区访问,需由平台驱动实现。