@@ -48,6 +48,11 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
48
48
#include "bootutil/mcuboot_uuid.h"
49
49
#endif /* MCUBOOT_UUID_VID || MCUBOOT_UUID_CID */
50
50
51
+ #if defined(MCUBOOT_DECOMPRESS_IMAGES )
52
+ #include <nrf_compress/implementation.h>
53
+ #include <compression/decompression.h>
54
+ #endif
55
+
51
56
#ifdef MCUBOOT_ENC_IMAGES
52
57
#include "bootutil/enc_key.h"
53
58
#endif
@@ -511,7 +516,7 @@ bootutil_img_validate(struct boot_loader_state *state,
511
516
)
512
517
{
513
518
#if (defined(EXPECTED_KEY_TLV ) && defined(MCUBOOT_HW_KEY )) || defined(MCUBOOT_HW_ROLLBACK_PROT ) \
514
- || defined(MCUBOOT_UUID_VID ) || defined(MCUBOOT_UUID_CID )
519
+ || defined(MCUBOOT_UUID_VID ) || defined(MCUBOOT_UUID_CID ) || defined( MCUBOOT_DECOMPRESS_IMAGES )
515
520
int image_index = (state == NULL ? 0 : BOOT_CURR_IMG (state ));
516
521
#endif
517
522
uint32_t off ;
@@ -567,6 +572,67 @@ bootutil_img_validate(struct boot_loader_state *state,
567
572
#endif
568
573
569
574
BOOT_LOG_DBG ("bootutil_img_validate: flash area %p" , fap );
575
+ #ifdef MCUBOOT_DECOMPRESS_IMAGES
576
+ /* If the image is compressed, the integrity of the image must also be validated */
577
+ if (MUST_DECOMPRESS (fap , image_index , hdr )) {
578
+ bool found_decompressed_size = false;
579
+ bool found_decompressed_sha = false;
580
+ bool found_decompressed_signature = false;
581
+
582
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_ANY , true);
583
+ if (rc ) {
584
+ goto out ;
585
+ }
586
+
587
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
588
+ rc = -1 ;
589
+ goto out ;
590
+ }
591
+
592
+ while (true) {
593
+ uint16_t expected_size = 0 ;
594
+ bool * found_flag = NULL ;
595
+
596
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
597
+ if (rc < 0 ) {
598
+ goto out ;
599
+ } else if (rc > 0 ) {
600
+ break ;
601
+ }
602
+
603
+ switch (type ) {
604
+ case IMAGE_TLV_DECOMP_SIZE :
605
+ expected_size = sizeof (size_t );
606
+ found_flag = & found_decompressed_size ;
607
+ break ;
608
+ case IMAGE_TLV_DECOMP_SHA :
609
+ expected_size = IMAGE_HASH_SIZE ;
610
+ found_flag = & found_decompressed_sha ;
611
+ break ;
612
+ case IMAGE_TLV_DECOMP_SIGNATURE :
613
+ found_flag = & found_decompressed_signature ;
614
+ break ;
615
+ default :
616
+ continue ;
617
+ };
618
+
619
+ if (type == IMAGE_TLV_DECOMP_SIGNATURE && !EXPECTED_SIG_LEN (len )) {
620
+ rc = -1 ;
621
+ goto out ;
622
+ } else if (type != IMAGE_TLV_DECOMP_SIGNATURE && len != expected_size ) {
623
+ rc = -1 ;
624
+ goto out ;
625
+ }
626
+
627
+ * found_flag = true;
628
+ }
629
+
630
+ rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature );
631
+ if (rc ) {
632
+ goto out ;
633
+ }
634
+ }
635
+ #endif
570
636
571
637
#if defined(EXPECTED_HASH_TLV ) && !defined(MCUBOOT_SIGN_PURE )
572
638
#if defined(MCUBOOT_SWAP_USING_OFFSET ) && defined(MCUBOOT_SERIAL_RECOVERY )
@@ -904,6 +970,161 @@ bootutil_img_validate(struct boot_loader_state *state,
904
970
}
905
971
#endif
906
972
973
+ #ifdef MCUBOOT_DECOMPRESS_IMAGES
974
+ /* Only after all previous verifications have passed, perform a dry-run of the decompression
975
+ * and ensure the image is valid
976
+ */
977
+ if (!rc && MUST_DECOMPRESS (fap , image_index , hdr )) {
978
+ image_hash_valid = 0 ;
979
+ FIH_SET (valid_signature , FIH_FAILURE );
980
+
981
+ rc = bootutil_img_hash_decompress (state , hdr , fap , tmp_buf , tmp_buf_sz ,
982
+ hash , seed , seed_len );
983
+ if (rc ) {
984
+ goto out ;
985
+ }
986
+
987
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_DECOMP_SHA , true);
988
+ if (rc ) {
989
+ goto out ;
990
+ }
991
+
992
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
993
+ rc = -1 ;
994
+ goto out ;
995
+ }
996
+
997
+ while (true) {
998
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
999
+ if (rc < 0 ) {
1000
+ goto out ;
1001
+ } else if (rc > 0 ) {
1002
+ break ;
1003
+ }
1004
+
1005
+ if (type == IMAGE_TLV_DECOMP_SHA ) {
1006
+ /* Verify the image hash. This must always be present. */
1007
+ if (len != sizeof (hash )) {
1008
+ rc = -1 ;
1009
+ goto out ;
1010
+ }
1011
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , sizeof (hash ));
1012
+ if (rc ) {
1013
+ goto out ;
1014
+ }
1015
+
1016
+ FIH_CALL (boot_fih_memequal , fih_rc , hash , buf , sizeof (hash ));
1017
+ if (FIH_NOT_EQ (fih_rc , FIH_SUCCESS )) {
1018
+ FIH_SET (fih_rc , FIH_FAILURE );
1019
+ goto out ;
1020
+ }
1021
+
1022
+ image_hash_valid = 1 ;
1023
+ }
1024
+ }
1025
+
1026
+ rc = !image_hash_valid ;
1027
+ if (rc ) {
1028
+ goto out ;
1029
+ }
1030
+
1031
+ #ifdef EXPECTED_SIG_TLV
1032
+ #ifdef EXPECTED_KEY_TLV
1033
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , EXPECTED_KEY_TLV , false);
1034
+ if (rc ) {
1035
+ goto out ;
1036
+ }
1037
+
1038
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
1039
+ rc = -1 ;
1040
+ goto out ;
1041
+ }
1042
+
1043
+ while (true) {
1044
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
1045
+ if (rc < 0 ) {
1046
+ goto out ;
1047
+ } else if (rc > 0 ) {
1048
+ break ;
1049
+ }
1050
+
1051
+ if (type == EXPECTED_KEY_TLV ) {
1052
+ /*
1053
+ * Determine which key we should be checking.
1054
+ */
1055
+ if (len > KEY_BUF_SIZE ) {
1056
+ rc = -1 ;
1057
+ goto out ;
1058
+ }
1059
+ #ifndef MCUBOOT_HW_KEY
1060
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , len );
1061
+ if (rc ) {
1062
+ goto out ;
1063
+ }
1064
+ key_id = bootutil_find_key (buf , len );
1065
+ #else
1066
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , key_buf , len );
1067
+ if (rc ) {
1068
+ goto out ;
1069
+ }
1070
+ key_id = bootutil_find_key (image_index , key_buf , len );
1071
+ #endif /* !MCUBOOT_HW_KEY */
1072
+ /*
1073
+ * The key may not be found, which is acceptable. There
1074
+ * can be multiple signatures, each preceded by a key.
1075
+ */
1076
+ }
1077
+ }
1078
+ #endif /* EXPECTED_KEY_TLV */
1079
+
1080
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_DECOMP_SIGNATURE , true);
1081
+ if (rc ) {
1082
+ goto out ;
1083
+ }
1084
+
1085
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
1086
+ rc = -1 ;
1087
+ goto out ;
1088
+ }
1089
+
1090
+ while (true) {
1091
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
1092
+ if (rc < 0 ) {
1093
+ goto out ;
1094
+ } else if (rc > 0 ) {
1095
+ rc = 0 ;
1096
+ break ;
1097
+ }
1098
+
1099
+ if (type == IMAGE_TLV_DECOMP_SIGNATURE ) {
1100
+ /* Ignore this signature if it is out of bounds. */
1101
+ if (key_id < 0 || key_id >= bootutil_key_cnt ) {
1102
+ key_id = -1 ;
1103
+ continue ;
1104
+ }
1105
+
1106
+ if (!EXPECTED_SIG_LEN (len ) || len > sizeof (buf )) {
1107
+ rc = -1 ;
1108
+ goto out ;
1109
+ }
1110
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , len );
1111
+ if (rc ) {
1112
+ goto out ;
1113
+ }
1114
+
1115
+ FIH_CALL (bootutil_verify_sig , valid_signature , hash , sizeof (hash ),
1116
+ buf , len , key_id );
1117
+ key_id = -1 ;
1118
+ }
1119
+ }
1120
+ #endif /* EXPECTED_SIG_TLV */
1121
+ }
1122
+ #endif
1123
+
1124
+ #ifdef EXPECTED_SIG_TLV
1125
+ FIH_SET (fih_rc , valid_signature );
1126
+ #endif
1127
+
907
1128
out :
908
1129
if (rc ) {
909
1130
FIH_SET (fih_rc , FIH_FAILURE );
0 commit comments