打印
[STM32U5]

【NUCLEO-U575ZI-Q测评】+第一篇_硬件Hash使用

[复制链接]
2100|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 zhanzr21 于 2023-3-5 14:42 编辑

#申请原创#
很幸运又拿到了STM32的板子,周末用了下,发几篇贴子分享下.
首先还是不免俗地上几张图,虽说STM32的Nucleo144板子的图各位坛友早就有点"审美疲劳了", 不过拿到板子后我还是忍不住拍两张.



板子的主控是STM32U575ZIT6QU, 是主打低功耗应用的新的系列. 这个系列功能非常强大,同时兼顾低功耗和安全.
Cortex M33自带的Trust Zone, 其余常规外设也非常丰富.

除了以太网接口和无线接口之外,暂时想不到还缺少什么外设. Flash和SRAM更是高达2MB和784KB. 对于大多数的嵌入式应用来说,外设存储都不是问题了.
当然硬件这些都是基础, 本人对STM系列的产品感觉最靠谱的是开发生态. 以STM32CubeMX为代表的开发工具,让应用设计者开发起来非常便捷.
本篇分享一个使用片上硬件Hash加速单元的例子.

应用设计中,尤其是通信/安全相关的设计中,  计算Hash/HMAC的场景很多, 比如校验下载数据的完整性,正确性. 但是Hash/HMAC计算很吃CPU资源.  尤其是需要频繁计算的场景下, CPU资源的很大一部分都给这种计算占去了. 所以即使是非嵌入式的CPU, 近年来也纷纷把这种计算进行硬件加速. 原因无他, 即CPU做这种计算不是很合算, CPU适合处理变化复杂的运算, Hash/Hmac这种运算变化不大,但需要很多指令周期去完成.

参考:Intel的Hash扩展,
https://edc.intel.com/content/ww ... e%20a%20family%20of,processing%20SHA-1%20and%20SHA-256%20on%20Intel%20architecture-based%20processors.

说到Hash的硬件加速, 大家也可以想象 "+密 货B Wa 矿",那是典型的使用ASIC或者GPU对Hash进行加速的场景.
所以STM32的一些系列就带有这种硬件Hash加速单元, 将这种不适合软件运算的工作从CPU那里解放出来.而且这个硬件单元使用起来也非常简单, 还支持DMA.
首先创建一个STM32CubeMX的工程, 选择不需要TrustZone, 关于TrustZone的使用, 以后会另外发贴分享. 当不使用TrustZone时, Cortex M33和Cortex M7基本特性一致.

选择激活Hash加速单元

这个单元激活即可, 底下配置框内的设置都可以用通过代码在运行时修改的,现在不用太在意.
可以看到这个硬件加速单元支持这几种硬件加速运算:
SHA1
MD5
SHA224
SHA256
HMAC-SHA1
HMAC-MD5
HMAC-SHA224
HMAC-SHA256

