cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 cryptografic AES CCM libraries giving wrong results

MSaez.1
Associate II

Hello everyone

I am trying to use the crypto library to perform an AES CCM encryption decryption. I am using an STM32F423CH MCU. The frames I am receiving are comming from other system and the authentication is always failing.

I implemted the validation scheme that appears in the NIST Special Publication 800-38C for CCM.

//FROM THE EXAMPLE IN nvlpubs.nist.gov
  const uint8_t key[] = {0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F};
  uint8_t nonce[] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
  uint8_t header[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
  uint8_t data[] = {0x20, 0x21, 0x22, 0x23};
  uint8_t outputData[40];
  uint8_t outputTag[8];
  uint8_t recoveredData[32];
  int32_t outputLength = 4;
  int32_t outputTagLength;
 
 
  volatile uint32_t error_status = AES_SUCCESS;
  AESCCMctx_stt AESCCMctx;
  AESCCMctx_stt* AESctx = &AESCCMctx;
 
	AESctx->mNonceSize = 7;
	AESctx->mKeySize = CRL_AES128_KEY;
	AESctx->mFlags = E_SK_DEFAULT;
	AESctx->mAssDataSize = 8;
	AESctx->mTagSize = 4;
	AESctx->mPayloadSize = 4;
	AESctx->pmTag = outputTag;
 
 
 
	error_status = AES_CCM_Encrypt_Init(AESctx, key, nonce);
 
	error_status = AES_CCM_Header_Append(AESctx, header, 8);
 
	error_status = AES_CCM_Encrypt_Append(AESctx, data, 4, outputData, &outputLength);
 
	error_status = AES_CCM_Encrypt_Finish(AESctx, outputData + 4, &outputTagLength);

I am using the SMALL implementation from the library. The expected output is:

MSG:0x71 0x62 0x01 0x5b

MAC: 0x4d 0xac 0x25 0x5d

But the result I am getting is:

MSG: 0x02 0x20 0x1d 0x49 

MAC: 0x49 0x37 0x36 0xab  

Though the decryption with the same libraries gives a positive result

AESctx->mNonceSize = 7;
	AESctx->mKeySize = CRL_AES128_KEY;
	AESctx->mFlags = E_SK_DEFAULT;
	AESctx->mAssDataSize = 8;
	AESctx->mTagSize = 4;
	AESctx->mPayloadSize = 4;
	AESctx->pmTag = outputData + 4;
 
	error_status = AES_CCM_Decrypt_Init(AESctx, key, nonce);
 
	error_status = AES_CCM_Header_Append(AESctx, header, 8);
 
	error_status = AES_CCM_Decrypt_Append(AESctx, outputData, 4, recoveredData, &outputLength);
 
 
	error_status = AES_CCM_Decrypt_Finish(AESctx, recoveredData, &outputLength);

Error_status = 1003 (SUCCESS) and the message match with the original.

Am I doing something wrong? Using the mbedtls libraries is working fine.

Thank you in advance for any support.

1 ACCEPTED SOLUTION

Accepted Solutions
MSaez.1
Associate II

First problem solved! I did not activate the CRC module before using the firmware version of the Cryptographic Library. Thanks to the video "Security Part3 - STM32 Security features - 30 - Crypto library lab"!

View solution in original post

3 REPLIES 3
MSaez.1
Associate II

Something is completly wrong somewhere. I have been doing steps in different location and going to the basics but it is still not working.

I activated the AES HW aceleration module to do the encryption/decryption there. I did not get CCM working but going even further I tried to replicate the example on the STM video tutorial on youtube:

Security Part3 - STM32 Security features - 25 - AES CRYPT lab (I cannot add the link directly).

This video tries to replicate one of the examples of the ECB encryption/decryption of the standard NIST Special Publication 800-38A. I am trying to replicate exactly the same example.

The function HAL_CRYP_Encrypt used in this video is not available in the version of the HAL drivers I am using (V.1.21.0) but i tried using the functions HAL_CRYP_AESECB_Encrypt and HAL_CRYPEx_AES. I even tried using the 32bits and the 8 bits configuration posibilities but none of them gave the expected result:

0693W00000QKKn7QAH.png 

CRYP_HandleTypeDef hcryp;
__ALIGN_BEGIN static const uint8_t pKeyAES[32] __ALIGN_END = {
                            0x60,0x3D,0xEB,0x10,0x15,0xCA,0x71,0xBE,0x2B,0x73,
                            0xAE,0xF0,0x85,0x7D,0x77,0x81,0x1F,0x35,0x2C,0x07,
                            0x3B,0x61,0x08,0xD7,0x2D,0x98,0x10,0xA3,0x09,0x14,
                            0xDF,0xF4};
 
CAN_HandleTypeDef hcan1;
 
SPI_HandleTypeDef hspi1;
 
TIM_HandleTypeDef htim1;
 
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;
 
osThreadId defaultTaskHandle;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
__ALIGN_BEGIN static const uint32_t pKeyAES32b[8] __ALIGN_END = {
                            0x603DEB10,0x15CA71BE,0x2B73AEF0,0x857D7781,0x1F352C07,
                            0x3B6108D7,0x2D9810A3,0x0914DFF4};
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM1_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_CAN1_Init(void);
static void MX_AES_Init(void);
void StartDefaultTask(void const * argument);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  *
  * @retval None
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  MX_CAN1_Init();
  MX_AES_Init();
  /* USER CODE BEGIN 2 */
//  Plaintext 6bc1bee22e409f96e93d7e117393172a
//  Input Block 6bc1bee22e409f96e93d7e117393172a
//  Output Block f3eed1bdb5d2a03c064b5a7e3db181f8
//  Ciphertext f3eed1bdb5d2a03c064b5a7e3db181f8
  uint32_t plaintext32b[4] = {0x6bc1bee2, 0x2e409f96, 0xe93d7e11, 0x7393172a};
  uint32_t encryptedData32b[4];
  uint32_t decryptedData32b[4];
 
  uint8_t plaintext[16] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
  uint8_t encryptedData[16];
  uint8_t decryptedData[16];
  volatile HAL_StatusTypeDef ret;
  ret = HAL_CRYPEx_AES(&hcryp, (uint8_t*)plaintext32b, 4, (uint8_t*)encryptedData32b, 1000);
 
  if (ret != HAL_OK)
	{
	  while(1);
	}
 
  ret = HAL_CRYP_AESECB_Encrypt(&hcryp, (uint8_t*)plaintext32b, 4, (uint8_t*)encryptedData32b, 1000);
  if (ret != HAL_OK)
  	{
  	  while(1);
  	}
  ret = HAL_CRYP_AESECB_Decrypt(&hcryp, (uint8_t*)encryptedData32b, 4, (uint8_t*)decryptedData32b, 1000);
  if (ret != HAL_OK)
  	{
  	  while(1);
  	}
  ret = HAL_CRYP_DeInit(&hcryp);
 
  hcryp.Init.pKey = (uint8_t *)pKeyAES;
 
   if (HAL_CRYP_Init(&hcryp) != HAL_OK)
   {
     _Error_Handler(__FILE__, __LINE__);
   }
 
 
  ret = HAL_CRYP_AESECB_Encrypt(&hcryp, plaintext, 16, encryptedData, 1000);
  if (ret != HAL_OK)
  	{
  	  while(1);
  	}
  ret = HAL_CRYP_AESECB_Decrypt(&hcryp, encryptedData, 16, decryptedData, 1000);
  if (ret != HAL_OK)
  	{
  	  while(1);
  	}
 
 
  /* USER CODE END 2 */
 
  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */
 
  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */
 
  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */
 
  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
 
  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */
 
  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
 
 
  /* Start scheduler */
  osKernelStart();
  
  /* We should never get here as control is now taken by the scheduler */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
 
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
 
  }
  /* USER CODE END 3 */
 
}

I am starting to think that something it mad in my MCU or in the drivers. Can please someone support!?

Best regards

PS: As commented before using the MBEDTLS SW I got it working straight forward. Regretfully this is too slow for my application. Any advice would be greatly wellcome.

MSaez.1
Associate II

First problem solved! I did not activate the CRC module before using the firmware version of the Cryptographic Library. Thanks to the video "Security Part3 - STM32 Security features - 30 - Crypto library lab"!

This is one of the gotchas with the libraries, this needs to be emphasized in the examples and README file.

And honestly a requirement that needs to be removed, and moved beyond.

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