cancel
Showing results for 
Search instead for 
Did you mean: 

SAES using wrapped key

AKova.3
Associate II

I am working with SAES on STM32U585. I am trying to make use of wrapping/unwrappinng my encryption key with  hardware-secret key DHUK . 

This in the SAES initialization I am using

 

	hcryp.Instance = SAES;
	hcryp.Init.DataType = CRYP_BYTE_SWAP;
	hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
	hcryp.Init.pInitVect = (uint32_t *)iv;
	hcryp.Init.pKey = (uint32_t *)key;
	hcryp.Init.Algorithm = CRYP_AES_CBC;
	hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
	hcryp.Init.KeyIVConfigSkip = CRYP_KEYNOCONFIG;
	hcryp.Init.KeyMode = CRYP_KEYMODE_WRAPPED;
	hcryp.Init.KeySelect = CRYP_KEYSEL_HW;
	hcryp.Init.KeyProtection = CRYP_KEYPROT_DISABLE;

 

 I make the encryption key available to SAES with 

 

	  HAL_CRYPEx_WrapKey(&hcryp, key, encrypted_key, 100);
	  HAL_CRYPEx_UnwrapKey(&hcryp, encrypted_key, 100);

 

If I make a simple test with

 

	  HAL_CRYP_Encrypt(&hcryp, (uint32_t*)test, 4, (uint32_t*)wbuf, 100);
	  HAL_CRYP_Decrypt(&hcryp, (uint32_t*)wbuf, 4, (uint32_t*)dbuf, 100);

 

i get the expected results. The encrypted text is what it shoud be and decrypt returns the original text. 

If I however call HAL_CRYP_Decrypt for the second time following the first call, passing it the same encypted text as the first time, it returns incorrect result. Also, a call to HAL_CRYP_Encrypt following a previous HAL_CRYP_Decrypt produces different result if passed the same plain text each time. I have found that all successive calls to HAL_CRYP_Encrypt produce the same result, which is correct if HAL_CRYP_Decrypt hasn't been called before, or incorrect if HAL_CRYP_Decrypt has previously been called. KEYVALID bit in SAES->CR register is set for the whole time and no error flags are raised. I have stepped through both HAL_CRYP_Encrypt and HAL_CRYP_Decrypt functions making sure that software doesn't try to load KEY registers since a valid key is already present there from wrapping/unwrapping procedure. I have observed the same thing when using ECB or CBC mode.

If I do a sequence of denit, init and key unwrapping, the next call to either HAL_CRYP_Encrypt or HAL_CRYP_Decrypt produces expected results. 

It sort of looks like that some state is carried over from decryption on to the next operation.

I did not observe this behaviour if I didn't use key wrapping/unwrapping but was loading the encryption key with software.

Any help would be appriciated.

6 REPLIES 6
Jocelyn RICARD
ST Employee

Hello @AKova.3 ,

When using HAL_CRYP_Decrypt, you have the key preparation that is done automatically.

This key preparation has to be done only once.

So, the way to use this API several times is to setup cryp configuration with:

hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;

This configuration has to be done before the first call to HAL_CRYP_Decrypt

Best regards

Jocelyn

I have put CRYP_KEYIVCONFIG_ONCE in to my init function, and if the first function I call afterwards is HAL_CRYP_Decrypt, providing it the encrypted text which would be produced with encryption, the funtion returns all 0s. If I first call HAL_CRYP_Encrypt it returns the correct encrypted text, but the following call to HAL_CRYP_Decrypt returns incorrect value (which is not all 0s this time). It is true that if I repeatedly call HAL_CRYP_Decrypt afterwards it returns the same value each time, but the value is incorrect. As before, a call to HAL_CRYP_Encrypt at this point also returns incorrect results. I have tried other options for hcryp.Init.KeyIVConfigSkip but none of them
provide the desired results. 

Jocelyn RICARD
ST Employee

Hello @AKova.3 ,

the parameter  CRYP_KEYIVCONFIG_ONCE must be set only for decryption.

Best regards

Jocelyn