值得注意的是, SHA1,MD5以及它们对应的HMAC算法现在已经被认为是不安全的了, 即攻击它们的成本现在并不高. 包含在这里, 可能还是为了兼容之前的数据和应用吧. 毕竟一下子淘汰SHA1,MD5还不现实. 如果大家设计新的应用,建议不要选择MD5,SHA1算法.反正都是通过硬件加速, MD5,SHA1运算的优势也没那么明显.
其余就都选默认即可, 生成代码框架.
主函数里分别对以上算法进行测试,即给一个输入,把计算结果打印出来.
printf("Core Freq:%u Hz\n", SystemCoreClock);
  /****************************************************************************/
  /*************************** HMAC-SHA1 **************************************/
  /****************************************************************************/
  if (HAL_HMAC_SHA1_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                          aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("HMAC-SHA1 test passed.\n");
  print_hex(aHashDigest, 20);

  /****************************************************************************/
  /*************************** HMAC-MD5 ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HMAC_MD5_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE, aHashDigest,
                         0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("HMAC-MD5 test passed.\n");
  print_hex(aHashDigest, 16);
  /****************************************************************************/
  /*************************** HMAC-SHA224
   * ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HMACEx_SHA224_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                              aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("HMAC-SHA224 test passed.\n");
  print_hex(aHashDigest, 28);

  /****************************************************************************/
  /*************************** HMAC-SHA256
   * ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HMACEx_SHA256_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                              aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("HMAC-SHA256 test passed.\n");
  print_hex(aHashDigest, 32);

  /****************************************************************************/
  /*************************** Hash-SHA1
   * ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HASH_SHA1_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                          aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("Hash-SHA1 test passed.\n");
  print_hex(aHashDigest, 20);

  /****************************************************************************/
  /*************************** Hash-MD5 ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HASH_MD5_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE, aHashDigest,
                         0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("Hash-MD5 test passed.\n");
  print_hex(aHashDigest, 16);
  /****************************************************************************/
  /*************************** Hash-SHA224
   * ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HASHEx_SHA224_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                              aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("Hash-SHA224 test passed.\n");
  print_hex(aHashDigest, 28);

  /****************************************************************************/
  /*************************** Hash-SHA256
   * ***************************************/
  /****************************************************************************/
  if (HAL_HASH_DeInit(&hhash) != HAL_OK) {
    Error_Handler();
  }
  MX_HASH_Init();

  if (HAL_HASHEx_SHA256_Start(&hhash, (uint8_t *)aInput, INPUT_TAB_SIZE,
                              aHashDigest, 0xFF) != HAL_OK) {
    Error_Handler();
  }
  printf("Hash-SHA256 test passed.\n");
  print_hex(aHashDigest, 32);

  printf("%u %u\n", SystemCoreClock, HAL_GetTick());
其中打印Hex数据函数和测试数据:
#define INPUT_TAB_SIZE    ((uint32_t) 261)/* The size of the input data "aInput" */
__ALIGN_BEGIN static const uint8_t pKeyHASH[261] __ALIGN_END = {
                            0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,0x20,0x70,
                            0x72,0x6f,0x63,0x65,0x73,0x73,0x6f,0x72,0x20,0x69,
                            0x73,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x79,0x20,
                            0x63,0x6f,0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
                            0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,
                            0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,
                            0x65,0x20,0x73,0x65,0x63,0x75,0x72,0x65,0x20,0x68,
                            0x61,0x73,0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
                            0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,0x2d,0x31,
                            0x29,0x2c,0x20,0x74,0x68,0x65,0x20,0x4d,0x44,0x35,
                            0x20,0x28,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x2d,
                            0x64,0x69,0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
                            0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,0x29,0x20,
                            0x68,0x61,0x73,0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,
                            0x69,0x74,0x68,0x6d,0x20,0x61,0x6e,0x64,0x20,0x74,
                            0x68,0x65,0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
                            0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,0x68,0x20,
                            0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x20,0x61,0x75,
                            0x74,0x68,0x65,0x6e,0x74,0x69,0x63,0x61,0x74,0x69,
                            0x6f,0x6e,0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
                            0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x73,
                            0x75,0x69,0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,
                            0x72,0x20,0x61,0x20,0x76,0x61,0x72,0x69,0x65,0x74,
                            0x79,0x20,0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
                            0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,0x2a,0x2a,
                            0x2a,0x20,0x53,0x54,0x4d,0x33,0x32,0x20,0x2a,0x2a,
                            0x2a};
__ALIGN_BEGIN const uint8_t aInput[INPUT_TAB_SIZE] __ALIGN_END =
                        {0x54,0x68,0x65,0x20,0x68,0x61,0x73,0x68,
                         0x20,0x70,0x72,0x6f,0x63,0x65,0x73,0x73,
                         0x6f,0x72,0x20,0x69,0x73,0x20,0x61,0x20,
                         0x66,0x75,0x6c,0x6c,0x79,0x20,0x63,0x6f,
                         0x6d,0x70,0x6c,0x69,0x61,0x6e,0x74,0x20,
                         0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,
                         0x74,0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,
                         0x66,0x20,0x74,0x68,0x65,0x20,0x73,0x65,
                         0x63,0x75,0x72,0x65,0x20,0x68,0x61,0x73,
                         0x68,0x20,0x61,0x6c,0x67,0x6f,0x72,0x69,
                         0x74,0x68,0x6d,0x20,0x28,0x53,0x48,0x41,
                         0x2d,0x31,0x29,0x2c,0x20,0x74,0x68,0x65,
                         0x20,0x4d,0x44,0x35,0x20,0x28,0x6d,0x65,
                         0x73,0x73,0x61,0x67,0x65,0x2d,0x64,0x69,
                         0x67,0x65,0x73,0x74,0x20,0x61,0x6c,0x67,
                         0x6f,0x72,0x69,0x74,0x68,0x6d,0x20,0x35,
                         0x29,0x20,0x68,0x61,0x73,0x68,0x20,0x61,
                         0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                         0x20,0x61,0x6e,0x64,0x20,0x74,0x68,0x65,
                         0x20,0x48,0x4d,0x41,0x43,0x20,0x28,0x6b,
                         0x65,0x79,0x65,0x64,0x2d,0x68,0x61,0x73,
                         0x68,0x20,0x6d,0x65,0x73,0x73,0x61,0x67,
                         0x65,0x20,0x61,0x75,0x74,0x68,0x65,0x6e,
                         0x74,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,
                         0x20,0x63,0x6f,0x64,0x65,0x29,0x20,0x61,
                         0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,
                         0x20,0x73,0x75,0x69,0x74,0x61,0x62,0x6c,
                         0x65,0x20,0x66,0x6f,0x72,0x20,0x61,0x20,
                         0x76,0x61,0x72,0x69,0x65,0x74,0x79,0x20,
                         0x6f,0x66,0x20,0x61,0x70,0x70,0x6c,0x69,
                         0x63,0x61,0x74,0x69,0x6f,0x6e,0x73,0x2e,
                         0x2a,0x2a,0x2a,0x20,0x53,0x54,0x4d,0x33,
                         0x32,0x20,0x2a,0x2a,0x2a};
__ALIGN_BEGIN static uint8_t aHashDigest[32] __ALIGN_END;

void print_hex(uint8_t* buf, uint32_t len) {
        for(uint32_t i=0; i<len; ++i) {
                printf("%02X", *(buf+i));
        }
        printf("\r\n");
}
构建, 获取计算结果:

计算起来很快的, 具体相对于软件计算的加速倍数跟优化选项和是否选择DMA有关, 之前在其他系列上测试过, 跟软件计算的速度相比至少是两个数量级. 感兴趣的同学可以做一个精确的Benchmark.
另外使用一个Python程序来验证运算的结果准确性:
import hmac
import hashlib
import sys
import binascii
import json

def main_str(key, msg) -> None:
    print("key:%s\nmsg:%s\n" % (key, msg))
    bkey = bytes(key, 'utf-8')
    bmsg = bytes(msg, 'utf-8')
   
    main_bin(bkey, bmsg)
    return

def main_bin(bkey, bmsg) -> None:
    print("bkey:%s\nbmsg:%s\n" % (binascii.hexlify(bkey), binascii.hexlify(bmsg)))
   
    result = hashlib.md5(bmsg).hexdigest()
    print("hash md5:\t" + result)
    result = hashlib.sha1(bmsg).hexdigest()
    print("hash sha1:\t" + result)
    result = hashlib.sha224(bmsg).hexdigest()
    print("hash sha224:\t" + result)
    result = hashlib.sha256(bmsg).hexdigest()
    print("hash sha256:\t" + result)

    result = hmac.new(bkey, bmsg, hashlib.md5).hexdigest()
    print("hmac md5:\t" + result)
    result = hmac.new(bkey, bmsg, hashlib.sha1).hexdigest()
    print("hmac sha1:\t" + result)
    result = hmac.new(bkey, bmsg, hashlib.sha224).hexdigest()
    print("hmac sha224:\t" + result)
    result = hmac.new(bkey, bmsg, hashlib.sha256).hexdigest()
    print("hmac sha256:\t" + result)
    return

if __name__ == "__main__":
    read_mode='string'
    if 1 < len(sys.argv):
        if sys.argv[1] == 's':
            read_mode = 'string'
            test_key='The hash processor is a fully compliant implementation of the secure hash algorithm (SHA-1), the MD5 (message-digest algorithm 5) hash algorithm and the HMAC (keyed-hash message authentication code) algorithm suitable for a variety of applications.*** STM32 ***'
            test_msg='The hash processor is a fully compliant implementation of the secure hash algorithm (SHA-1), the MD5 (message-digest algorithm 5) hash algorithm and the HMAC (keyed-hash message authentication code) algorithm suitable for a variety of applications.*** STM32 ***'
            if 2 < len(sys.argv):
                test_key=sys.argv[2]
            if 3 < len(sys.argv):
                test_msg=sys.argv[3]

            main_str(test_key, test_msg)
            pass
        elif sys.argv[1] == 'f':
            read_mode = 'file'
            test_hex_input_file='hexInput.json'
            test_bkey=b'\x12\x34'
            test_bmsg=b'\x45\x67'
            if 2 < len(sys.argv):
                test_hex_input_file=sys.argv[2]
            json_load=''
            with open(test_hex_input_file, mode='rb') as fin:
                json_load = json.load(fin)
                test_bkey = bytearray.fromhex(json_load['key'])
                test_bmsg = bytearray.fromhex(json_load['msg'])         
            main_bin(test_bkey, test_bmsg)
            pass
        else:
            print("invalid read mode:" + sys.argv[1])
            pass
    else:
        print("no read mode provided!")
        pass
    pass
测试数据文件:
{
    "key":"54686520686173682070726f636573736f7220697320612066756c6c7920636f6d706c69616e7420696d706c656d656e746174696f6e206f662074686520736563757265206861736820616c676f726974686d20285348412d31292c20746865204d443520286d6573736167652d64696765737420616c676f726974686d203529206861736820616c676f726974686d20616e642074686520484d414320286b657965642d68617368206d6573736167652061757468656e7469636174696f6e20636f64652920616c676f726974686d207375697461626c6520666f7220612076617269657479206f66206170706c69636174696f6e732e2a2a2a2053544d3332202a2a2a",
    "msg":"54686520686173682070726f636573736f7220697320612066756c6c7920636f6d706c69616e7420696d706c656d656e746174696f6e206f662074686520736563757265206861736820616c676f726974686d20285348412d31292c20746865204d443520286d6573736167652d64696765737420616c676f726974686d203529206861736820616c676f726974686d20616e642074686520484d414320286b657965642d68617368206d6573736167652061757468656e7469636174696f6e20636f64652920616c676f726974686d207375697461626c6520666f7220612076617269657479206f66206170706c69636174696f6e732e2a2a2a2053544d3332202a2a2a"
}
验证:
$ python3 t1.py f
bkey:b'54686520686173682070726f636573736f7220697320612066756c6c7920636f6d706c69616e7420696d706c656d656e746174696f6e206f662074686520736563757265206861736820616c676f726974686d20285348412d31292c20746865204d443520286d6573736167652d64696765737420616c676f726974686d203529206861736820616c676f726974686d20616e642074686520484d414320286b657965642d68617368206d6573736167652061757468656e7469636174696f6e20636f64652920616c676f726974686d207375697461626c6520666f7220612076617269657479206f66206170706c69636174696f6e732e2a2a2a2053544d3332202a2a2a'
bmsg:b'54686520686173682070726f636573736f7220697320612066756c6c7920636f6d706c69616e7420696d706c656d656e746174696f6e206f662074686520736563757265206861736820616c676f726974686d20285348412d31292c20746865204d443520286d6573736167652d64696765737420616c676f726974686d203529206861736820616c676f726974686d20616e642074686520484d414320286b657965642d68617368206d6573736167652061757468656e7469636174696f6e20636f64652920616c676f726974686d207375697461626c6520666f7220612076617269657479206f66206170706c69636174696f6e732e2a2a2a2053544d3332202a2a2a'

hash md5:       6707862c7cd0b522b2dd22d8477be318
hash sha1:      f859c18dec9472427924fb61ef7c6a6b670bf9c3
hash sha224:    76ccdd1fde036cde39c9d23ce6bdb169ff743b89d15791bfba109a55
hash sha256:    9691cf47c93807990b049ad4d2e7f60133ab48aada53a80889a3da46170f4afe
hmac md5:       877ebbbfc8a9c08578a2c331d67ec70e
hmac sha1:      2b47ef34f66658be3b2ac6ec5885f21ed59fddad
hmac sha224:    6bd3132e89c7715c9cbaee0150d0b25c577297e4264031cae9656078
hmac sha256:    c501fc6c173778e69744ae06944f094c9eaf1c562f58debc478cdea85a421f58

所有代码在这个仓库:
git@github.com:zhanzr/Nucelo144-STM32U575.git
分支:
hash_test

谢谢阅读,  下一篇再见!







使用特权

评论回复
沙发
lulugl| | 2023-3-10 17:02 | 只看该作者
楼主大佬,专业呀!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:每天都進步

91

主题

1013

帖子

34

粉丝