Skip to main content
Associate II
October 22, 2024
Solved

Unexpected results for AES (ECB mode)

  • October 22, 2024
  • 1 reply
  • 2159 views

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:

  1. encrypting a single ECB buffer yields incorrect results,
  2. calculating CMAC (which uses ECB encryption as subroutine) is OK / as expected,
  3. 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!

Best answer by Tesla DeLorean

Doesn't AES-128 only work on 16-byte lines? You'd need to PAD appropriately to the next paragraph. As it rearranges all 128-bits in the line. ie give it 32-bytes of padded input, get 32-bytes of output

Or use CTR mode which is the Encrypt to a 16-byte line which you then get to XOR with the data stream

uint8_t key[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

You don't show your 32-bit key, which I might expect needs to be

uint32_t key32[4] = { 0x00010203, 0x04050607,0x08090A0B,0x0C0D0E0F };

1 reply

bnsAuthor
Associate II
October 28, 2024

Is there someone who can give some input on this, please? :)

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
October 28, 2024

Doesn't AES-128 only work on 16-byte lines? You'd need to PAD appropriately to the next paragraph. As it rearranges all 128-bits in the line. ie give it 32-bytes of padded input, get 32-bytes of output

Or use CTR mode which is the Encrypt to a 16-byte line which you then get to XOR with the data stream

uint8_t key[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

You don't show your 32-bit key, which I might expect needs to be

uint32_t key32[4] = { 0x00010203, 0x04050607,0x08090A0B,0x0C0D0E0F };

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
October 29, 2024

You'd need to encrypt from a 32-byte, zero padded buffer

0000 : C6 A1 3B 37 87 8F 5B 82-6F 4F 81 62 A1 C8 D8 79 ..;7..[.oO.b...y
0010 : C6 A1 3B 37 87 8F 5B 82-6F 4F 81 62 A1 C8 D8 79 ..;7..[.oO.b...y

To get your 24-bytes back you'd need to decrypt the 32-byte cipher-text, and take the first 24-bytes

IN
0000 : 00 01 02 03 04 05 06 07-08 09 0A 0B 0C 0D 0E 0F ................
0010 : 10 11 12 13 14 15 16 17-00 00 00 00 00 00 00 00 ................

OUT
0000 : 0A 94 0B B5 41 6E F0 45-F1 C3 94 58 C6 53 EA 5A ....An.E...X.S.Z
0010 : 8D E6 D8 C0 DD 5B CC 98-DF 46 3A CA E0 F5 2A 75 .....[...F:...*u

 

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..