2024-06-16 10:20 PM
Hi,
i am trying to develop a device which sends out bthome advertisements via ble (some sensor data).
So far so good, this part is working, but now i would also like to use bthome encryption.
So following this guide, i would need AES128 - CCM and MIC.
What i did so far is enabling AES and set it to be CCM and added a key (using CubeMX).
In the generated code i now have the hcrypt handle.
What i did afterwards -> I collected all the described data to create the nonce:
uint8_t nonce[13];
// MAC Address
nonce[0] = mac_address[0];
nonce[1] = mac_address[1];
nonce[2] = mac_address[2];
nonce[3] = mac_address[3];
nonce[4] = mac_address[4];
nonce[5] = mac_address[5];
// add bt_home_device_info
nonce[6] = bt_home_device_info;
// add UUID
nonce[7] = (uuid >> 8) & 0xff;
nonce[8] = uuid & 0xff;
// add counter
nonce[9] = (counter >> 24) & 0xff;
nonce[10] = (counter >> 16) & 0xff;
nonce[11] = (counter >> 8) & 0xff;
nonce[12] = counter & 0xff;
This is my nonce i would need for AES CCM.
Now sadly the example on bthome is a python one.. but they are using it as follows:
from Cryptodome.Cipher import AES
cipher = AES.new(key, AES.MODE_CCM, nonce=nonce, mac_len=4)
ciphertext, mic = cipher.encrypt_and_digest(data)
So basically a new cipher instance is created with the key and the nonce, telling the mac/mic len is 4 bytes.
Then encrypt the data (bthome service data) with this cipher.
My question is how i would achieve this using HAL_Cryp* library on a stm32wb55?
I looked for different examples and there are some for a wb55 but none for CCM as far as i can see.
-> Then i saw that there also is a third party software pack mbedtls which should make this a bit easier but apparently it is not available on stm32wb.
My current aes init is as cubemx generated it:
CRYP_HandleTypeDef hcryp1;
__ALIGN_BEGIN static const uint32_t pKeyAES1[4] __ALIGN_END = {
0xAAAAAAAA,0xBBBBBBBB,0xCCCCCCCC,0xDDDDDDDD};
__ALIGN_BEGIN static const uint32_t HeaderAES1[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000};
__ALIGN_BEGIN static const uint32_t B0AES1[4] __ALIGN_END = {
0x00000000,0x00000000,0x00000000,0x00000000};
/* AES1 init function */
void MX_AES1_Init(void)
{
/* USER CODE BEGIN AES1_Init 0 */
/* USER CODE END AES1_Init 0 */
/* USER CODE BEGIN AES1_Init 1 */
/* USER CODE END AES1_Init 1 */
hcryp1.Instance = AES1;
hcryp1.Init.DataType = CRYP_DATATYPE_8B;
hcryp1.Init.KeySize = CRYP_KEYSIZE_128B;
hcryp1.Init.pKey = (uint32_t *)pKeyAES1;
hcryp1.Init.Algorithm = CRYP_AES_CCM;
hcryp1.Init.Header = (uint32_t *)HeaderAES1;
hcryp1.Init.HeaderSize = 4;
hcryp1.Init.B0 = (uint32_t *)B0AES1;
hcryp1.Init.DataWidthUnit = CRYP_DATAWIDTHUNIT_WORD;
hcryp1.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ALWAYS;
if (HAL_CRYP_Init(&hcryp1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN AES1_Init 2 */
/* USER CODE END AES1_Init 2 */
}
My knowledge about crypto is quite limited so i also don't really know what i should use for B0 and HeaderAES1.
Maybe you know some wrapper library or sth. similar which i could use.