Unexpected results for AES (ECB mode)
Hi folks,
I am trying to use the hardware-AES of the STM32WLE5JC, but I get weird results that do not match the expected values. I am comparing my STM-implementation against RadioLib's Crypto which is based on tiny-AES-c and AES-CMAC. RadioLib's implementation yields results that completely match verification tools such as this one.
I am investigating two things: 1) single-buffer ECB encryption, and 2) CMAC calculation based on ECB encryption. My observations are as follows:
- encrypting a single ECB buffer yields incorrect results,
- calculating CMAC (which uses ECB encryption as subroutine) is OK / as expected,
- calculating CMAC and then a single ECB buffer yields expected results*
* I only get OK results for buffers <=128 bits.
Example:
uint8_t key[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
RadioLibAES128Instance.init(key);
uint8_t data[24] = { 0 };
uint8_t out[24] = { 0 };
// RadioLibAES128Instance.generateCMAC(data, 24, out);
RadioLibAES128Instance.encryptECB(data, 24, out);
RadioLib's software ECB outputs the following (verified using AES calculator):
11:17:16.387 > RLB_PRO: Init key:
11:17:16.389 > RLB_PRO: 00000000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
11:17:16.396 > RLB_PRO: Data in:
11:17:16.397 > RLB_PRO: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
11:17:16.405 > RLB_PRO: 00000010: 00 00 00 00 00 00 00 00 ........
11:17:16.412 > RLB_PRO: Data out:
11:17:16.414 > RLB_PRO: 00000000: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 ..;7..[.oO.b...y
11:17:16.421 > RLB_PRO: 00000010: c6 a1 3b 37 87 8f 5b 82 ..;7..[.
Cube's hardware ECB outputs the following:
11:17:11.161 > RLB_PRO: Init key:
11:17:11.163 > RLB_PRO: 00000000: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................
11:17:11.170 > RLB_PRO: Data in:
11:17:11.172 > RLB_PRO: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
11:17:11.180 > RLB_PRO: 00000010: 00 00 00 00 00 00 00 00 ........
11:17:11.562 > RLB_PRO: Data out:
11:17:11.564 > RLB_PRO: 00000000: 52 9d 08 6c 42 02 9a 85 43 44 05 6d 78 ab 8d 9f R..lB...CD.mx...
11:17:11.573 > RLB_PRO: 00000010: 46 63 6a 4c d9 4f 0c f8 FcjL.O..
When I uncomment the call the `generateCMAC()`, the following is the output of the CMAC call and the subsequent call to `encryptECB()` for RadioLib (CMAC verified using calculator, ECB output same as earlier):
11:29:36.528 > RLB_PRO: CMAC Data out:
11:29:36.530 > RLB_PRO: 00000000: 0b 14 5a b3 85 41 ba e9 2b 04 6a 68 81 0e 6f c2 ..Z..A..+.jh..o.
11:29:36.538 > RLB_PRO: Data in:
11:29:36.539 > RLB_PRO: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
11:29:36.546 > RLB_PRO: 00000010: 00 00 00 00 00 00 00 00 ........
11:29:36.554 > RLB_PRO: Data out:
11:29:36.556 > RLB_PRO: 00000000: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 ..;7..[.oO.b...y
11:29:36.563 > RLB_PRO: 00000010: c6 a1 3b 37 87 8f 5b 82 ..;7..[.
And the same for Cube-hardware (CMAC output correct, ECB output first 16 bytes correct, other 8 incorrect):
11:29:29.863 > RLB_PRO: CMAC Data out:
11:29:29.866 > RLB_PRO: 00000000: 0b 14 5a b3 85 41 ba e9 2b 04 6a 68 81 0e 6f c2 ..Z..A..+.jh..o.
11:29:29.873 > RLB_PRO: Data in:
11:29:29.875 > RLB_PRO: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
11:29:29.884 > RLB_PRO: 00000010: 00 00 00 00 00 00 00 00 ........
11:29:29.891 > RLB_PRO: Data out:
11:29:29.894 > RLB_PRO: 00000000: c6 a1 3b 37 87 8f 5b 82 6f 4f 81 62 a1 c8 d8 79 ..;7..[.oO.b...y
11:29:29.901 > RLB_PRO: 00000010: 13 97 f1 e0 eb cd 02 f9 ........
I am at a loss for how I should fix this. The key- and buffer-endianness seems all good given that I do get correct results, but only under specific circumstances. The crypto initialization is done as follows:
stm32CubeCrypto.Instance = AES;
stm32CubeCrypto.Init.DataType = CRYP_DATATYPE_32B;
stm32CubeCrypto.Init.KeySize = CRYP_KEYSIZE_128B;
stm32CubeCrypto.Init.pKey = key32;
stm32CubeCrypto.Init.Algorithm = CRYP_AES_ECB;
stm32CubeCrypto.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
stm32CubeCrypto.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_WORD;
stm32CubeCrypto.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
status = HAL_CRYP_Init(&stm32CubeCrypto);
Any clues, hints, further questions are very much appreciated!
