1
1
/*
2
2
* Copyright (c) 2020 Markus Fuchs <[email protected] >
3
+ * Copyright (c) 2025 Georgij Cernysiov <[email protected] >
3
4
*
4
5
* SPDX-License-Identifier: Apache-2.0
5
6
*/
@@ -45,6 +46,12 @@ LOG_MODULE_REGISTER(crypto_stm32);
45
46
#define STM32_CRYPTO_TYPEDEF AES_TypeDef
46
47
#endif
47
48
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
+
48
55
struct crypto_stm32_session crypto_stm32_sessions [CRYPTO_MAX_SESSION ];
49
56
50
57
typedef HAL_StatusTypeDef status_t ;
@@ -81,7 +88,11 @@ typedef status_t (*hal_cryp_aes_op_func_t)(CRYP_HandleTypeDef *hcryp, uint8_t *i
81
88
#define hal_cbc_decrypt_op hal_decrypt
82
89
#define hal_ctr_encrypt_op hal_encrypt
83
90
#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) */
85
96
86
97
/* L4 HAL driver uses uint8_t pointers for input/output data while the generic HAL driver uses
87
98
* uint32_t pointers.
@@ -325,6 +336,109 @@ static int crypto_stm32_ctr_decrypt(struct cipher_ctx *ctx,
325
336
return ret ;
326
337
}
327
338
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
+
328
442
static int crypto_stm32_get_unused_session_index (const struct device * dev )
329
443
{
330
444
int i ;
@@ -365,21 +479,13 @@ static int crypto_stm32_session_setup(const struct device *dev,
365
479
return - EINVAL ;
366
480
}
367
481
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 )) {
380
485
LOG_ERR ("Unsupported mode" );
381
486
return - EINVAL ;
382
487
}
488
+ #endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
383
489
384
490
/* The STM32F4 CRYP peripheral supports key sizes of 128, 192 and 256
385
491
* bits.
@@ -447,6 +553,12 @@ static int crypto_stm32_session_setup(const struct device *dev,
447
553
#endif
448
554
ctx -> ops .ctr_crypt_hndlr = crypto_stm32_ctr_encrypt ;
449
555
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 */
450
562
default :
451
563
return - EINVAL ;
452
564
}
@@ -470,6 +582,12 @@ static int crypto_stm32_session_setup(const struct device *dev,
470
582
#endif
471
583
ctx -> ops .ctr_crypt_hndlr = crypto_stm32_ctr_decrypt ;
472
584
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 */
473
591
default :
474
592
return - EINVAL ;
475
593
}
0 commit comments