cancel
Showing results for 
Search instead for 
Did you mean: 

AES_CBC_Encrypt and AES_CBC_Decrypt don't yield the same result again.

SWink
Associate II

I'm using an STM32L4A6ZG (as a nucleo board). This is the code I am using:

#include "err_codes.h"
#include "sk.h"
#include "aes_common.h"
#include "aes_cbc.h"
#define AES_BLOCK 16
#define IV_LENGTH 16
#define SIZE 32

__ALIGN_BEGIN static const uint8_t pKeyAES[16] __ALIGN_END = {
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00};
__ALIGN_BEGIN static const uint8_t pInitVectAES[16] __ALIGN_END = {
                            0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
                            0x00,0x00,0x00,0x00,0x00,0x00};
 
// Test Data and some return values for debugging
// 19 32 4b 64 7d 96 c8 fa 18 31 4a 63 7c 95 19 18 0 1 5 9 6d 1d 63 58 6c 6b 3b 1e 9 6 3 39
uint8_t Plaintext[SIZE] = {25,50,75,100,125,150,200,250,
24,49,74,99,124,149,25,24,
0, 1, 5, 9, 109, 29, 99, 88,
108, 107, 59, 30, 9, 6, 3, 57};
uint8_t tx[SIZE] = {0};

AESCBCctx_stt AESctx;
   uint32_t error_status = AES_SUCCESS;
   int32_t outputLength = 0;
   /* Set flag field to default value */
   AESctx.mFlags = E_SK_DEFAULT; //AccHw_E_SK_DEFAULT
   AESctx.mKeySize = AES_BLOCK;
   /* Set iv size field to IvLength*/
   AESctx.mIvSize = IV_LENGTH;
 
   error_status = AES_CBC_Encrypt_Init(&AESctx, pKeyAES,
 		  pInitVectAES );
   /* check for initialization errors */
   if (error_status == AES_SUCCESS) {
           /* Encrypt Data */
           error_status = AES_CBC_Encrypt_Append(&AESctx,Plaintext,SIZE,
        		   tx,&outputLength);
           if (error_status == AES_SUCCESS) {
                   /* Do the Finalization */
                   error_status = AES_CBC_Encrypt_Finish(&AESctx, tx +
                                   SIZE, &outputLength);
           }
   }
 
   AESCBCctx_stt AESctxD;
   outputLength = 0;
     /* Set flag field to default value */
     AESctxD.mFlags = E_SK_DEFAULT; //AccHw_E_SK_DEFAULT
     AESctxD.mKeySize = AES_BLOCK;
     /* Set iv size field to IvLength*/
     AESctxD.mIvSize = IV_LENGTH;
   error_status = AES_CBC_Decrypt_Init(&AESctxD, pKeyAES,
   		  pInitVectAES );
     /* check for initialization errors */
     if (error_status == AES_SUCCESS) {
             /* Encrypt Data */
             error_status = AES_CBC_Decrypt_Append(&AESctxD,tx,SIZE,
            		 Plaintext,&outputLength);
             if (error_status == AES_SUCCESS) {
                     /* Do the Finalization */
                     error_status = AES_CBC_Decrypt_Finish(&AESctxD, Plaintext +
                                     SIZE, &outputLength);
             }
     }

I have tried this with b128 and b256 keys. The results are different from the inputs, but the decrypted text isn't the plain text again.

If I'm correct, the encrypted message should be

6f ad 39 3a e1 c9 8c 33 05 d4 03 91 a5 7d bc 66 83 32 66 37 79 ec 45 d3 1b 75 bd d8 cd f9 a6 81

but the output is different, namely it starts with 3d ed...

Any ideas?

8 REPLIES 8
Jocelyn RICARD
ST Employee

Hello,

I'm sorry for late answer, I didn't receive the notification.

Did you activate the CRC clock ?

I can't see that in your code extract.

Best regards

Jocelyn

fPucc.1
Associate II

Hello,

did you find any solution to the correct Encryption but the incorrect Decryption?

I am having the same issue.

Thank you for any help

Make sure to explicitly clear local/auto variable structures.

Y​ou have the same chip?

Show the test code?

Do other CRYP examples from CubeL4, perhaps EVAL board ones, work?​

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
fPucc.1
Associate II
  • I am using a custom board based on ST STM32F765NI and STM32CryptographicV3.0.0_CM7_IAR_otnsc.a: First official release of optimized STM32 Cryptographic Library for Cortex M7 with High speed optimization and the option No Size constraints is enabled.

