cancel
Showing results for 
Search instead for 
Did you mean: 

STM32U585: AES GCM Tag mismatch

SafeDev
Associate II

Good afternoon,

we are facing issue with AES GCM Tag generated with STM32U585.

In particular we compare the results generated by the microcontroller with the ones generated by an application developed with C#.

This is the code running on the microcontroller

SafeDev_0-1739541887725.png

Key size is 256 Bit set to all 0 just to speed operations. Tag size is 128 bit. I know that the IV vector must have the last byte set as 2 an I dit it as requested.

 

 

 

 

uint32_t pKeyAES[8] = {0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000};

uint32_t pInitVectAES[4] = {0x00000000,0x00000000,0x00000000,0x00000002};

__ALIGN_BEGIN static const uint32_t HeaderAES[4] __ALIGN_END = {

0x24825602,0xbd12a984,0xe0092d3e,0x448eda5f};

 

 

 

Plaintext is a simple 48 bytes buffer (so a multiple of 16).

The EncryptedText is identical to the one generated by the application: good.

On the other hand the generated Tag is always different....maybe we are doing something wrong....could you help us with this topic?

Thanks

Best regards

10 REPLIES 10
CMYL
ST Employee

Ciao @SafeDev 

 Sorry for my late answer. I want to ask if Tag is always different whatever the vector test or just when the key and IV are Zeros ? 

Can you compare the computed TAG of your implementation versus the vector test provided by ~\STM32Cube_FW_U5_V1.7.0\Projects\B-U585I-IOT02A\Examples\CRYP\CRYP_AES_GCM ?

 

__ALIGN_BEGIN static const uint32_t pKeyAES[4] __ALIGN_END = {
                            0xC939CC13,0x397C1D37,0xDE6AE0E1,0xCB7C423C};
__ALIGN_BEGIN static const uint32_t pInitVectAES[4] __ALIGN_END = {
                            0xB3D8CC01,0x7CBB89B3,0x9E0F67E2,0x00000002};
__ALIGN_BEGIN static const uint32_t HeaderAES[4] __ALIGN_END = {
                            0x24825602,0xbd12a984,0xe0092d3e,0x448eda5f};

/* USER CODE BEGIN PV */
uint32_t Plaintext[PLAINTEXT_SIZE] = {0xc3b3c41f,0x113a31b7,0x3d9a5cd4,0x32103069};

uint32_t Ciphertext[4] = {0x93FE7D9E,0x9BFD1034,0x8A5606E5,0xCAFA7354};

uint32_t ExpectedTAG[4]={0x0032A1DC,0x85F1C978,0x6925A2E7,0x1D8272DD};

 

 

Best regards

 

Hi CMYL,

thanks for the feedback.

I want to ask if Tag is always different whatever the vector test or just when the key and IV are Zeros ?

Yes, the TAG is always different even if I change the IV or the key.

Can you compare the computed TAG of your implementation versus the vector test provide.

Yes for sure.

First of all this is my running code

SafeDev_3-1741674243897.png

In order to be compliant with your example I have to change a little bit my AES configuration (Key is downgrade to 128 bit, No byte swap, DataWidthUnit set to word and HeaderWidthUnit set to word).

SafeDev_2-1741674177010.png

With these parameters I could obtain same cyphertext as yours

SafeDev_0-1741674106914.png

but again different TAG

TAG computed by STM32U585

SafeDev_1-1741674153585.png

TAG computed by Visual Studio code

SafeDev_4-1741674333857.png

TAG expected by your code example

uint32_t ExpectedTAG[4]={0x0032A1DC,0x85F1C978,0x6925A2E7,0x1D8272DD};

So we have three different tags.....

Thank you

Best regards

Hi @SafeDev 

In the MX_AES_Init(void) function, in the field HeaderSize you put : 

hcryp.Init.HeaderSize = 1;

It should be 

hcryp.Init.HeaderSize = 4;

As the the expected tag is computed whith size 4

 

Can you check again ?

Best regards

Hi CMYL,

little better.

Now computed TAG match with the example one.

SafeDev_0-1741688241671.png

Unfortunately it still not match with the Visual Studio generated one.

This is the very simple Visual Studio code

SafeDev_1-1741688363587.png

As said before I have match between STM32U585 crypted text and Visual Studio crypted text. But tag results are different. (Visual Studio Tag is shown in the previous post)

Thank you

Best regards

 

CMYL
ST Employee

Hi @SafeDev 

>> what is the origin of the visual studio code ? Your own code or some built-in code ?

For the validation of this implementation you can refer to NIST vectors examples for AES GCM. Check the gcmEncrypt/decrypt testvectors in this Github

You can check for example the following vector test from gcmEncryptExtIV256.rsp

/** Extract from NIST Special Publication 800-38D
  * gcmEncryptExtIV256.rsp
[Keylen = 128]
[IVlen = 96]
[PTlen = 408]
[AADlen = 384]
[Taglen = 128]

Count = 0
Key = 463b412911767d57a0b33969e674ffe7845d313b88c6fe312f3d724be68e1fca
IV = 611ce6f9a6880750de7da6cb
PT = e7d1dcf668e2876861940e012fe52a98dacbd78ab63c08842cc9801ea581682ad54af0c34d0d7f6f59e8ee0bf4900e0fd85042
AAD = 0a682fbc6192e1b47a5e0868787ffdafe5a50cead3575849990cdd2ea9b3597749403efb4a56684f0c6bde352d4aeec5
CT = 8886e196010cb3849d9c1a182abe1eeab0a5f3ca423c3669a4a8703c0f146e8e956fb122e0d721b869d2b6fcd4216d7d4d3758
Tag = 2469cecd70fd98fec9264f71df1aee9a
  */
