cancel
Showing results for 
Search instead for 
Did you mean: 

X-CUBE-CRYPTOLIB first computed SHA256 hash wrong

POliv
Associate III

Hello,

I would like to use the X-CUBE-CRYPTOLIB to calculate a SHA256 with a key, i'm using STM32CubeIDE 1.18.0 for an STM32u083 microcontroller, STM32CubeExpansion_Crypto_V4.2.0.

The issue I have is the first time I call cmox_mac_compute the wrong result is returned.

 

cmox_init_arg_t init_target = {CMOX_INIT_TARGET_AUTO, NULL};

if (cmox_initialize(&init_target) != CMOX_INIT_SUCCESS)
{
  Error_Handler();
}
  
uint8_t tResult[32] = {0};
uint8_t tMessage[63] = {153,234,98,104,200,115,43,208,16,24,124,106,63,66,15,0,0,0,0,0,250,191,113,33,0,0,0,0,0,0,0,53,231,216,222,211,203,112,30,58,145,125,101,150,57,215,149,108,50,229,247,80,239,35,157,119,19,121,218,120,231,50,70};
uint8_t tKey[32] = {173,182,187,187,244,184,224,88,49,224,82,119,184,125,189,202,255,179,154,153,213,5,120,138,162,120,25,250,40,96,170,122};

//Test 1
retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
						tMessage, sizeof(tMessage),  // Message to authenticate
						tKey,sizeof(tKey),          //HMAC Key to use
						NULL, 0,                   // Custom data
						tResult,              // Data buffer to receive generated authnetication tag
						sizeof(tResult),      // Expected authentication tag size
						&computed_size);

//Test 2
retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
						tMessage, sizeof(tMessage),  // Message to authenticate
						tKey,sizeof(tKey),          //HMAC Key to use
						NULL, 0,                   // Custom data
						tResult,              // Data buffer to receive generated authnetication tag
						sizeof(tResult),      // Expected authentication tag size
						&computed_size);

The test 1 result is

tResultuint8_t [32]0x20007c5c
tResult[0] uint8_t 112 'p'
tResult[1] uint8_t 217 'Ù'
tResult[2] uint8_t 29 '\035'
tResult[3] uint8_t 236 'ì'
tResult[4] uint8_t 15 '\017'
tResult[5] uint8_t 90 'Z'
tResult[6] uint8_t 181 'µ'
tResult[7] uint8_t 180 '´'
tResult[8] uint8_t 160 ' '
tResult[9] uint8_t 231 'ç'
tResult[10] uint8_t 12 '\f'
tResult[11] uint8_t 245 'õ'
tResult[12] uint8_t 103 'g'
tResult[13] uint8_t 108 'l'
tResult[14] uint8_t 174 '®'
tResult[15] uint8_t 103 'g'
tResult[16] uint8_t 134 '\206'
tResult[17] uint8_t 203 'Ë'
tResult[18] uint8_t 184 '¸'
tResult[19] uint8_t 142 '\216'
tResult[20] uint8_t 242 'ò'
tResult[21] uint8_t 100 'd'
tResult[22] uint8_t 32 ' '
tResult[23] uint8_t 47 '/'
tResult[24] uint8_t 122 'z'
tResult[25] uint8_t 0 '\0'
tResult[26] uint8_t 164 '¤'
tResult[27] uint8_t 176 '°'
tResult[28] uint8_t 160 ' '
tResult[29] uint8_t 179 '³'
tResult[30] uint8_t 55 '7'
tResult[31] uint8_t 114 'r'
 
and the test 2 result is
 