It works fine in the Encryption AES CBC 128/192/256 (no padding) on 16 bytes as starting message. By using for comparison many public web pages, I am sure that it works fine but when I reverse the encryption it doesn't give me back the starting messages

int32_t STM32_AES_CBC_Decrypt(uint8_t* InputMessage,
                        uint32_t InputMessageLength,
                        uint8_t  *AES_Key,
                        uint8_t   AES_KeyLen,
                        uint8_t  *InitializationVector,
                        uint32_t  IvLength,
                        uint8_t  *OutputMessage,
                        uint32_t *OutputMessageLength){
   AESCBCctx_stt AESctx;
   uint32_t error_status = (uint32_t)AES_SUCCESS;
   int32_t outputLength = 0;
   
   /* Set flag field to default value */
   AESctx.mFlags = E_SK_DEFAULT;
 
  // Set key size to 16 (corresponding to AES-128) ; 24 -> 196; 32 -> 256
  AESctx.mKeySize = AES_KeyLen;
 
   /* Set iv size field to IvLength*/
   AESctx.mIvSize = (int32_t)IvLength;
 
   /* Initialize the operation, by passing the key. */
   error_status = AES_CBC_Decrypt_Init(&AESctx, AES_Key, InitializationVector );
 
   /* check for initialization errors */
   if (error_status == (uint32_t)AES_SUCCESS){
      /* Decrypt Data */
      error_status = AES_CBC_Decrypt_Append(&AESctx,
                                             InputMessage,
                                             InputMessageLength,
                                             OutputMessage,
                                             &outputLength);
      if (error_status == (uint32_t)AES_SUCCESS){
         /* Write the number of data written*/
         *OutputMessageLength = outputLength;
         /* Do the Finalization */
         error_status = AES_CBC_Decrypt_Finish(&AESctx, OutputMessage + *OutputMessageLength, &outputLength);
         /* Add data written to the information to be returned */
         *OutputMessageLength += outputLength;
      }
   }
 
   return (int32_t)error_status;
}

Ok, so not the HW implementation.

Is the clock for the CRC Peripheral enabled?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
fPucc.1
Associate II

I use the CRC in other parts of the code and this is the function to initialize it:

static void MX_CRC_Init(void)
{
 
  /* USER CODE BEGIN CRC_Init 0 */
 
  /* USER CODE END CRC_Init 0 */
 
  /* USER CODE BEGIN CRC_Init 1 */
 
  /* USER CODE END CRC_Init 1 */
  hcrc.Instance = CRC;
  hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;  //DEFAULT_POLYNOMIAL_ENABLE; 
  hcrc.Init.DefaultInitValueUse  = DEFAULT_INIT_VALUE_DISABLE;   //DEFAULT_INIT_VALUE_ENABLE;
  
  hcrc.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_NONE;
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
  hcrc.InputDataFormat              = CRC_INPUTDATA_FORMAT_BYTES;
  
  hcrc.Init.InitValue           = 0x0000;
  hcrc.Init.GeneratingPolynomial= 0x1021;
  hcrc.Init.CRCLength           = CRC_POLYLENGTH_16B;
  
  if (HAL_CRC_Init(&hcrc) != HAL_OK){
    Error_Handler();
  }
  /* USER CODE BEGIN CRC_Init 2 */
  
  /* USER CODE END CRC_Init 2 */
 
}

then, why if it correctly encrypts, does not correctly Decrypt?

I guess that if it uses the CRC HW for decrypting it also uses for Encryption.

Anyway thank you for your help

I've long complained about the use of the CRC unit to hardware lock the library to STM32 parts, but nobody listens..

Just enable the CRC clock, don't configure it into non-standard modes. The lock expects a challenge / response, and that will fail if its not ST's standard 32-bit polynomial, shift, etc.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
fPucc.1
Associate II

Thank you for your answer.

Unfortunately, I have also to use the CRC in a non-standard mode so I fixed it by switching it from non-standard to standard mode before using AES-256-noPadding functions and back to non-standard mode after that I used the library.

The only strange thing is that if I have to cypher a message, the CRC configuration is not relevant but I need the standard configuration only when I need to decipher the message.

Anyway,

thank you