@@ -91,6 +91,8 @@ typedef status_t (*hal_cryp_aes_op_func_t)(CRYP_HandleTypeDef *hcryp, uint8_t *i
91
91
#ifdef STM32_CRYPTO_GCM_CCM_SUPPORTED
92
92
#define hal_gcm_encrypt_op hal_encrypt
93
93
#define hal_gcm_decrypt_op hal_decrypt
94
+ #define hal_ccm_encrypt_op hal_encrypt
95
+ #define hal_ccm_decrypt_op hal_decrypt
94
96
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
95
97
#endif /* !DT_HAS_COMPAT_STATUS_OKAY(st_stm32l4_aes) */
96
98
@@ -437,6 +439,175 @@ static int crypto_stm32_gcm_decrypt(struct cipher_ctx *ctx, struct cipher_aead_p
437
439
438
440
return ret ;
439
441
}
442
+
443
+ static int crypto_stm32_ccm (struct cipher_ctx * ctx , hal_cryp_aes_op_func_t fn ,
444
+ struct cipher_aead_pkt * apkt , uint8_t * nonce , uint8_t * * b1 )
445
+ {
446
+ struct crypto_stm32_session * const session = CRYPTO_STM32_SESSN (ctx );
447
+ size_t b1_padded_len ;
448
+ uint8_t b0 [BLOCK_LEN_BYTES ] = {0 };
449
+ uint8_t q ;
450
+ int ret ;
451
+
452
+ /* tag length: 4, 6, 8, 10, 12, 14, 16 */
453
+ if ((ctx -> mode_params .ccm_info .tag_len < 4 ) ||
454
+ (ctx -> mode_params .ccm_info .tag_len > 16 ) ||
455
+ (ctx -> mode_params .ccm_info .tag_len % 2 ) != 0 ) {
456
+ return - EINVAL ;
457
+ }
458
+
459
+ /* nonce length [7, 13] */
460
+ if ((ctx -> mode_params .ccm_info .nonce_len < 7 ) ||
461
+ (ctx -> mode_params .ccm_info .nonce_len > 13 )) {
462
+ return - EINVAL ;
463
+ }
464
+
465
+ /* bytes left for payload length */
466
+ q = (15 - ctx -> mode_params .ccm_info .nonce_len );
467
+
468
+ /* check if payload length fits into q bytes */
469
+ if (apkt -> pkt -> in_len > BIT_MASK (8U * q )) {
470
+ return - EINVAL ;
471
+ }
472
+
473
+ if (apkt -> ad_len == 0 ) {
474
+ session -> config .Header = NULL ;
475
+ session -> config .HeaderSize = 0U ;
476
+ } else {
477
+ uint8_t header_len ;
478
+
479
+ if (apkt -> ad_len < 0xFF00U ) {
480
+ header_len = 2 ;
481
+ } else if (apkt -> ad_len < 0xFFFFFFFFU ) {
482
+ header_len = 6 ;
483
+ } else {
484
+ return - ENOTSUP ;
485
+ }
486
+
487
+ b1_padded_len =
488
+ (((apkt -> ad_len + header_len ) / BLOCK_LEN_BYTES ) + 1 ) * BLOCK_LEN_BYTES ;
489
+
490
+ * b1 = k_calloc (1 , b1_padded_len );
491
+ if (* b1 == NULL ) {
492
+ return - ENOMEM ;
493
+ }
494
+
495
+ if (header_len == 2 ) {
496
+ sys_put_be16 (apkt -> ad_len , * b1 );
497
+ } else {
498
+ * b1 [0 ] = 0xFFU ;
499
+ * b1 [1 ] = 0xFEU ;
500
+ sys_put_be32 (apkt -> ad_len , * b1 + 2 );
501
+ }
502
+
503
+ memcpy (* b1 + header_len , apkt -> ad , apkt -> ad_len );
504
+
505
+ /* blocks (B) associated to the Associated Data (A) */
506
+ session -> config .Header = CAST_VEC (* b1 );
507
+ session -> config .HeaderSize = b1_padded_len / sizeof (uint32_t );
508
+ session -> config .HeaderWidthUnit = CRYP_HEADERWIDTHUNIT_WORD ;
509
+
510
+ /* set AD presence flag */
511
+ b0 [0 ] = BIT (6 );
512
+ }
513
+
514
+ /* encode leftover flags */
515
+ b0 [0 ] |= ((ctx -> mode_params .gcm_info .tag_len - 2 ) / 2 ) << 3 ;
516
+ b0 [0 ] |= q - 1 ;
517
+
518
+ /* encode nonce */
519
+ memcpy (& b0 [1 ], nonce , ctx -> mode_params .ccm_info .nonce_len );
520
+
521
+ /* encode payload length */
522
+ for (unsigned int i = 0 ; i < q ; i ++ ) {
523
+ b0 [15 - i ] = (uint8_t )((apkt -> pkt -> in_len >> (8U * i )) & 0xFFU );
524
+ }
525
+
526
+ /* set B0 */
527
+ for (unsigned int i = 0 ; i < sizeof (b0 ); i += sizeof (uint32_t )) {
528
+ sys_mem_swap (& b0 [i ], sizeof (uint32_t ));
529
+ }
530
+
531
+ session -> config .B0 = CAST_VEC (b0 );
532
+
533
+ ret = do_aes (ctx , fn , apkt -> pkt -> in_buf , apkt -> pkt -> in_len , apkt -> pkt -> out_buf );
534
+ if (ret < 0 ) {
535
+ k_free (* b1 );
536
+ * b1 = NULL ;
537
+ }
538
+
539
+ return ret ;
540
+ }
541
+
542
+ static int crypto_stm32_ccm_encrypt (struct cipher_ctx * ctx , struct cipher_aead_pkt * apkt ,
543
+ uint8_t * nonce )
544
+ {
545
+ struct crypto_stm32_data * const data = CRYPTO_STM32_DATA (ctx -> device );
546
+ uint8_t * b1 = NULL ;
547
+ int ret ;
548
+
549
+ k_sem_take (& data -> device_sem , K_FOREVER );
550
+
551
+ ret = crypto_stm32_ccm (ctx , hal_ccm_encrypt_op , apkt , nonce , & b1 );
552
+ if (ret < 0 ) {
553
+ /* crypto_stm32_ccm deallocates b1 upon error */
554
+ k_sem_give (& data -> device_sem );
555
+ return ret ;
556
+ }
557
+
558
+ if (HAL_CRYPEx_AESCCM_GenerateAuthTAG (& data -> hcryp , CAST_VEC (apkt -> tag ),
559
+ HAL_MAX_DELAY ) != HAL_OK ) {
560
+ ret = - EIO ;
561
+ }
562
+
563
+ k_sem_give (& data -> device_sem );
564
+
565
+ k_free (b1 );
566
+
567
+ if (ret < 0 ) {
568
+ apkt -> pkt -> out_len = 0 ;
569
+ } else {
570
+ apkt -> pkt -> out_len = apkt -> pkt -> in_len ;
571
+ }
572
+
573
+ return ret ;
574
+ }
575
+
576
+ static int crypto_stm32_ccm_decrypt (struct cipher_ctx * ctx , struct cipher_aead_pkt * apkt ,
577
+ uint8_t * nonce )
578
+ {
579
+ struct crypto_stm32_data * const data = CRYPTO_STM32_DATA (ctx -> device );
580
+ uint8_t * b1 = NULL ;
581
+ uint32_t tag [BLOCK_LEN_WORDS ] = {0 };
582
+ int ret ;
583
+
584
+ k_sem_take (& data -> device_sem , K_FOREVER );
585
+
586
+ ret = crypto_stm32_ccm (ctx , hal_ccm_decrypt_op , apkt , nonce , & b1 );
587
+ if (ret < 0 ) {
588
+ k_sem_give (& data -> device_sem );
589
+ return ret ;
590
+ }
591
+
592
+ if (HAL_CRYPEx_AESCCM_GenerateAuthTAG (& data -> hcryp , CAST_VEC (tag ), HAL_MAX_DELAY ) !=
593
+ HAL_OK ) {
594
+ ret = - EIO ;
595
+ }
596
+
597
+ k_sem_give (& data -> device_sem );
598
+
599
+ k_free (b1 );
600
+
601
+ if (memcmp (tag , apkt -> tag , ctx -> mode_params .ccm_info .tag_len ) != 0 ) {
602
+ /* auth/tag verification fails */
603
+ apkt -> pkt -> out_len = 0 ;
604
+ ret = - EFAULT ;
605
+ } else {
606
+ apkt -> pkt -> out_len = apkt -> pkt -> in_len ;
607
+ }
608
+
609
+ return ret ;
610
+ }
440
611
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
441
612
442
613
static int crypto_stm32_get_unused_session_index (const struct device * dev )
@@ -558,6 +729,10 @@ static int crypto_stm32_session_setup(const struct device *dev,
558
729
session -> config .Algorithm = CRYP_AES_GCM ;
559
730
ctx -> ops .gcm_crypt_hndlr = crypto_stm32_gcm_encrypt ;
560
731
break ;
732
+ case CRYPTO_CIPHER_MODE_CCM :
733
+ session -> config .Algorithm = CRYP_AES_CCM ;
734
+ ctx -> ops .ccm_crypt_hndlr = crypto_stm32_ccm_encrypt ;
735
+ break ;
561
736
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
562
737
default :
563
738
return - EINVAL ;
@@ -587,6 +762,10 @@ static int crypto_stm32_session_setup(const struct device *dev,
587
762
session -> config .Algorithm = CRYP_AES_GCM ;
588
763
ctx -> ops .gcm_crypt_hndlr = crypto_stm32_gcm_decrypt ;
589
764
break ;
765
+ case CRYPTO_CIPHER_MODE_CCM :
766
+ session -> config .Algorithm = CRYP_AES_CCM ;
767
+ ctx -> ops .ccm_crypt_hndlr = crypto_stm32_ccm_decrypt ;
768
+ break ;
590
769
#endif /* STM32_CRYPTO_GCM_CCM_SUPPORTED */
591
770
default :
592
771
return - EINVAL ;
0 commit comments