Skip to content

Commit 1667ea8

Browse files
committed
drivers: crypto: stm32: h7: support AES GCM
Adds AES GCM support for: * H723XX * H725XX * H730XX, H730XXQ * H735XX Signed-off-by: Georgij Černyšiov <[email protected]>
1 parent 6678e29 commit 1667ea8

File tree

1 file changed

+131
-13
lines changed

1 file changed

+131
-13
lines changed

drivers/crypto/crypto_stm32.c

Lines changed: 131 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2020 Markus Fuchs <[email protected]>
3+
* Copyright (c) 2025 Georgij Cernysiov <[email protected]>
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -45,6 +46,12 @@ LOG_MODULE_REGISTER(crypto_stm32);
4546
#define STM32_CRYPTO_TYPEDEF AES_TypeDef
4647
#endif
4748

49+
#if defined(CONFIG_SOC_STM32H723XX) || defined(CONFIG_SOC_STM32H725XX) || \
50+
defined(CONFIG_SOC_STM32H730XX) || defined(CONFIG_SOC_STM32H730XXQ) || \
51+
defined(CONFIG_SOC_STM32H735XX)
52+
#define STM32_CRYPTO_GCM_CCM_SUPPORTED
53+
#endif
54+
4855
struct crypto_stm32_session crypto_stm32_sessions[CRYPTO_MAX_SESSION];
4956