tResultuint8_t [32]0x20007c5c
tResult[0] uint8_t 18 '\022'
tResult[1] uint8_t 119 'w'
tResult[2] uint8_t 126 '~'
tResult[3] uint8_t 117 'u'
tResult[4] uint8_t 190 '¾'
tResult[5] uint8_t 209 'Ñ'
tResult[6] uint8_t 204 'Ì'
tResult[7] uint8_t 56 '8'
tResult[8] uint8_t 127 '\177'
tResult[9] uint8_t 227 'ã'
tResult[10] uint8_t 113 'q'
tResult[11] uint8_t 213 'Õ'
tResult[12] uint8_t 119 'w'
tResult[13] uint8_t 195 'Ã'
tResult[14] uint8_t 171 '«'
tResult[15] uint8_t 156 '\234'
tResult[16] uint8_t 223 'ß'
tResult[17] uint8_t 163 '£'
tResult[18] uint8_t 229 'å'
tResult[19] uint8_t 132 '\204'
tResult[20] uint8_t 118 'v'
tResult[21] uint8_t 137 '\211'
tResult[22] uint8_t 111 'o'
tResult[23] uint8_t 233 'é'
tResult[24] uint8_t 171 '«'
tResult[25] uint8_t 255 'ÿ'
tResult[26] uint8_t 100 'd'
tResult[27] uint8_t 209 'Ñ'
tResult[28] uint8_t 14 '\016'
tResult[29] uint8_t 233 'é'
tResult[30] uint8_t 204 'Ì'
tResult[31] uint8_t 218 'Ú'
 
The test 2 result is correct. Any idea what could be causing this?

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
POliv
Associate III

I have done further testing. I am using HAL_CRC_Calculate in a couple of places which seems to be causing the issue. If I change my test code to to do a CRC calculation, this reproduces the bug

  cmox_init_arg_t init_target = {CMOX_INIT_TARGET_AUTO, NULL};

    if (cmox_initialize(&init_target) != CMOX_INIT_SUCCESS)
    {
  	  Error_Handler();
    }
    uint32_t test[2] = {0,0};
    HAL_CRC_Calculate(&hcrc, (uint32_t*)test, 2);

    cmox_mac_retval_t retval;
    size_t computed_size;
    uint8_t tResult[32] = {0};
    uint8_t tResult2[32] = {0};
  	uint8_t tMessage[63] = {153,234,98,104,200,115,43,208,16,24,124,106,63,66,15,0,0,0,0,0,250,191,113,33,0,0,0,0,0,0,0,53,231,216,222,211,203,112,30,58,145,125,101,150,57,215,149,108,50,229,247,80,239,35,157,119,19,121,218,120,231,50,70};
  	uint8_t tKey[32] = {173,182,187,187,244,184,224,88,49,224,82,119,184,125,189,202,255,179,154,153,213,5,120,138,162,120,25,250,40,96,170,122};

	retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
							tMessage, sizeof(tMessage),  // Message to authenticate
							tKey,sizeof(tKey),          //HMAC Key to use
							NULL, 0,                   // Custom data
							tResult,              // Data buffer to receive generated authnetication tag
							sizeof(tResult),      // Expected authentication tag size
							&computed_size);

	retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
									tMessage, sizeof(tMessage),  // Message to authenticate
									tKey,sizeof(tKey),          //HMAC Key to use
									NULL, 0,                   // Custom data
									tResult2,              // Data buffer to receive generated authnetication tag
									sizeof(tResult2),      // Expected authentication tag size
									&computed_size);

If I add  __HAL_CRC_DR_RESET(&hcrc); 

After the HAL_CRC_CALCULATE but before the cmox_mac_compute it fixes the issue.

Why would that be?

 

View solution in original post

10 REPLIES 10
Pavel A.
Super User

Not checking computed_size first time?

 

POliv
Associate III

Computed size in both cases return 32, and retval in both cases is CMOX_MAC_SUCCESS.

POliv
Associate III

