SHA256 摘要在 Python 与 STM32 的内置 HASH 设备中不一致

SHA256 digest disagrees in Python vs. STM32's built-in HASH device

问题:

我正在尝试使用 mbedTLS 我正在使用的 STM32 中内置的 HASH 设备来计算 STM32L552ZE-Q 上单个块(512 位)的 SHA256 摘要。不幸的是,摘要与 Python 的 SHA256 实现不一致,即使对于单个全零块也是如此。

示例输出:

  1. Python: f5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b

  2. STM32,数据类型=1位:B20941D6177356919BCDF1F716029D5F53C81932439D59B98F04A5EE0E192A25

  3. STM32, data-type != 1 bit 037D6DFB3A369A41E01100FDD53C35EE3FB69DDEC5830D61E1138D066A4C2285

以上结果非常混乱。我的 MCU 的 STM32 参考手册指定 HASH 设备在 big-endian 的 32 位字上运行,并且消息需要通过将数据类型指定为 1、8、16 或 32 位来说明这一点。设置这些值会导致位被重新排序,但在我看来,排序不应该对全 0 块产生影响,因为 64 个 0 序列的任何排列再次只是 64 个 0。我显然误解了一些东西,因为更改数据类型(即重新排序)会导致哈希值发生变化。

Python代码:

from cryptography.hazmat.primitives import hashes
digest = hashes.Hash(hashes.SHA256())
by = b"[=11=]" * 64
digest.update(by)
print(digest.finalize().hex())

STM32代码:

#define SHA256_INPUT_SIZE       64                      // 512 bit
#define SHA256_OUTPUT_SIZE      32                      // 256 bit

// (0) Initialize the HASH peripheral
MX_HASH_Init();

// (1) Create input buffer of size one block (512 bit, 64 byte) and initialize it with all 0-bytes
byte_t ibuf[SHA256_INPUT_SIZE];
memset(ibuf, 0, sizeof(ibuf));

// (2) Create output buffer of size 256 bit, 32 byte (setting it to all 1-bytes shouldn't be relevant) 
byte_t obuf[SHA256_OUTPUT_SIZE];
memset(obuf, 1, sizeof(ibuf));

// (3) Compute the digest based on ibuf and store it into obuf
HAL_StatusTypeDef rv = HAL_HASHEx_SHA256_Start(&hhash, ibuf, SHA256_INPUT_SIZE, obuf, 10);
char debug_msg[MAX_PRINT_LEN];

// (4) Print an error message or the hash digest.
if(rv != HAL_OK){
    sprintf(debug_msg, "ERROR: HAL_HASHEx_SHA256_Start failed on line %i\r\n", __LINE__);
}
else{
    char hash_buf[SHA256_OUTPUT_SIZE * 3];                  // For one byte of the output digest, e.g. value 24, we write THREE characters (except for last byte of output, we only write TWO characters).
                                                            // Here, for value 24 we would write "18:" for 24 not the last byte and "18" if it is the last byte.
    memset(hash_buf, 1, sizeof(hash_buf));
    bytes_to_hex_string(obuf, SHA256_OUTPUT_SIZE, hash_buf);
    sprintf(debug_msg, "DEBUG: Hash output: %s\r\n", hash_buf);
}
print_debug(debug_msg);

问题:

  1. 我哪里做错了,即为什么我的 STM32 的哈希不正确(我也在 golang 中计算了摘要,它与 python 匹配)?
  2. 尽管块全为 0(因此排序没有影响),更改数据类型怎么可能影响散列?

根据“数据类型”重新排序的可视化表示:

原来是我草率写了memset(obuf, 1, sizeof(ibuf));而不是memset(obuf, 1, sizeof(obuf));导致的问题。这导致 memset 覆盖输入缓冲区的一部分以包含 256 个 1 位。这也解释了为什么STM32的重新排序特性导致输出改变...