Skip to content

AES GCM Invalid Tag Generation after Decryption #88

@GeorgeCGV

Description

@GeorgeCGV

Describe the bug
An invalid tag is generated for payloads that are not a multiple of 4, as described in Re: STM32U545 AES GCM Tag mismatch - STMicroelectronics Community.

ST Internal ticket number: 210917.

How To Reproduce
An example STM32Cube-IDE project is generated with STM32CubeMX and attached in the mentioned community thread.

Describe the set-up
Custom board with STM32H730XX.

AES GCM encryption and decryption are performed with settings:

DataType = CRYP_DATATYPE_8B
DataWidthUnit  = CRYP_DATAWIDTHUNIT_BYTE
KeySize = CRYP_KEYSIZE_128B
HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE

Additional context

Tag is generated correctly when:

  • When the input array is 16 bytes, but we decode 15 bytes (as there is only 15 bytes of data).
  • When we dynamically allocate an aligned input array of size that is a multiple of 4,
    but decode with real size (i.e, 15).
  • When the input array is in the global scope (regardless of its size).

The tag is generated incorrectly:

  • When the input array is 15 bytes on the stack.

Tried to flush and invalidate the input memory area, as well as to flush ECC (as buffers are located within SRAM with enabled ECC), no difference.

After further investigation, the culprit seems to be the padding bytes.

During the encryption, the CRYP_CR_NPBLB is used to let HW know which bytes to discard;
However, during the decryption process, it is not used/or available.

Here is the debug info, which shows that the input with 16 bytes has explicit 00 padding in the last word (0x00a989d1); whereas when the input buffer is 15 bytes, we get 8a instead of 00 in the last word (0x8aa989d1).

Working with 16 length:

x/15xb hcryp->pCrypInBuffPtr
0x2402a5d8: 0x13    0xb4    0xc7    0x2b    0x38    0x9d    0xc5    0x01
0x2402a5e0: 0x8e    0x72    0xa1    0x71    0xd1    0x89    0xa9

x/4xw hcryp->pCrypInBuffPtr
0x2402a5d8: 0x2bc7b413  0x01c59d38  0x71a1728e  0x00a989d1

When CrypInCount == 3
p/x *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount)
$2 = 0xa989d1

Not working with 15 length:

x/15xb hcryp->pCrypInBuffPtr
0x24021c54: 0x13    0xb4    0xc7    0x2b    0x38    0x9d    0xc5    0x01
0x24021c5c: 0x8e    0x72    0xa1    0x71    0xd1    0x89    0xa9

x/4xw hcryp->pCrypInBuffPtr
0x24021c54: 0x2bc7b413  0x01c59d38  0x71a1728e  0x8aa989d1

After correction of the padding in the last block (16 bytes) of the last writable word (4 bytes) the tag generation works fine after decryption, required changes are applied to CRYP_AESGCM_Process in stm32h7xx_hal_cryp.c:

--- a/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_cryp.c
+++ b/stm32cube/stm32h7xx/drivers/src/stm32h7xx_hal_cryp.c
@@ -3085,10 +3085,17 @@ static HAL_StatusTypeDef CRYP_AESGCM_Process(CRYP_HandleTypeDef *hcryp, uint32_t
       }
 
       /* Write the last input block in the IN FIFO */
+      unsigned pad_bytes = ((((uint32_t)(hcryp->Size) / 4U) + 1U) * 4U) - (uint32_t)(hcryp->Size);
       for (index = 0U; index < lastwordsize; index ++)
       {
-        hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
-        hcryp->CrypInCount++;
+          if (((hcryp->Instance->CR & CRYP_CR_ALGODIR) == CRYP_OPERATINGMODE_DECRYPT) &&
+              (((pad_bytes != 0)) && (index + 1 == lastwordsize))) {
+            // set pad bytes to 0
+            hcryp->Instance->DIN = (*(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount) << (pad_bytes * 8)) >> (pad_bytes * 8);
+          } else {
+            hcryp->Instance->DIN  = *(uint32_t *)(hcryp->pCrypInBuffPtr + hcryp->CrypInCount);
+          }
+          hcryp->CrypInCount++;
       }

PS: Although the fix appears to work (tested with input data of 15 and 42 bytes, with and without AD of size 13 and 20 bytes), I'm uncertain if it's entirely correct; therefore, I'm opening this as an issue. I can also submit a PR if needed.

Metadata

Metadata

Assignees

Labels

aesAdvanced Encryption Standard cryptographic corebugSomething isn't workingcrcCyclic Redundancy Check calculation unithalHAL-LL driver-related issue or pull-request.internal bug trackerIssue confirmed and logged into the internal bug tracking systemst communityAlso reported by users on the community.st.com

Type

Projects

Status

In progress

Relationships

None yet

Development

No branches or pull requests

Issue actions