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

很幸运又拿到了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

 谢谢阅读,  下一篇再见!

---------------------
作者:zhanzr21
链接:https://bbs.21ic.com/icview-3288320-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值