drivers: crypto: Add support for STM32L4 AES accelerator
This patch completes the addition of support for the STM32L4 AES accelerator by introducing conditional handling for different STM32 AES HAL variants. Key changes include: - Created device tree bindings `st,stm32l4-aes` for STM32L4 AES - Replaced `copy_reverse_words` with `copy_words_adjust_endianness` to handle endianness conversion for different variants. Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
This commit is contained in:
parent
8f0de8455d
commit
ad431dcc23
3 changed files with 65 additions and 13 deletions
|
|
@ -67,27 +67,37 @@ typedef HAL_StatusTypeDef status_t;
|
|||
typedef status_t (*hal_cryp_aes_op_func_t)(CRYP_HandleTypeDef *hcryp, uint8_t *in_data,
|
||||
uint16_t size, uint8_t *out_data, uint32_t timeout);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
#define hal_ecb_encrypt_op HAL_CRYP_AESECB_Encrypt
|
||||
#define hal_ecb_decrypt_op HAL_CRYP_AESECB_Decrypt
|
||||
#define hal_cbc_encrypt_op HAL_CRYP_AESCBC_Encrypt
|
||||
#define hal_cbc_decrypt_op HAL_CRYP_AESCBC_Decrypt
|
||||
#define hal_ctr_encrypt_op HAL_CRYP_AESCTR_Encrypt
|
||||
#define hal_ctr_decrypt_op HAL_CRYP_AESCTR_Decrypt
|
||||
#else
|
||||
#define hal_ecb_encrypt_op hal_encrypt
|
||||
#define hal_ecb_decrypt_op hal_decrypt
|
||||
#define hal_cbc_encrypt_op hal_encrypt
|
||||
#define hal_cbc_decrypt_op hal_decrypt
|
||||
#define hal_ctr_encrypt_op hal_encrypt
|
||||
#define hal_ctr_decrypt_op hal_decrypt
|
||||
#endif
|
||||
|
||||
static int copy_reverse_words(uint8_t *dst_buf, int dst_len,
|
||||
const uint8_t *src_buf, int src_len)
|
||||
static int copy_words_adjust_endianness(uint8_t *dst_buf, int dst_len, const uint8_t *src_buf,
|
||||
int src_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((dst_len < src_len) || ((dst_len % 4) != 0)) {
|
||||
LOG_ERR("Buffer length error");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(dst_buf, src_buf, src_len);
|
||||
for (i = 0; i < dst_len; i += sizeof(uint32_t)) {
|
||||
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
for (int i = 0; i < dst_len; i += sizeof(uint32_t)) {
|
||||
sys_mem_swap(&dst_buf[i], sizeof(uint32_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -102,12 +112,19 @@ static int do_aes(struct cipher_ctx *ctx, hal_cryp_aes_op_func_t fn, uint8_t *in
|
|||
|
||||
k_sem_take(&data->device_sem, K_FOREVER);
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
/* Device is initialized from the configuration in the encryption/decryption function
|
||||
* called bellow.
|
||||
*/
|
||||
memcpy(&data->hcryp.Init, &session->config, sizeof(session->config));
|
||||
#else
|
||||
status = HAL_CRYP_SetConfig(&data->hcryp, &session->config);
|
||||
if (status != HAL_OK) {
|
||||
LOG_ERR("Configuration error");
|
||||
k_sem_give(&data->device_sem);
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = fn(&data->hcryp, in_buf, in_len, out_buf, HAL_MAX_DELAY);
|
||||
if (status != HAL_OK) {
|
||||
|
|
@ -121,6 +138,7 @@ static int do_aes(struct cipher_ctx *ctx, hal_cryp_aes_op_func_t fn, uint8_t *in
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
static status_t hal_encrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pPlainData, uint16_t Size,
|
||||
uint8_t *pCypherData, uint32_t Timeout)
|
||||
{
|
||||
|
|
@ -134,6 +152,7 @@ static status_t hal_decrypt(CRYP_HandleTypeDef *hcryp, uint8_t *pCypherData, uin
|
|||
return HAL_CRYP_Decrypt(hcryp, (uint32_t *)pCypherData, Size, (uint32_t *)pPlainData,
|
||||
Timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int crypto_stm32_ecb_encrypt(struct cipher_ctx *ctx,
|
||||
struct cipher_pkt *pkt)
|
||||
|
|
@ -186,7 +205,7 @@ static int crypto_stm32_cbc_encrypt(struct cipher_ctx *ctx,
|
|||
|
||||
struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
|
||||
|
||||
(void)copy_reverse_words((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
|
||||
(void)copy_words_adjust_endianness((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
|
||||
|
||||
session->config.pInitVect = vec;
|
||||
|
||||
|
|
@ -213,7 +232,7 @@ static int crypto_stm32_cbc_decrypt(struct cipher_ctx *ctx,
|
|||
|
||||
struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
|
||||
|
||||
(void)copy_reverse_words((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
|
||||
(void)copy_words_adjust_endianness((uint8_t *)vec, sizeof(vec), iv, BLOCK_LEN_BYTES);
|
||||
|
||||
session->config.pInitVect = vec;
|
||||
|
||||
|
|
@ -238,7 +257,7 @@ static int crypto_stm32_ctr_encrypt(struct cipher_ctx *ctx,
|
|||
|
||||
struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
|
||||
|
||||
if (copy_reverse_words((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
|
||||
if (copy_words_adjust_endianness((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -261,7 +280,7 @@ static int crypto_stm32_ctr_decrypt(struct cipher_ctx *ctx,
|
|||
|
||||
struct crypto_stm32_session *session = CRYPTO_STM32_SESSN(ctx);
|
||||
|
||||
if (copy_reverse_words((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
|
||||
if (copy_words_adjust_endianness((uint8_t *)ctr, sizeof(ctr), iv, ivlen) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
|
@ -305,8 +324,6 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
int ctx_idx, ret;
|
||||
struct crypto_stm32_session *session;
|
||||
|
||||
struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
|
||||
|
||||
if (ctx->flags & ~(CRYP_SUPPORT)) {
|
||||
LOG_ERR("Unsupported flag");
|
||||
return -EINVAL;
|
||||
|
|
@ -353,6 +370,9 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
session = &crypto_stm32_sessions[ctx_idx];
|
||||
memset(&session->config, 0, sizeof(session->config));
|
||||
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
struct crypto_stm32_data *data = CRYPTO_STM32_DATA(dev);
|
||||
|
||||
if (data->hcryp.State == HAL_CRYP_STATE_RESET) {
|
||||
if (HAL_CRYP_Init(&data->hcryp) != HAL_OK) {
|
||||
LOG_ERR("Initialization error");
|
||||
|
|
@ -360,6 +380,7 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
return -EIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (ctx->keylen) {
|
||||
case 16U:
|
||||
|
|
@ -378,15 +399,21 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
if (op_type == CRYPTO_CIPHER_OP_ENCRYPT) {
|
||||
switch (mode) {
|
||||
case CRYPTO_CIPHER_MODE_ECB:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_ECB;
|
||||
#endif
|
||||
ctx->ops.block_crypt_hndlr = crypto_stm32_ecb_encrypt;
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CBC:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_CBC;
|
||||
#endif
|
||||
ctx->ops.cbc_crypt_hndlr = crypto_stm32_cbc_encrypt;
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CTR:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_CTR;
|
||||
#endif
|
||||
ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_encrypt;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -395,15 +422,21 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
} else {
|
||||
switch (mode) {
|
||||
case CRYPTO_CIPHER_MODE_ECB:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_ECB;
|
||||
#endif
|
||||
ctx->ops.block_crypt_hndlr = crypto_stm32_ecb_decrypt;
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CBC:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_CBC;
|
||||
#endif
|
||||
ctx->ops.cbc_crypt_hndlr = crypto_stm32_cbc_decrypt;
|
||||
break;
|
||||
case CRYPTO_CIPHER_MODE_CTR:
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.Algorithm = CRYP_AES_CTR;
|
||||
#endif
|
||||
ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_decrypt;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -411,7 +444,7 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
ret = copy_reverse_words((uint8_t *)session->key, CRYPTO_STM32_AES_MAX_KEY_LEN,
|
||||
ret = copy_words_adjust_endianness((uint8_t *)session->key, CRYPTO_STM32_AES_MAX_KEY_LEN,
|
||||
ctx->key.bit_stream, ctx->keylen);
|
||||
if (ret != 0) {
|
||||
return -EIO;
|
||||
|
|
@ -419,7 +452,10 @@ static int crypto_stm32_session_setup(const struct device *dev,
|
|||
|
||||
session->config.pKey = session->key;
|
||||
session->config.DataType = CRYP_DATATYPE_8B;
|
||||
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
session->config.DataWidthUnit = CRYP_DATAWIDTHUNIT_BYTE;
|
||||
#endif
|
||||
|
||||
ctx->drv_sessn_state = session;
|
||||
ctx->device = dev;
|
||||
|
|
@ -448,12 +484,14 @@ static int crypto_stm32_session_free(const struct device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
/* Deinitialize and reset peripheral. */
|
||||
if (HAL_CRYP_DeInit(&data->hcryp) != HAL_OK) {
|
||||
LOG_ERR("Deinitialization error");
|
||||
k_sem_give(&data->session_sem);
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
|
||||
(void)reset_line_toggle_dt(&cfg->reset);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@
|
|||
#ifndef ZEPHYR_DRIVERS_CRYPTO_CRYPTO_STM32_PRIV_H_
|
||||
#define ZEPHYR_DRIVERS_CRYPTO_CRYPTO_STM32_PRIV_H_
|
||||
|
||||
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes)
|
||||
#define crypt_config_t CRYP_InitTypeDef
|
||||
#else
|
||||
#define crypt_config_t CRYP_ConfigTypeDef
|
||||
#endif
|
||||
|
||||
/* Maximum supported key length is 256 bits */
|
||||
#define CRYPTO_STM32_AES_MAX_KEY_LEN (256 / 8)
|
||||
|
||||
|
|
@ -23,7 +29,7 @@ struct crypto_stm32_data {
|
|||
};
|
||||
|
||||
struct crypto_stm32_session {
|
||||
CRYP_ConfigTypeDef config;
|
||||
crypt_config_t config;
|
||||
uint32_t key[CRYPTO_STM32_AES_MAX_KEY_LEN / sizeof(uint32_t)];
|
||||
bool in_use;
|
||||
};
|
||||
|
|
|
|||
8
dts/bindings/crypto/st,stm32l4-aes.yaml
Normal file
8
dts/bindings/crypto/st,stm32l4-aes.yaml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Copyright (c) 2024, Lucas Dietrich
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: STM32L4 AES Accelerator
|
||||
|
||||
compatible: "st,stm32l4-aes"
|
||||
|
||||
include: st,stm32-crypto-common.yaml
|
||||
Loading…
Reference in a new issue