Here's the code I am running

 

uint32_t key[4] = {0x2b7e1516,0x28aed2a6,0xabf71588,0x09cf4f3c};
uint32_t iv[4] = {0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f};
uint32_t encrypted_key[4] = {0};

hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_BYTE_SWAP;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp.Init.pInitVect = (uint32_t *)iv;
hcryp.Init.pKey = (uint32_t *)key;
hcryp.Init.Algorithm = CRYP_AES_CBC;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYNOCONFIG;
hcryp.Init.KeyMode = CRYP_KEYMODE_WRAPPED;
hcryp.Init.KeySelect = CRYP_KEYSEL_HW;
hcryp.Init.KeyProtection = CRYP_KEYPROT_DISABLE;
HAL_CRYP_Init(&hcryp);

HAL_CRYPEx_WrapKey(&hcryp, key, encrypted_key, 100);
HAL_CRYPEx_UnwrapKey(&hcryp, encrypted_key, 100);

CRYP_ConfigTypeDef Conf = {0};
HAL_CRYP_GetConfig(&hcryp, &Conf);
Conf.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
HAL_CRYP_SetConfig(&hcryp, &Conf);

uint8_t wbuf[16] = {0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46, 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d};
HAL_CRYP_Decrypt(&hcryp, (uint32_t*)wbuf, 4, (uint32_t*)dbuf, 100);

 

HAL_CRYP_Decrypt return the value of all 0s but should be {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a}

 

Jocelyn RICARD
ST Employee

Hello @AKova.3 ,

reason is you removed the encrypt call which is setting the key mode to normal (not done in decrypt).

So, a simple way to fix this is to add:

MODIFY_REG(hcryp.Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);

before the decryption

Best regards

Jocelyn

I appriciate your help but it still didn't solve my issue. I still get the incorrect result when I put the line you suggested before the first call to HAL_CRYP_Decrypt. As before I have configured AES in CBC mode with 128 bit key with this the following inputs:

Key: 2b7e151628aed2a6abf7158809cf4f3c

IV: 000102030405060708090a0b0c0d0e0f

Plaintext: 6bc1bee22e409f96e93d7e117393172a

These parameters procude the ciphertext 7649abac8119b246cee98e9b12e9197d, which I have as an input the to the decrypt function.

I am running the following code:

hcryp.Instance = SAES;
hcryp.Init.DataType = CRYP_BYTE_SWAP;
hcryp.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp.Init.pInitVect = (uint32_t *)iv;
hcryp.Init.pKey = (uint32_t *)key;
hcryp.Init.Algorithm = CRYP_AES_CBC;
hcryp.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp.Init.KeyIVConfigSkip = CRYP_KEYNOCONFIG;
hcryp.Init.KeyMode = CRYP_KEYMODE_WRAPPED;
hcryp.Init.KeySelect = CRYP_KEYSEL_HW;
hcryp.Init.KeyProtection = CRYP_KEYPROT_DISABLE;
HAL_CRYP_Init(&hcryp);

HAL_CRYPEx_WrapKey(&hcryp, ekey, encrypted_key, 100); 
HAL_CRYPEx_UnwrapKey(&hcryp, encrypted_key, 100);

CRYP_ConfigTypeDef Conf = {0};
HAL_CRYP_GetConfig(&hcryp, &Conf);
Conf.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
HAL_CRYP_SetConfig(&hcryp, &Conf);

MODIFY_REG(hcryp.Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
HAL_CRYP_Decrypt(&hcryp, (uint32_t*)wbuf, 4, (uint32_t*)dbuf, 100);

 

The decrypted output I get is f49dac72ed15204d80ed9d5d7b50c478, which is not the original plaintext.

 

I've also found that if I move the wrapping/unwrapping function calls after setting the KeyIVConfigSkip option to CRYP_KEYIVCONFIG_ONCE or if I have the CRYP_KEYIVCONFIG_ONCE option already set with the HAL_CRYP_Init function I get a different result from HAL_CRYP_Decrypt, which this time is c6998505d039fa1d1e6d365a607e4d2c.