const uint8_t Key[] =
{
  0x46, 0x3b, 0x41, 0x29, 0x11, 0x76, 0x7d, 0x57, 0xa0, 0xb3, 0x39, 0x69, 0xe6, 0x74, 0xff, 0xe7,
  0x84, 0x5d, 0x31, 0x3b, 0x88, 0xc6, 0xfe, 0x31, 0x2f, 0x3d, 0x72, 0x4b, 0xe6, 0x8e, 0x1f, 0xca
};
const uint8_t IV[] =
{
  0x61, 0x1c, 0xe6, 0xf9, 0xa6, 0x88, 0x07, 0x50, 0xde, 0x7d, 0xa6, 0xcb
};
const uint8_t Plaintext[] =
{
  0xe7, 0xd1, 0xdc, 0xf6, 0x68, 0xe2, 0x87, 0x68, 0x61, 0x94, 0x0e, 0x01, 0x2f, 0xe5, 0x2a, 0x98,
  0xda, 0xcb, 0xd7, 0x8a, 0xb6, 0x3c, 0x08, 0x84, 0x2c, 0xc9, 0x80, 0x1e, 0xa5, 0x81, 0x68, 0x2a,
  0xd5, 0x4a, 0xf0, 0xc3, 0x4d, 0x0d, 0x7f, 0x6f, 0x59, 0xe8, 0xee, 0x0b, 0xf4, 0x90, 0x0e, 0x0f,
  0xd8, 0x50, 0x42
};
const uint8_t AddData[] =
{
  0x0a, 0x68, 0x2f, 0xbc, 0x61, 0x92, 0xe1, 0xb4, 0x7a, 0x5e, 0x08, 0x68, 0x78, 0x7f, 0xfd, 0xaf,
  0xe5, 0xa5, 0x0c, 0xea, 0xd3, 0x57, 0x58, 0x49, 0x99, 0x0c, 0xdd, 0x2e, 0xa9, 0xb3, 0x59, 0x77,
  0x49, 0x40, 0x3e, 0xfb, 0x4a, 0x56, 0x68, 0x4f, 0x0c, 0x6b, 0xde, 0x35, 0x2d, 0x4a, 0xee, 0xc5
};
const uint8_t Expected_Ciphertext[] =
{
  0x88, 0x86, 0xe1, 0x96, 0x01, 0x0c, 0xb3, 0x84, 0x9d, 0x9c, 0x1a, 0x18, 0x2a, 0xbe, 0x1e, 0xea,
  0xb0, 0xa5, 0xf3, 0xca, 0x42, 0x3c, 0x36, 0x69, 0xa4, 0xa8, 0x70, 0x3c, 0x0f, 0x14, 0x6e, 0x8e,
  0x95, 0x6f, 0xb1, 0x22, 0xe0, 0xd7, 0x21, 0xb8, 0x69, 0xd2, 0xb6, 0xfc, 0xd4, 0x21, 0x6d, 0x7d,
  0x4d, 0x37, 0x58,
};
const uint8_t Expected_Tag[] =
{
  0x24, 0x69, 0xce, 0xcd, 0x70, 0xfd, 0x98, 0xfe, 0xc9, 0x26, 0x4f, 0x71, 0xdf, 0x1a, 0xee, 0x9a
};

 

Hi CMYL,

I just googling for some example. Language is C#.

Do you have some hints about it?

Many Thanks

Best regards

 

Hi SafeDev,

I just edited my previous comment. Can you check your implementation with NIST test vectors ?

I provided a link and a Test Vector to check if the C# implementation is correct or not

 

Best Regards,

 

Hi CMYL,

nice idea.

I have made some test and still the TAG does not match.

So now it is a Visual Studio code problem, I think from ST side we are solved.

Again, thanks you very much.

Best regards

Hi CMYL,

I try to use same test vector on STM32 but still have tag problem.

This are the key,IV and additional data as per NIST example.

uint32_t pKeyAES[8] = {0x463B4129,0x11767D57,0xA0B33969,0xE674FFE7,0x845D313B,0x88C6FE31,0x2F3D724B,0xE68E1FCA};
uint32_t pInitVectAES[4] = {0x611CE6F9,0xA6880750,0xDE7DA6CB,0x00000002};
__ALIGN_BEGIN static const uint32_t HeaderAES[12] __ALIGN_END = {
                            0x0a682fbc,0x6192e1b4,0x7a5e0868,0x787ffdaf,0xe5a50cea,0xd3575849,0x990cdd2e,0xa9b35977,0x49403efb,0x4a56684f,
                            0x0c6bde35,0x2d4aeec5};

This the peripheral configuration. We use Byte size due to the stream communication with Personal Computer and also we need BYTE_SWAP in order to get the same order as Personal Computer.

  hcryp.Instance = AES;
  hcryp.Init.DataType = CRYP_BYTE_SWAP;
  hcryp.Init.KeySize = CRYP_KEYSIZE_256B;
  hcryp.Init.pKey = (uint32_t *)pKeyAES;
  hcryp.Init.pInitVect = (uint32_t *)pInitVectAES;
  hcryp.Init.Algorithm = CRYP_AES_GCM_GMAC;
  hcryp.Init.Header = (uint32_t *)HeaderAES;
  hcryp.Init.HeaderSize = 12;
  hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
  hcryp.Init.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
  hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
  hcryp.Init.KeyMode = CRYP_KEYMODE_NORMAL;

Again: cyphertext perfectly match while TAG still mismatch.....

Thank you

Best regards