Hi,
I need to use AES CBC 256 encryption/decryption on nrf52840 but since its cyrpto cell only supports AES 128, I tried using mbedtls to do AES 256 encryption. It works fine but if then I add
CONFIG_NRF_SECURITY=y CONFIG_MBEDTLS=y CONFIG_MBEDTLS_AES_C=y CONFIG_MBEDTLS_CIPHER_MODE_CBC=y CONFIG_ENTROPY_GENERATOR=y
#include <zephyr/kernel.h>
#include <mbedtls/aes.h>
#include <string.h>
#define AES_KEY_SIZE 32 // AES-256 requires 32 bytes (256 bits)
#define AES_BLOCK_SIZE 16
#define KEY_SIZE 256
static const uint8_t key[AES_KEY_SIZE] = {
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
};
static uint8_t iv[AES_BLOCK_SIZE] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};
// **PKCS#7 Padding**
static size_t pkcs7_pad(uint8_t *data, size_t data_len, size_t block_size) {
size_t pad_len = block_size - (data_len % block_size);
for (size_t i = 0; i < pad_len; i++) {
data[data_len + i] = (uint8_t)pad_len;
}
return data_len + pad_len;
}
// **PKCS#7 Unpadding**
static size_t pkcs7_unpad(uint8_t *data, size_t data_len) {
uint8_t pad_len = data[data_len - 1]; // Last byte gives padding size
if (pad_len > AES_BLOCK_SIZE || pad_len == 0) {
return data_len; // Invalid padding, return as-is
}
return data_len - pad_len;
}
// **AES-256-CBC Encryption**
static int aes_encrypt(const uint8_t *input, size_t input_len, uint8_t *output, size_t *output_len) {
mbedtls_aes_context aes;
uint8_t iv_enc[AES_BLOCK_SIZE];
memcpy(iv_enc, iv, AES_BLOCK_SIZE); // Use fresh IV
// **PKCS#7 Pad Input**
uint8_t padded_input[64]; // Adjust buffer size as needed
memcpy(padded_input, input, input_len);
*output_len = pkcs7_pad(padded_input, input_len, AES_BLOCK_SIZE);
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_enc(&aes, key, KEY_SIZE);
int ret = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_ENCRYPT, *output_len, iv_enc, padded_input, output);
mbedtls_aes_free(&aes);
return ret;
}
// **AES-256-CBC Decryption**
static int aes_decrypt(const uint8_t *input, size_t input_len, uint8_t *output, size_t *output_len) {
mbedtls_aes_context aes;
uint8_t iv_dec[AES_BLOCK_SIZE];
memcpy(iv_dec, iv, AES_BLOCK_SIZE); // Use fresh IV
mbedtls_aes_init(&aes);
mbedtls_aes_setkey_dec(&aes, key, KEY_SIZE);
int ret = mbedtls_aes_crypt_cbc(&aes, MBEDTLS_AES_DECRYPT, input_len, iv_dec, input, output);
mbedtls_aes_free(&aes);
// **PKCS#7 Unpad Output**
*output_len = pkcs7_unpad(output, input_len);
return ret;
}
// **Main Function**
void main(void) {
uint8_t plaintext[] = "Hello, AES-256-CBC!"; // 20 bytes
uint8_t encrypted[64] = {0};
uint8_t decrypted[64] = {0};
size_t enc_len, dec_len;
printf("Plain: %s\n", plaintext);
// Encrypt
if (aes_encrypt(plaintext, strlen((char *)plaintext), encrypted, &enc_len) != 0) {
printf("Encryption failed!\n");
return;
}
printf("Encrypted: ");
for (size_t i = 0; i < enc_len; i++) {
printf("%02x", encrypted[i]);
}
printf("\n");
// Decrypt
if (aes_decrypt(encrypted, enc_len, decrypted, &dec_len) != 0) {
printf("Decryption failed!\n");
return;
}
decrypted[dec_len] = '\0'; // Null-terminate string
printf("Decrypted: %s\n", decrypted);
}