2024-11-08 04:18 AM
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.
2024-11-12 05:33 AM
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
2024-11-13 12:46 AM
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.
2024-11-13 12:51 AM
Hello @AKova.3 ,
the parameter CRYP_KEYIVCONFIG_ONCE must be set only for decryption.
Best regards
Jocelyn
2024-11-13 03:58 AM - edited 2024-11-13 04:01 AM
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}
2024-11-13 07:54 AM
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
2024-11-17 11:47 PM
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.
2024-11-25 10:10 AM
Hello @AKova.3 ,
here is the sequence that works:
MX_SAES_AES_Init();
/* USER CODE BEGIN 2 */
/* User key AESKey256 encryption*/
if (HAL_CRYPEx_WrapKey(&hcryp, AESKey256, Encryptedkey, TIMEOUT_VALUE) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
/* we could not compare results, key is not known and unique for each device */
/* User key AESKey256 decryption*/
if (HAL_CRYPEx_UnwrapKey(&hcryp, Encryptedkey, TIMEOUT_VALUE) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
MODIFY_REG(hcryp.Instance->CR, AES_CR_KMOD, CRYP_KEYMODE_NORMAL);
//MODIFY_REG(hcryp.Instance->CR, AES_CR_MODE, AES_CR_MODE_1);
hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE;
/*Secure AES ECB Decryption */
if (HAL_CRYP_Decrypt(&hcryp, CiphertextAESECB256, 16, DecryptedText, TIMEOUT_VALUE) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
/*Compare decryption result with Plaintext*/
if(memcmp(DecryptedText, Plaintext, 64) != 0)
{
/* Processing Error */
Error_Handler();
}
/*Secure AES ECB Decryption */
if (HAL_CRYP_Decrypt(&hcryp, CiphertextAESECB256, 16, DecryptedText, TIMEOUT_VALUE) != HAL_OK)
{
/* Processing Error */
Error_Handler();
}
/*Compare decryption result with Plaintext*/
if(memcmp(DecryptedText, Plaintext, 64) != 0)
{
/* Processing Error */
Error_Handler();
}
Best regards
Jocelyn
2024-11-26 03:21 AM
The code you posted works for me in ECB mode, but not in CBC. In CBC mode I get the correct result only the on the first call to HAL_CRYP_Decrypt, all the following calls produce incorrect result, which is at least the same every time.
2024-11-26 08:19 AM
Hello @AKova.3 ,
Sorry, I missed this point.
You can check with following configuration:
CRYP_ConfigTypeDef Conf={0};
HAL_CRYP_GetConfig(&hcryp, &Conf);
/* Change CRYP parameters */
Conf.KeyMode = CRYP_KEYMODE_NORMAL;
Conf.KeySelect = CRYP_KEYSEL_NORMAL;
Conf.Algorithm = CRYP_AES_CBC;
Conf.pInitVect = AESIV;
Conf.KeyMode = CRYP_KEYMODE_NORMAL;
Best regards,
Jocelyn