I have done further testing. I am using HAL_CRC_Calculate in a couple of places which seems to be causing the issue. If I change my test code to to do a CRC calculation, this reproduces the bug

  cmox_init_arg_t init_target = {CMOX_INIT_TARGET_AUTO, NULL};

    if (cmox_initialize(&init_target) != CMOX_INIT_SUCCESS)
    {
  	  Error_Handler();
    }
    uint32_t test[2] = {0,0};
    HAL_CRC_Calculate(&hcrc, (uint32_t*)test, 2);

    cmox_mac_retval_t retval;
    size_t computed_size;
    uint8_t tResult[32] = {0};
    uint8_t tResult2[32] = {0};
  	uint8_t tMessage[63] = {153,234,98,104,200,115,43,208,16,24,124,106,63,66,15,0,0,0,0,0,250,191,113,33,0,0,0,0,0,0,0,53,231,216,222,211,203,112,30,58,145,125,101,150,57,215,149,108,50,229,247,80,239,35,157,119,19,121,218,120,231,50,70};
  	uint8_t tKey[32] = {173,182,187,187,244,184,224,88,49,224,82,119,184,125,189,202,255,179,154,153,213,5,120,138,162,120,25,250,40,96,170,122};

	retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
							tMessage, sizeof(tMessage),  // Message to authenticate
							tKey,sizeof(tKey),          //HMAC Key to use
							NULL, 0,                   // Custom data
							tResult,              // Data buffer to receive generated authnetication tag
							sizeof(tResult),      // Expected authentication tag size
							&computed_size);

	retval = cmox_mac_compute(CMOX_HMAC_SHA256_ALGO,     // Use HMAC SHA256 algorithm
									tMessage, sizeof(tMessage),  // Message to authenticate
									tKey,sizeof(tKey),          //HMAC Key to use
									NULL, 0,                   // Custom data
									tResult2,              // Data buffer to receive generated authnetication tag
									sizeof(tResult2),      // Expected authentication tag size
									&computed_size);

If I add  __HAL_CRC_DR_RESET(&hcrc); 

After the HAL_CRC_CALCULATE but before the cmox_mac_compute it fixes the issue.

Why would that be?

 

Pavel A.
Super User

 I am using HAL_CRC_Calculate in a couple of places, 

Aha. The ST cryptolib reserves the CRC for something (proprietary locking?) so don't use the CRC in your code. Or use it with caution.

 

 

POliv
Associate III

Thank you Pavel.

Looking at the stm32u0xx_hal_crc.h the first thing that is called is __HAL_CRC_DR_RESET(hcrc);

If the cryptolib reserves the CRC for something, shouldn't any functions that use it do the same, so developers don't encounter unexpected behaviour when implementing these functions?

 

>>Why would that be?

The library is locked to STM32's by use of the CRC peripheral and obfuscation of initialization constants

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

Perhaps, but the CRC isn't something that can be shared or threaded.

If the STM32 you're using supports hashing in hardware, use it more directly, and not use the CMOX to add an additional level of abstraction.

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

I use the CRC peripheral to generate a CRC value of configuration data stored in flash, when reading configuration data from flash I recalculate the CRC to ensure that it is not corrupted.

When doing this, I wouldn't expect that another library would not return the correct results from an unrelated function because I have used a peripheral for the purpose it was intended.

I'm using a STM32U083 which unfortunately doesn't have hardware hashing, if it did I would have used it, same reason I am using the CRC peripheral for performance.

STM are clearly aware of the need to reset the CRC as previously mentioned because it is done when within HAL_CRC_Calculate, so just questioning why it is also not done in cmox_mac_compute, if it is required to ensure the correct behaviour of the function

Whilst this is very annoying, and has been complained about for more than a decade in various forms, this is what ST has decided to do. Expecting it to change is perhaps optimistic.

Adding additional overhead in the library punishes everyone, better your use of the CRC is scoped so it leaves it in a reset state. Some STM32 support multiple polynomials and shift directions, others just support their odd CRC32 mechanics. I'd prefer they remove this nonsense entirely.

Most of the docs at least mention to use of the CRC peripheral by the libraries, often more subtly than they should

The HW CRC isn't that efficient

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