24
24
* Modifications are Copyright (c) 2019-2024 Arm Limited.
25
25
*/
26
26
27
+ #include <assert.h>
27
28
#include <stddef.h>
28
29
#include <stdbool.h>
29
30
#include <bootutil/sign_key.h>
@@ -533,14 +534,17 @@ int boot_retrieve_public_key_hash(uint8_t image_index,
533
534
(uint32_t * )key_hash_size );
534
535
}
535
536
#elif defined(MCUBOOT_BUILTIN_KEY )
537
+ /* Maximum number of keys per image */
538
+ #define MAX_KEYS_PER_IMAGE MCUBOOT_ROTPK_MAX_KEYS_PER_IMAGE
539
+
536
540
/**
537
541
* @note When using builtin keys the signature verification happens based on key IDs.
538
542
* During verification MCUboot feeds the image index as a key ID and it is the
539
543
* underlying crypto library's responsibility to do a mapping (if required)
540
544
* between the image indexes and the builtin key IDs. Therefore it only allows
541
- * as many IDs as there are images.
545
+ * as many IDs as there are images times number of keys per image .
542
546
*/
543
- const int bootutil_key_cnt = MCUBOOT_IMAGE_NUMBER ;
547
+ const int bootutil_key_cnt = ( MCUBOOT_IMAGE_NUMBER * MAX_KEYS_PER_IMAGE ) ;
544
548
545
549
/**
546
550
* @brief Loader function to retrieve the Root of Trust Public Key
@@ -570,10 +574,11 @@ static enum tfm_plat_err_t tfm_plat_get_bl2_rotpk(const void *ctx,
570
574
{
571
575
enum tfm_plat_err_t err ;
572
576
const tfm_plat_builtin_key_descriptor_t * descriptor = (const tfm_plat_builtin_key_descriptor_t * )ctx ;
573
- /* ToDo: sort out the mapping between Key IDs and image indexes at runtime */
574
- uint32_t image_idx = descriptor -> key_id - 1 ;
575
577
576
- err = tfm_plat_otp_read (PLAT_OTP_ID_BL2_ROTPK_0 + image_idx , buf_len , buf );
578
+ assert (descriptor -> key_id >= 0 );
579
+
580
+ uint32_t otp_id = PLAT_OTP_ID_BL2_ROTPK_0 + descriptor -> key_id ;
581
+ err = tfm_plat_otp_read (otp_id , buf_len , buf );
577
582
if (err != TFM_PLAT_ERR_SUCCESS ) {
578
583
return err ;
579
584
}
@@ -583,7 +588,7 @@ static enum tfm_plat_err_t tfm_plat_get_bl2_rotpk(const void *ctx,
583
588
* encoding of the key (RSA) or alignment requirements of the stored key
584
589
* material, which in OTP must be 4-bytes aligned
585
590
*/
586
- err = tfm_plat_otp_get_size (PLAT_OTP_ID_BL2_ROTPK_0 + image_idx , key_len );
591
+ err = tfm_plat_otp_get_size (otp_id , key_len );
587
592
if (err != TFM_PLAT_ERR_SUCCESS ) {
588
593
return err ;
589
594
}
@@ -625,67 +630,119 @@ static enum tfm_plat_err_t tfm_plat_get_bl2_rotpk(const void *ctx,
625
630
return TFM_PLAT_ERR_SUCCESS ;
626
631
}
627
632
633
+ typedef struct {
634
+ uint32_t key_id [MAX_KEYS_PER_IMAGE ]; /*!< Key id of built in keys */
635
+ }image_key_id_mapping_t ;
636
+
637
+ /* Platform specific image to key id (otp id offset) map */
638
+ static const image_key_id_mapping_t tfm_image_key_map [] = {
639
+ {
640
+ /* Image 0: Only one key is provided and required */
641
+ .key_id = { TFM_S_KEY_ID },
642
+ },
643
+ {
644
+ /* Image 1: Only one key is provided and required */
645
+ .key_id = { TFM_NS_KEY_ID },
646
+ },
647
+ #if (MCUBOOT_IMAGE_NUMBER > 2 )
648
+ {
649
+ /* Image 2: Only one key is provided and required */
650
+ .key_id = { TFM_S_KEY_ID_3 },
651
+ },
652
+ #endif /* MCUBOOT_IMAGE_NUMBER > 2 */
653
+ #if (MCUBOOT_IMAGE_NUMBER > 3 )
654
+ {
655
+ /* Image 3: Only one key is provided and required */
656
+ .key_id = { TFM_S_KEY_ID_4 },
657
+ },
658
+ #endif /* MCUBOOT_IMAGE_NUMBER > 3 */
659
+ };
660
+
661
+ static int get_key_id (uint8_t img_idx , uint8_t key_idx )
662
+ {
663
+ assert (img_idx < MCUBOOT_IMAGE_NUMBER );
664
+ assert (key_idx < MAX_KEYS_PER_IMAGE );
665
+ return tfm_image_key_map [img_idx ].key_id [key_idx ];
666
+ }
667
+
628
668
/* The policy table is built dynamically at runtime to allow for an arbitrary
629
669
* number of MCUBOOT_IMAGE_NUMBER entries, without hardcoding at build time
630
670
*/
631
671
size_t tfm_plat_builtin_key_get_policy_table_ptr (const tfm_plat_builtin_key_policy_t * policy_ptr [])
632
672
{
633
- #if defined(MCUBOOT_BUILTIN_KEY )
634
- static tfm_plat_builtin_key_policy_t policy_table [MCUBOOT_IMAGE_NUMBER ];
673
+ static tfm_plat_builtin_key_policy_t policy_table [MCUBOOT_IMAGE_NUMBER ][MAX_KEYS_PER_IMAGE ];
635
674
static bool policy_table_is_initalized = false;
636
675
637
676
if (!policy_table_is_initalized ) {
638
- for (uint32_t idx = 0 ; idx < MCUBOOT_IMAGE_NUMBER ; idx ++ ) {
639
- tfm_plat_builtin_key_policy_t policy = {
640
- .key_id = idx + 1 , /* ToDo: Relationship between key_id and image_idx is simply hardcoded */
641
- .per_user_policy = 0 ,
642
- .usage = PSA_KEY_USAGE_VERIFY_HASH ,
643
- };
644
-
645
- policy_table [idx ] = policy ;
646
- }
677
+ for (uint32_t i = 0 ; i < MCUBOOT_IMAGE_NUMBER ; i ++ ) {
678
+ for (uint32_t j = 0 ; j < MAX_KEYS_PER_IMAGE ; j ++ ) {
679
+ tfm_plat_builtin_key_policy_t policy = {
680
+ .per_user_policy = 0 ,
681
+ .usage = PSA_KEY_USAGE_VERIFY_HASH ,
682
+ };
647
683
684
+ policy .key_id = get_key_id (i ,j );
685
+ policy_table [i ][j ] = policy ;
686
+ }
687
+ }
648
688
policy_table_is_initalized = true;
649
689
}
650
690
651
- * policy_ptr = & policy_table [0 ];
652
- return MCUBOOT_IMAGE_NUMBER ;
653
- #else
654
- * policy_ptr = NULL ;
655
- return 0 ;
656
- #endif
691
+ * policy_ptr = & policy_table [0 ][0 ];
692
+ return MCUBOOT_IMAGE_NUMBER * MAX_KEYS_PER_IMAGE ;
693
+
657
694
}
658
695
659
696
/* The descriptor table is built dynamically at runtime to allow for an arbitrary
660
697
* number of MCUBOOT_IMAGE_NUMBER entries, without hardcoding at build time
661
698
*/
662
699
size_t tfm_plat_builtin_key_get_desc_table_ptr (const tfm_plat_builtin_key_descriptor_t * desc_ptr [])
663
700
{
664
- #if defined(MCUBOOT_BUILTIN_KEY )
665
- static tfm_plat_builtin_key_descriptor_t descriptor_table [MCUBOOT_IMAGE_NUMBER ];
701
+ static tfm_plat_builtin_key_descriptor_t descriptor_table [MCUBOOT_IMAGE_NUMBER ][MAX_KEYS_PER_IMAGE ];
666
702
static bool descriptor_table_is_initalized = false;
667
703
668
704
if (!descriptor_table_is_initalized ) {
669
- for (uint32_t idx = 0 ; idx < MCUBOOT_IMAGE_NUMBER ; idx ++ ) {
670
- tfm_plat_builtin_key_descriptor_t descriptor = {
671
- .key_id = idx + 1 , /* ToDo: Relationship between key_id and image_idx is simply hardcoded */
672
- .slot_number = 0 , /* Unused */
673
- .lifetime = PSA_KEY_LIFETIME_PERSISTENT ,
674
- .loader_key_func = tfm_plat_get_bl2_rotpk ,
675
- .loader_key_ctx = & descriptor_table [idx ],
676
- };
677
-
678
- descriptor_table [idx ] = descriptor ;
705
+ for (uint32_t i = 0 ; i < MCUBOOT_IMAGE_NUMBER ; i ++ ) {
706
+ for (uint32_t j = 0 ; j < MAX_KEYS_PER_IMAGE ; j ++ ) {
707
+ tfm_plat_builtin_key_descriptor_t descriptor = {
708
+ .slot_number = 0 , /* Unused */
709
+ .lifetime = PSA_KEY_LIFETIME_PERSISTENT ,
710
+ .loader_key_func = tfm_plat_get_bl2_rotpk ,
711
+ .loader_key_ctx = & descriptor_table [i ][j ],
712
+ };
713
+ descriptor .key_id = get_key_id (i ,j );
714
+ descriptor_table [i ][j ] = descriptor ;
715
+ }
679
716
}
680
717
681
718
descriptor_table_is_initalized = true;
682
719
}
683
720
684
- * desc_ptr = & descriptor_table [0 ];
685
- return MCUBOOT_IMAGE_NUMBER ;
686
- #else
721
+ * desc_ptr = & descriptor_table [0 ][0 ];
722
+ return MCUBOOT_IMAGE_NUMBER * MAX_KEYS_PER_IMAGE ;
723
+ }
724
+
725
+ int boot_verify_key_id_for_image (uint8_t image_index , int32_t key_id )
726
+ {
727
+ for (int i = 0 ; i < MAX_KEYS_PER_IMAGE ; i ++ ) {
728
+ if (key_id == get_key_id (image_index , i )) {
729
+ return 0 ;
730
+ }
731
+ }
732
+ /* If the key id is not found in the image key id mapping, return -1 */
733
+ return -1 ;
734
+ }
735
+
736
+ #else /* MCUBOOT_BUILTIN_KEY */
737
+ size_t tfm_plat_builtin_key_get_policy_table_ptr (const tfm_plat_builtin_key_policy_t * policy_ptr [])
738
+ {
739
+ * policy_ptr = NULL ;
740
+ return 0 ;
741
+ }
742
+
743
+ size_t tfm_plat_builtin_key_get_desc_table_ptr (const tfm_plat_builtin_key_descriptor_t * desc_ptr [])
744
+ {
687
745
* desc_ptr = NULL ;
688
746
return 0 ;
689
- #endif
690
747
}
691
- #endif /* MCUBOOT_USE_PSA_CRYPTO */
748
+ #endif /* MCUBOOT_BUILTIN_KEY */
0 commit comments