From ad431dcc233903a007860d2e89ab43507402d571 Mon Sep 17 00:00:00 2001 From: Lucas Dietrich Date: Tue, 24 Sep 2024 22:40:56 +0200 Subject: [PATCH] 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 --- drivers/crypto/crypto_stm32.c | 62 ++++++++++++++++++++----- drivers/crypto/crypto_stm32_priv.h | 8 +++- dts/bindings/crypto/st,stm32l4-aes.yaml | 8 ++++ 3 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 dts/bindings/crypto/st,stm32l4-aes.yaml diff --git a/drivers/crypto/crypto_stm32.c b/drivers/crypto/crypto_stm32.c index 061b9775e92..3d833cdebb9 100644 --- a/drivers/crypto/crypto_stm32.c +++ b/drivers/crypto/crypto_stm32.c @@ -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); diff --git a/drivers/crypto/crypto_stm32_priv.h b/drivers/crypto/crypto_stm32_priv.h index ff9dade6a23..e74b33beb13 100644 --- a/drivers/crypto/crypto_stm32_priv.h +++ b/drivers/crypto/crypto_stm32_priv.h @@ -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; }; diff --git a/dts/bindings/crypto/st,stm32l4-aes.yaml b/dts/bindings/crypto/st,stm32l4-aes.yaml new file mode 100644 index 00000000000..e373530aab5 --- /dev/null +++ b/dts/bindings/crypto/st,stm32l4-aes.yaml @@ -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