SHA-256(Secure Hash Algorithm 256-bit)是SHA-2哈希函数家族的核心成员,由美国国家标准与技术研究院(NIST)于2001年发布,旨在替代已被破解的SHA-1。SHA-256通过一系列复杂的数学运算,将任意长度的输入数据转换为固定长度的256位哈希值。
备注:团队最近在做演示demo,整理一部分HSM中SHA-256的资料分享,如果错误欢迎大家批评指正。support@softor.com.cn
英飞凌TC3xx系列单片机集成了高性能的硬件安全模块(HSM),专为安全关键应用设计:
HSM通过专用的HASH硬件模块实现SHA-256加速,主要优势:
TC3xx HSM的哈希模块由以下部分组成:
void HASH_SHA256(unsigned int num_blocks)
{
int i;
unsigned int block_num = 0;
unsigned int *psrc, *pdst;
// 配置哈希算法为SHA-256
HSM_HASH->HASH_CFG = ((HASH_ALGO_SHA_256 << HASH_CFG_ALGO_Pos) |
(HASH_ORDER_OUT_MSW_FIRST << HASH_CFG_ORDER_OUT_Pos));
// 初始化定时器,用于性能测量
HSM_TIM->TIM_CFG = 0x0008; // 禁用预分频器
HSM_TIM->TIM_CTRL = 0x0001; // 开启定时器1
// 记录开始时间
Start = HSM_TIM->TIM_CNT0;
STStart = STM0_COUNT;
// 处理数据块
while (num_blocks)
{
// 写入64字节数据到HASH_DATA寄存器
for (i = 0; i < 16; i++)
{
HSM_HASH->HASH_DATA = pHOST2HSMbuf[(block_num * 16) + i];
}
if (--num_blocks > 0)
{
// 等待数据FIFO非满,确保可以继续写入数据
while ((HSM_HASH->HASH_STAT & HASH_STAT_DF_NF_Msk) != HASHSTAT_FIFO_NOT_FULL)
;
}
block_num += 1;
}
// 等待哈希计算完成
while ((HSM_HASH->HASH_STAT & HASH_STAT_BSY_Msk) == HASHSTAT_BSY)
;
// 读取哈希结果
i = 0;
while ((HSM_HASH->HASH_STAT & HASH_STAT_CNT_Msk) != 0x0)
{
pHSM2HOSTbuf[i++] = HSM_HASH->HASH_VAL;
}
// 记录结束时间,用于性能分析
if(overflow > 0)
Finish = HSM_TIM->TIM_CNT0 + 0xFFFF;
else
Finish = HSM_TIM->TIM_CNT0;
STFinish = STM0_COUNT;
Total = Finish - Start;
STTotal = STFinish - STStart;
}
void hsm_hash_sha256_Test(unsigned int num_blocks)
{
uint32 i;
// 初始化标志,用于等待HSM处理完成
HashProcessEnd = FALSE;
// 清空缓冲区,准备数据
for (i = 0; i < (16 * num_blocks); i += 1)
{
HOST2HSMbuf[i] = 0;
HSM2HOSTbuf[i] = 0;
}
// 准备测试数据
if (num_blocks == HASH_ONE_BLOCK)
{
// 单个数据块(512位)
HOST2HSMbuf[0] = 0x61626380; // "abc" + 0x80填充
HOST2HSMbuf[15] = 0x18; // 24位长度
}
else if (num_blocks == HASH_TWO_BLOCKS)
{
// 两个数据块(1024位)
HOST2HSMbuf[0] = 0x61626300; // "abc0"
HOST2HSMbuf[16] = 0x01020304; // "1234"
HOST2HSMbuf[17] = 0x05060708; // "5678"
HOST2HSMbuf[18] = 0x09800000; // "9" + 0x80填充
HOST2HSMbuf[31] = 0x248; // 584位长度
}
// 设置数据块数并触发HSM中断
HSM_HT2HSMS.U = num_blocks; // 要哈希的512位数据块数
HSM_HT2HSMF.U = (1 << CMD_HASH_SHA_256); // 向HSM发出中断
// 等待处理完成
while (!HashProcessEnd)
;
// 验证响应状态
if (HSM_HSM2HTS.U != (0xCCCC0000 | CMD_HASH_SHA_256))
__debug(); // 响应不正确或超时
// 验证结果
for (i = 0; i < 8; i += 1)
{
if (HSM2HOSTbuf[i] != SHA256_Val[num_blocks - 1][i])
{
DBG_Store_Trace(str_dbg("HASH"), str_dbg("-SHA"), str_dbg("-256"),
str_dbg("FAIL"), i, HSM2HOSTbuf[i], 0xE003);
__debug();
}
}
}
注意:上述代码中的寄存器命名(如HSM_HASH->HASH_CFG、HSM_TIM等)为示例逻辑,实际使用时需根据芯片手册替换为正确的寄存器地址和位定义。TC3xx系列的HSM哈希模块实际名称可能为HASH或HASH_ACC,具体寄存器定义请参考英飞凌官方文档。
// 使能HSM时钟
Ccu60_CLC.B.DISR = 0; // 清除HSM时钟禁用位
while (Ccu60_CLC.B.DISS != 0); // 等待时钟使能完成
// 释放HSM复位
HSM_RSTSTAT.B.RST = 1; // 触发HSM复位
while (HSM_RSTSTAT.B.RST != 0); // 等待复位完成
// 加载HSM固件到HSM代码RAM
memcpy((void*)HSM_CODE_RAM_BASE, hsm_firmware, hsm_firmware_size);
// 启动HSM
HSM_CTL.B.START = 1; // 启动HSM执行
// 设置共享内存基地址
HSM_SAHBASE.B.ADDRESS = (uint32_t)HOST2HSMbuf >> 16;
// 配置HSM到主机的中断
HSM_IGCR0.B.IRQEN = 1; // 使能HSM中断
// 配置中断路由器
SRC_HSM.B.SRE = 1; // 使能服务请求
SRC_HSM.B.TOS = 3; // 设置服务优先级
SRC_HSM.B.SRR = 1; // 清除服务请求
HOST2HSMbuf(TriCore到HSM)和HSM2HOSTbuf(HSM到TriCore)作为数据交换桥梁,每个缓冲区大小为0x100个32位字HSM_HT2HSMF(主机到HSM标志)和HSM_HSM2HTF(HSM到主机标志)寄存器触发中断HSM_HSM2HTS(HSM到主机状态)寄存器传递操作状态和结果SAHBASE寄存器映射主机内存,实现直接访问HOST2HSMbuf中准备待哈希的数据,包括数据填充和长度信息HSM_HT2HSMS(主机到HSM状态)设置数据块数等参数HSM_HT2HSMF触发HSM中断,通知HSM开始处理HSM2HOSTbufHSM_HSM2HTS并触发TriCore中断,通知TriCore处理完成hostread32_uncached和hostwrite32_uncached函数,避免缓存一致性问题// 配置DMA通道用于HSM数据传输
IfxDma_Dma_Config dmaConfig;
IfxDma_Dma_initModuleConfig(&dmaConfig, &MODULE_DMA);
IfxDma_Dma_initModule(&g_dma, &dmaConfig);
// 配置DMA通道
IfxDma_ChannelConfig channelConfig;
IfxDma_Channel_initConfig(&channelConfig, &g_dma);
channelConfig.channelId = IfxDma_ChannelId_0;
channelConfig.transferCount = 16; // 每次传输16个32位字(64字节)
channelConfig.sourceAddress = (uint32)&HOST2HSMbuf[0];
channelConfig.destinationAddress = (uint32)&HSM_HASH->HASH_DATA;
channelConfig.transferMode = IfxDma_ChannelTransferMode_continuous;
channelConfig.requestSource = IfxDma_ChannelRequestSource_software;
IfxDma_Channel_init(&g_dmaChannel, &channelConfig);
// 启动DMA传输
IfxDma_Channel_start(&g_dmaChannel);
// 等待DMA传输完成
while (IfxDma_Channel_getStatus(&g_dmaChannel) == IfxDma_ChannelStatus_busy);
HOST2HSMbuf和HSM2HOSTbuf缓冲区,确保内存分配正确// 注意:SHA-256标准使用大端字节序,需要确保数据正确处理
// 方法1:通过HASH_CFG配置字节序
HSM_HASH->HASH_CFG |= (HASH_ORDER_IN_MSW_FIRST << HASH_CFG_ORDER_IN_Pos);
// 方法2:手动转换字节序
uint32_t swap_endian(uint32_t value) {
return ((value >> 24) & 0x000000FF) |
((value >> 8) & 0x0000FF00) |
((value << 8) & 0x00FF0000) |
((value << 24) & 0xFF000000);
}
// 正确的SHA-256数据填充
void sha256_pad(uint8_t *data, uint32_t length, uint32_t *padded_data, uint32_t *num_blocks) {
uint32_t i, pad_length;
uint64_t bit_length = (uint64_t)length * 8;
// 计算需要的数据块数
*num_blocks = (length + 9 + 63) / 64; // 1字节0x80 + 8字节长度 + 填充
// 清空填充数据
memset(padded_data, 0, (*num_blocks) * 16 * 4);
// 复制原始数据
memcpy(padded_data, data, length);
// 添加0x80
padded_data[length / 4] |= 0x80 << ((length % 4) * 8);
// 添加长度(大端)
uint32_t last_word = (*num_blocks * 16) - 1;
padded_data[last_word] = (uint32_t)(bit_length & 0xFFFFFFFF);
padded_data[last_word - 1] = (uint32_t)(bit_length >> 32);
}
HSM_HT2HSMS设置数据块数HSM_HT2HSMF触发SHA-256计算HSM2HOSTbuf读取哈希结果,共8个32位字(256位)HSM_HSM2HTS状态,确保操作成功完成// TC3xx SHA-256使用示例
void tc3xx_sha256_example(const uint8_t *data, uint32_t length, uint32_t *hash_result)
{
uint32_t i, num_blocks;
uint32_t padded_data[64]; // 最大支持512字节数据
// 填充数据
sha256_pad(data, length, padded_data, &num_blocks);
// 清空缓冲区
for (i = 0; i < (16 * num_blocks); i++) {
HOST2HSMbuf[i] = 0;
HSM2HOSTbuf[i] = 0;
}
// 复制填充后的数据到共享缓冲区
for (i = 0; i < (16 * num_blocks); i++) {
HOST2HSMbuf[i] = padded_data[i];
}
// 执行哈希计算
HashProcessEnd = FALSE;
HSM_HT2HSMS.U = num_blocks;
HSM_HT2HSMF.U = (1 << CMD_HASH_SHA_256);
// 等待完成(带超时检测)
uint32_t start_time = get_system_time_ms();
while (!HashProcessEnd) {
if (get_system_time_ms() - start_time > 100) { // 100ms超时
// 处理超时错误
for (i = 0; i < 8; i++) {
hash_result[i] = 0;
}
return;
}
}
// 验证结果
if (HSM_HSM2HTS.U == (0xCCCC0000 | CMD_HASH_SHA_256)) {
// 复制结果到输出缓冲区
for (i = 0; i < 8; i++) {
hash_result[i] = HSM2HOSTbuf[i];
}
} else {
// 处理错误,返回全0
for (i = 0; i < 8; i++) {
hash_result[i] = 0;
}
}
}
// 使用示例
void example_usage(void)
{
uint8_t test_data[] = "Hello, TC3xx SHA-256!";
uint32_t hash_result[8];
uint32_t i;
// 计算SHA-256哈希
tc3xx_sha256_example(test_data, sizeof(test_data) - 1, hash_result);
// 打印结果
printf("SHA-256 hash:
");
for (i = 0; i < 8; i++) {
printf("%08X ", hash_result[i]);
}
printf("
");
}
hostread32_uncached和hostwrite32_uncached函数根据英飞凌官方文档和实测数据,SHA-256的执行时间取决于数据块数量:
// 优化后的SHA-256批量处理函数
void tc3xx_sha256_batch(const uint8_t *data, uint32_t length, uint32_t *hash_result)
{
uint32_t i, num_blocks, processed_blocks = 0;
const uint8_t *current_data = data;
uint32_t remaining_length = length;
// 批量处理,每次最多处理4块数据
while (remaining_length > 0) {
// 计算本次处理的数据块数
num_blocks = (remaining_length + 63) / 64;
if (num_blocks > 4) num_blocks = 4; // 限制每次处理的块数
// 准备数据
uint32_t padded_data[64];
sha256_pad(current_data, remaining_length > 4*64 ? 4*64 : remaining_length, padded_data, &num_blocks);
// 复制到共享缓冲区
for (i = 0; i < (16 * num_blocks); i++) {
HOST2HSMbuf[i] = padded_data[i];
}
// 执行哈希计算
HashProcessEnd = FALSE;
HSM_HT2HSMS.U = num_blocks;
HSM_HT2HSMF.U = (1 << CMD_HASH_SHA_256);
// 等待完成
while (!HashProcessEnd);
// 处理结果
if (processed_blocks == 0) {
// 第一次处理,保存结果
for (i = 0; i < 8; i++) {
hash_result[i] = HSM2HOSTbuf[i];
}
} else {
// 后续处理,需要合并哈希结果(复杂,实际应用中建议使用HSM的多部分哈希功能)
}
// 更新指针和长度
current_data += num_blocks * 64;
remaining_length -= num_blocks * 64;
processed_blocks += num_blocks;
}
}
// 预计算的哈希值
static const unsigned int SHA256_Val [2][8] = {
{0xBA7816BF, 0x8F01CFEA, 0x414140DE, 0x5DAE2223, 0xB00361A3, 0x96177A9C, 0xB410FF61, 0xF20015AD}, // "abc"
{0xf198213f, 0x738513eb, 0xfaab6a49, 0xf2915f47, 0xc8791536, 0xd01e0f42, 0xbfe654c0, 0x927ed6be} // 测试数据
};
// 验证结果
for (i = 0; i < 8; i += 1)
{
if (HSM2HOSTbuf[i] != SHA256_Val[num_blocks - 1][i])
{
// 验证失败,处理错误
error_handler(ERROR_HASH_MISMATCH);
}
}
// 验证HSM响应状态
if (HSM_HSM2HTS.U != (0xCCCC0000 | CMD_HASH_SHA_256))
{
// 响应不正确或超时,处理错误
error_handler(ERROR_HSM_RESPONSE);
}
// 错误处理函数
void error_handler(uint32_t error_code)
{
switch (error_code)
{
case ERROR_HASH_MISMATCH:
printf("Error: Hash mismatch
");
// 处理哈希不匹配错误
break;
case ERROR_HSM_RESPONSE:
printf("Error: HSM response error
");
// 处理HSM响应错误
break;
case ERROR_TIMEOUT:
printf("Error: HSM timeout
");
// 处理超时错误
break;
default:
printf("Error: Unknown error
");
break;
}
// 记录错误日志
log_error(error_code);
// 可能的恢复措施
hsm_reset();
}
// 带超时检测的SHA-256计算
int tc3xx_sha256_with_timeout(const uint8_t *data, uint32_t length, uint32_t *hash_result, uint32_t timeout_ms)
{
uint32_t start_time = get_system_time_ms();
// 执行哈希计算
tc3xx_sha256_example(data, length, hash_result);
// 检查超时
if (get_system_time_ms() - start_time > timeout_ms)
{
error_handler(ERROR_TIMEOUT);
return ERROR_TIMEOUT;
}
return SUCCESS;
}
// 记录调试信息
DBG_Store_Trace(str_dbg("HASH"), str_dbg("-SHA"), str_dbg("-256"),
0x0, str_dbg("Strt"), num_blocks, 0x0);
// 记录结果
DBG_Store_Trace(str_dbg("HASH"), str_dbg("-SHA"), str_dbg("-256"),
0x0, str_dbg("Done"), num_blocks, 0x0);
if (error_condition)
__debug(); // 触发调试器断点
HOST2HSMbuf和HSM2HOSTbuf的内容,验证数据传输正确性HOST2HSMbuf中的数据正确,包括填充和长度信息HSM_HSM2HTS状态,确保HSM正常响应|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 安全启动验证
int secure_boot_verify(void)
{
uint32_t firmware_hash[8];
uint32_t stored_hash[8];
// 计算固件哈希
tc3xx_sha256_example(firmware_start, firmware_size, firmware_hash);
// 从安全存储读取存储的哈希
read_secure_hash(stored_hash);
// 比较哈希值
for (int i = 0; i < 8; i++) {
if (firmware_hash[i] != stored_hash[i]) {
return SECURE_BOOT_ERROR;
}
}
return SECURE_BOOT_SUCCESS;
}
// 消息认证
int authenticate_message(const uint8_t *message, uint32_t length, const uint32_t *expected_hash)
{
uint32_t calculated_hash[8];
// 计算消息哈希
tc3xx_sha256_example(message, length, calculated_hash);
// 验证哈希
for (int i = 0; i < 8; i++) {
if (calculated_hash[i] != expected_hash[i]) {
return AUTHENTICATION_FAILED;
}
}
return AUTHENTICATION_SUCCESS;
}
// OTA升级包验证
int verify_ota_package(const uint8_t *package_data, uint32_t package_size, const uint32_t *server_hash)
{
uint32_t calculated_hash[8];
// 计算升级包哈希
tc3xx_sha256_example(package_data, package_size, calculated_hash);
// 验证哈希
for (int i = 0; i < 8; i++) {
if (calculated_hash[i] != server_hash[i]) {
return OTA_PACKAGE_CORRUPTED;
}
}
return OTA_PACKAGE_VALID;
}
// 文件完整性验证
int verify_file_integrity(const uint8_t *file_data, uint32_t file_size, const uint32_t *stored_hash)
{
uint32_t calculated_hash[8];
// 计算文件哈希
tc3xx_sha256_example(file_data, file_size, calculated_hash);
// 验证哈希
for (int i = 0; i < 8; i++) {
if (calculated_hash[i] != stored_hash[i]) {
return FILE_CORRUPTED;
}
}
return FILE_INTACT;
}
// 安全的密钥派生(使用HKDF)
void derive_key_hkdf(const uint8_t *master_key, uint32_t key_length,
const uint8_t *salt, uint32_t salt_length,
const uint8_t *info, uint32_t info_length,
uint8_t *derived_key, uint32_t derived_key_length)
{
// 实现HKDF算法,使用SHA-256作为哈希函数
// 此处省略具体实现,实际应用中应使用标准HKDF实现
}
// 密钥安全存储
int store_key_securely(const uint8_t *key, uint32_t key_length, uint32_t *stored_hash)
{
// 计算密钥哈希
tc3xx_sha256_example(key, key_length, stored_hash);
// 存储哈希值到安全区域
if (write_secure_storage(stored_hash, sizeof(uint32_t) * 8) != SUCCESS) {
return KEY_STORAGE_ERROR;
}
// 安全擦除密钥
memset_s(key, key_length, 0, key_length);
return KEY_STORAGE_SUCCESS;
}
HOST2HSMbuf和HSM2HOSTbuf时需要互斥// 使用互斥锁保护HSM访问
IfxMutex mutex;
// 初始化互斥锁
IfxMutex_init(&mutex);
// 访问HSM前获取锁
IfxMutex_lock(&mutex, IfxMutex_Timeout_infinite);
// 执行HSM操作
tc3xx_sha256_example(data, length, hash_result);
// 释放锁
IfxMutex_unlock(&mutex);
// 配置HSM中断优先级
SRC_HSM.B.TOS = 3; // 设置为中等优先级
// 批量处理多个哈希请求
void batch_process_hashes(uint8_t **data_array, uint32_t *length_array, uint32_t count, uint32_t **hash_results)
{
for (uint32_t i = 0; i < count; i++) {
tc3xx_sha256_example(data_array[i], length_array[i], hash_results[i]);
}
}
|
|
|
|
|
|
|
|
|
|
|---|---|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HSM_SHA256_Demo/
├── 0_Src/
│ ├── AppSw/
│ │ ├── Tricore/
│ │ │ ├── MAIN_HSM.c # 主应用
│ │ │ ├── HSM_Test_def.h # 测试定义
│ │ │ └── HsmDemo/
│ │ │ ├── IfxHsm_HASH.c # SHA-256测试
│ │ │ └── IfxHsm_TestsCommon.c # 公共测试代码
│ │ └── ArmCortexM3/
│ │ └── code_hsm.c # HSM端代码
│ └── BaseSw/
│ ├── iLLD/ # Infineon Low Level Drivers
│ └── Service/ # 基础服务
├── 1_Config/
│ ├── Config_Tricore_Tasking/ # Tasking编译配置
│ └── Config_Arm_Tasking/ # ARM编译配置
├── 2_Out/
│ ├── Tricore_Tasking/ # TriCore编译输出
│ └── Arm_Tasking/ # ARM编译输出
├── Makefile # 主Makefile
└── README.md # 项目说明
# Tasking编译器配置
# 目标处理器
TARGET = tc39xa
# 包含路径
INCLUDES = -I0_Src/AppSw/Tricore \
-I0_Src/AppSw/CpuGeneric/Config \
-I0_Src/BaseSw/Service/CpuGeneric/SysSe/Bsp \
-I0_Src/BaseSw/iLLD/TC39A/Tricore \
-I0_Src/BaseSw/iLLD/TC39A/Tricore/Cpu/Std
# 编译选项
CFLAGS = -mtc39xa -O2 -g
# 链接选项
LDFLAGS = -liltd_tc39a -Tlinker.lsl
SHA-256是一种广泛应用的密码哈希算法,在英飞凌TC3xx单片机的HSM上通过硬件加速实现,可以提供高效、安全的哈希计算能力。通过本文档的介绍,您应该已经了解:
这些知识将帮助您在英飞凌TC3xx单片机项目中有效使用SHA-256功能,确保数据的安全性和完整性。通过合理的代码设计和优化,您可以充分发挥TC3xx HSM的性能优势,实现高效、安全的哈希计算应用。
support@softor.com.cn
tianpengbo@softor.com.cn
‘,
create_time: ‘2026-04-07 06:22’,
cdn_url: ‘https://mmbiz.qpic.cn/mmbiz_jpg/M9XQklgjm1eWKRHn7jicy8B1NkpzRtcMekROxjHk8Cy1ZZwu1xW0tqcjicJWwiaR3D5Y3YBCJ8Ofdov2TT6Bgh7KuTx79vRibHHZ6sy15Xl0mqA/0?wx_fmt=jpeg’,
link: ‘https://mp.weixin.qq.com/s/kuPWHvKk9qYbh6_YDPCQDQ’,
source_url: ”,
can_share: ‘0’ * 1,
alias: ”,
type: ‘9’ * 1,
author: ‘tianpb
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn
作者:tianpengbo / 田朋博。大家如果在项目中遇到相关技术问题,欢迎联系我交流。
support@softor.com.cn
tianpengbo@softor.com.cn