一、HASH简介
HASH 安全散列算法是HC32F460加密协处理模块的一个功能,该算法是 SHA-2 版本的 SHA-256(Secure Hash Algorithm),符合美国国家标准和技术局发布的国家标准“FIPS PUB 180-3”,可以对长度不超过 2^64 位的消息产生 256 位的消息摘要输出。
安全散列算法的步骤如下:
首先填充消息使其长度恰好为一个比 512 的倍数仅小 64 位的数。填充方法是附一个1在消息后面,后接所要求的多个 0,然后在其后附上 64 位的消息长度(填充前),使消息长度恰好是 512 位的整数倍。
其次将 A、B、C、D、E、F、G、H 8 个 32 位变量,用十六进制初始化。然后开始算法的主循环,一次处理 512 位消息,循环次数是消息中 512 位分组的数目。循环一共进行 64 次操作,此操作称为压缩函数。每次操作都包含移位、循环移位、逻辑运算、模 232 加等,运算的过程见下图 33-2。最后的输出由 A、B、C、D、E、F、G、H 级联而成。其中 Wt 为由 512 位消息得到的第 t 步所用的临时值,Kt 为第t 步所用的常数值,t(0≤t≤63)是 64 步循环中的一步。
二、操作流程上电后,本模块进行一次异步复位操作。时钟需在复位脱离前稳定有效,并且在后续运行中持续稳定。HSAH 模块的操作流程如下:
1) 软件将原始数据按照算法规则进行填充,并且将填充后的消息按512 比特进行分组。
2) 将被操作的数据写入数据寄存器(HASH_DR)中。
3) 如果本次运算为消息分组的第一组数据,对HASH_CR . FST_GRP 位写入1。
4) 对 HASH_CR.START 写入1,启动本模块进行运算。
注:以上的 3)和 4)可以同时进行
5) 判断本模块本次运算是否完成,通过以下方法:
不断读取 HASH_CR.START 直到读到该位为 0 即表示运算完成
6) 如果本次运算不是消息分组的最后一组数据,返回到 2)。
7) 如果本次运算为消息分组的最后一组数据,读取摘要寄存器(HASH_HR)获得本
次运算的结果。如需进行进一步运算则返回到步骤1。
三、测试
测试程序如下:
/*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*/
/******************************************************************************/
/** \file main.c
**
** \brief This sample demonstrates how to set GPIO as output function.
**
** - 2021-04-16 CDT first version for Device Driver Library of GPIO.
**
******************************************************************************/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
#include "ev_hc32f460_lqfp100_v1.h"
#include "TIM_Measure.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
#define HASH_MSG_DIGEST_SIZE (32u)
#define TIMEOUT_VAL (10u)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
float t = 0.0f;
static uint8_t m_au8HashMsgDigest[HASH_MSG_DIGEST_SIZE];
const static char *m_su8SrcData = "abcdefghijklmnopqrstuvwxyz";
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief Main function of GPIO output
**
** \param None
**
** \retval int32_t Return value, if needed
**
******************************************************************************/
int32_t main(void)
{
BSP_CLK_Init();
/* 1. Enable HASH peripheral clock. */
PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_HASH, Enable);
/* 2. Initialize HASH. */
HASH_Init();
DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, BSP_PRINTF_PortInit);
TIM_Measure_Init();
while(1)
{
TIM_Measure_Start();
/* Use HASH. */
HASH_Start((uint8_t *)m_su8SrcData, strlen(m_su8SrcData), \
m_au8HashMsgDigest, TIMEOUT_VAL);
TIM_Measure_Stop();
t = Get_Time();
DDL_Printf("\n");
DDL_Printf("HASH use time: %fus\n",t*1000.0f);
DDL_Printf("String \"%s\" message digest:\n", m_su8SrcData);
for (uint8_t i = 0u; i < sizeof(m_au8HashMsgDigest); i++)
{
DDL_Printf("%.2x ", m_au8HashMsgDigest[i]);
}
while(1);
};
}
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/
编译运行:
和网上的运行结果比较:
可以看出结果正确。
HC32F460_HASH.zip
(701.04 KB)
|