5057
typedef HAL_StatusTypeDef status_t;
@@ -81,7 +88,11 @@ typedef status_t (*hal_cryp_aes_op_func_t)(CRYP_HandleTypeDef *hcryp, uint8_t *i
8188
#define hal_cbc_decrypt_op hal_decrypt
8289
#define hal_ctr_encrypt_op hal_encrypt
8390
#define hal_ctr_decrypt_op hal_decrypt
84-
#endif
91+
#ifdef STM32_CRYPTO_GCM_CCM_SUPPORTED
92+
#define hal_gcm_encrypt_op hal_encrypt
93+
#define hal_gcm_decrypt_op hal_decrypt
94+
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
95+
#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes) */
8596

8697
/* L4 HAL driver uses uint8_t pointers for input/output data while the generic HAL driver uses
8798
* uint32_t pointers.
@@ -325,6 +336,109 @@ static int crypto_stm32_ctr_decrypt(struct cipher_ctx *ctx,
325336
return ret;
326337
}
327338

339+
#ifdef STM32_CRYPTO_GCM_CCM_SUPPORTED
340+
static int crypto_stm32_gcm(struct cipher_ctx *ctx, hal_cryp_aes_op_func_t fn,
341+
struct cipher_aead_pkt *apkt, uint8_t *nonce)
342+
{
343+
struct crypto_stm32_session *const session = CRYPTO_STM32_SESSN(ctx);
344+
uint32_t iv[4] = {0};
345+
346+
if (ctx->mode_params.gcm_info.nonce_len != 12) {
347+
return -EINVAL;
348+
}
349+
350+
if (ctx->mode_params.gcm_info.tag_len != BLOCK_LEN_BYTES) {
351+
return -EINVAL;
352+
}
353+
354+
if (copy_words_adjust_endianness((uint8_t *)iv, sizeof(iv), nonce,
355+
ctx->mode_params.gcm_info.nonce_len) != 0) {
356+
return -EIO;
357+
}
358+
359+
iv[3] = 0x00000002U;
360+
361+
session->config.pInitVect = CAST_VEC(iv);
362+
363+
if (apkt->ad_len == 0) {
364+
session->config.Header = NULL;
365+
session->config.HeaderSize = 0;
366+
} else {
367+
session->config.Header = CAST_VEC(apkt->ad);
368+
session->config.HeaderSize = apkt->ad_len;
369+
session->config.HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_BYTE;
370+
}
371+
372+
return do_aes(ctx, fn, apkt->pkt->in_buf, apkt->pkt->in_len, apkt->pkt->out_buf);
373+
}
374+
375+
static int crypto_stm32_gcm_encrypt(struct cipher_ctx *ctx, struct cipher_aead_pkt *apkt,
376+
uint8_t *nonce)
377+
{
378+
struct crypto_stm32_data *const data = CRYPTO_STM32_DATA(ctx->device);
379+
int ret;
380+
381+
k_sem_take(&data->device_sem, K_FOREVER);
382+
383+
ret = crypto_stm32_gcm(ctx, hal_gcm_encrypt_op, apkt, nonce);
384+
if (ret < 0) {
385+
return ret;
386+
}
387+
388+
if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(&data->hcryp, CAST_VEC(apkt->tag),
389+
HAL_MAX_DELAY) != HAL_OK) {
390+
ret = -EIO;
391+
}
392+
393+
k_sem_give(&data->device_sem);
394+
395+
if (ret < 0) {
396+
apkt->pkt->out_len = 0;
397+
} else {
398+
apkt->pkt->out_len = apkt->pkt->in_len;
399+
}
400+
401+
return ret;
402+
}
403+
404+
static int crypto_stm32_gcm_decrypt(struct cipher_ctx *ctx, struct cipher_aead_pkt *apkt,
405+
uint8_t *nonce)
406+
{
407+
struct crypto_stm32_data *const data = CRYPTO_STM32_DATA(ctx->device);
408+
uint32_t tag[4] = {0};
409+
int ret;
410+
411+
k_sem_take(&data->device_sem, K_FOREVER);
412+
413+
ret = crypto_stm32_gcm(ctx, hal_gcm_decrypt_op, apkt, nonce);
414+
if (ret < 0) {
415+
k_sem_give(&data->device_sem);
416+
return ret;
417+
}
418+
419+
if (HAL_CRYPEx_AESGCM_GenerateAuthTAG(&data->hcryp, CAST_VEC(tag),
420+
HAL_MAX_DELAY) != HAL_OK) {
421+
ret = -EIO;
422+
}
423+
424+
k_sem_give(&data->device_sem);
425+
426+
if (ret < 0) {
427+
return ret;
428+
}
429+
430+
if (memcmp(tag, apkt->tag, ctx->mode_params.gcm_info.tag_len) != 0) {
431+
/* auth/tag verification fails */
432+
apkt->pkt->out_len = 0;
433+
ret = -EFAULT;
434+
} else {
435+
apkt->pkt->out_len = apkt->pkt->in_len;
436+
}
437+
438+
return ret;
439+
}
440+
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
441+
328442
static int crypto_stm32_get_unused_session_index(const struct device *dev)
329443
{
330444
int i;
@@ -365,21 +479,13 @@ static int crypto_stm32_session_setup(const struct device *dev,
365479
return -EINVAL;
366480
}
367481

368-
/* The CRYP peripheral supports the AES ECB, CBC, CTR, CCM and GCM
369-
* modes of operation, of which ECB, CBC, CTR and CCM are supported
370-
* through the crypto API. However, in CCM mode, although the STM32Cube
371-
* HAL driver follows the documentation (cf. RM0090, par. 23.3) by
372-
* padding incomplete input data blocks in software prior encryption,
373-
* incorrect authentication tags are returned for input data which is
374-
* not a multiple of 128 bits. Therefore, CCM mode is not supported by
375-
* this driver.
376-
*/
377-
if ((mode != CRYPTO_CIPHER_MODE_ECB) &&
378-
(mode != CRYPTO_CIPHER_MODE_CBC) &&
379-
(mode != CRYPTO_CIPHER_MODE_CTR)) {
482+
#ifndef STM32_CRYPTO_GCM_CCM_SUPPORTED
483+
if ((mode == CRYPTO_CIPHER_MODE_CCM) ||
484+
(mode == CRYPTO_CIPHER_MODE_GCM)) {
380485
LOG_ERR("Unsupported mode");
381486
return -EINVAL;
382487
}
488+
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
383489

384490
/* The STM32F4 CRYP peripheral supports key sizes of 128, 192 and 256
385491
* bits.
@@ -447,6 +553,12 @@ static int crypto_stm32_session_setup(const struct device *dev,
447553
#endif
448554
ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_encrypt;
449555
break;
556+
#ifdef STM32_CRYPTO_GCM_CCM_SUPPORTED
557+
case CRYPTO_CIPHER_MODE_GCM:
558+
session->config.Algorithm = CRYP_AES_GCM;
559+
ctx->ops.gcm_crypt_hndlr = crypto_stm32_gcm_encrypt;
560+
break;
561+
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
450562
default:
451563
return -EINVAL;
452564
}
@@ -470,6 +582,12 @@ static int crypto_stm32_session_setup(const struct device *dev,
470582
#endif
471583
ctx->ops.ctr_crypt_hndlr = crypto_stm32_ctr_decrypt;
472584
break;
585+
#ifdef STM32_CRYPTO_GCM_CCM_SUPPORTED
586+
case CRYPTO_CIPHER_MODE_GCM:
587+
session->config.Algorithm = CRYP_AES_GCM;
588+
ctx->ops.gcm_crypt_hndlr = crypto_stm32_gcm_decrypt;
589+
break;
590+
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
473591
default:
474592
return -EINVAL;
475593
}

0 commit comments

Comments
 (0)