@@ -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 ;
@@ -564,6 +569,67 @@ bootutil_img_validate(struct boot_loader_state *state,
564
569
#endif
565
570
566
571
BOOT_LOG_DBG ("bootutil_img_validate: flash area %p" , fap );
572
+ #ifdef MCUBOOT_DECOMPRESS_IMAGES
573
+ /* If the image is compressed, the integrity of the image must also be validated */
574
+ if (MUST_DECOMPRESS (fap , image_index , hdr )) {
575
+ bool found_decompressed_size = false;
576
+ bool found_decompressed_sha = false;
577
+ bool found_decompressed_signature = false;
578
+
579
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_ANY , true);
580
+ if (rc ) {
581
+ goto out ;
582
+ }
583
+
584
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
585
+ rc = -1 ;
586
+ goto out ;
587
+ }
588
+
589
+ while (true) {
590
+ uint16_t expected_size = 0 ;
591
+ bool * found_flag = NULL ;
592
+
593
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
594
+ if (rc < 0 ) {
595
+ goto out ;
596
+ } else if (rc > 0 ) {
597
+ break ;
598
+ }
599
+
600
+ switch (type ) {
601
+ case IMAGE_TLV_DECOMP_SIZE :
602
+ expected_size = sizeof (size_t );
603
+ found_flag = & found_decompressed_size ;
604
+ break ;
605
+ case IMAGE_TLV_DECOMP_SHA :
606
+ expected_size = IMAGE_HASH_SIZE ;
607
+ found_flag = & found_decompressed_sha ;
608
+ break ;
609
+ case IMAGE_TLV_DECOMP_SIGNATURE :
610
+ found_flag = & found_decompressed_signature ;
611
+ break ;
612
+ default :
613
+ continue ;
614
+ };
615
+
616
+ if (type == IMAGE_TLV_DECOMP_SIGNATURE && !EXPECTED_SIG_LEN (len )) {
617
+ rc = -1 ;
618
+ goto out ;
619
+ } else if (type != IMAGE_TLV_DECOMP_SIGNATURE && len != expected_size ) {
620
+ rc = -1 ;
621
+ goto out ;
622
+ }
623
+
624
+ * found_flag = true;
625
+ }
626
+
627
+ rc = (!found_decompressed_size || !found_decompressed_sha || !found_decompressed_signature );
628
+ if (rc ) {
629
+ goto out ;
630
+ }
631
+ }
632
+ #endif
567
633
568
634
#if defined(EXPECTED_HASH_TLV ) && !defined(MCUBOOT_SIGN_PURE )
569
635
#if defined(MCUBOOT_SWAP_USING_OFFSET ) && defined(MCUBOOT_SERIAL_RECOVERY )
@@ -883,6 +949,161 @@ bootutil_img_validate(struct boot_loader_state *state,
883
949
}
884
950
#endif
885
951
952
+ #ifdef MCUBOOT_DECOMPRESS_IMAGES
953
+ /* Only after all previous verifications have passed, perform a dry-run of the decompression
954
+ * and ensure the image is valid
955
+ */
956
+ if (!rc && MUST_DECOMPRESS (fap , image_index , hdr )) {
957
+ image_hash_valid = 0 ;
958
+ FIH_SET (valid_signature , FIH_FAILURE );
959
+
960
+ rc = bootutil_img_hash_decompress (state , hdr , fap , tmp_buf , tmp_buf_sz ,
961
+ hash , seed , seed_len );
962
+ if (rc ) {
963
+ goto out ;
964
+ }
965
+
966
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_DECOMP_SHA , true);
967
+ if (rc ) {
968
+ goto out ;
969
+ }
970
+
971
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
972
+ rc = -1 ;
973
+ goto out ;
974
+ }
975
+
976
+ while (true) {
977
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
978
+ if (rc < 0 ) {
979
+ goto out ;
980
+ } else if (rc > 0 ) {
981
+ break ;
982
+ }
983
+
984
+ if (type == IMAGE_TLV_DECOMP_SHA ) {
985
+ /* Verify the image hash. This must always be present. */
986
+ if (len != sizeof (hash )) {
987
+ rc = -1 ;
988
+ goto out ;
989
+ }
990
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , sizeof (hash ));
991
+ if (rc ) {
992
+ goto out ;
993
+ }
994
+
995
+ FIH_CALL (boot_fih_memequal , fih_rc , hash , buf , sizeof (hash ));
996
+ if (FIH_NOT_EQ (fih_rc , FIH_SUCCESS )) {
997
+ FIH_SET (fih_rc , FIH_FAILURE );
998
+ goto out ;
999
+ }
1000
+
1001
+ image_hash_valid = 1 ;
1002
+ }
1003
+ }
1004
+
1005
+ rc = !image_hash_valid ;
1006
+ if (rc ) {
1007
+ goto out ;
1008
+ }
1009
+
1010
+ #ifdef EXPECTED_SIG_TLV
1011
+ #ifdef EXPECTED_KEY_TLV
1012
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , EXPECTED_KEY_TLV , false);
1013
+ if (rc ) {
1014
+ goto out ;
1015
+ }
1016
+
1017
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
1018
+ rc = -1 ;
1019
+ goto out ;
1020
+ }
1021
+
1022
+ while (true) {
1023
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
1024
+ if (rc < 0 ) {
1025
+ goto out ;
1026
+ } else if (rc > 0 ) {
1027
+ break ;
1028
+ }
1029
+
1030
+ if (type == EXPECTED_KEY_TLV ) {
1031
+ /*
1032
+ * Determine which key we should be checking.
1033
+ */
1034
+ if (len > KEY_BUF_SIZE ) {
1035
+ rc = -1 ;
1036
+ goto out ;
1037
+ }
1038
+ #ifndef MCUBOOT_HW_KEY
1039
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , len );
1040
+ if (rc ) {
1041
+ goto out ;
1042
+ }
1043
+ key_id = bootutil_find_key (buf , len );
1044
+ #else
1045
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , key_buf , len );
1046
+ if (rc ) {
1047
+ goto out ;
1048
+ }
1049
+ key_id = bootutil_find_key (image_index , key_buf , len );
1050
+ #endif /* !MCUBOOT_HW_KEY */
1051
+ /*
1052
+ * The key may not be found, which is acceptable. There
1053
+ * can be multiple signatures, each preceded by a key.
1054
+ */
1055
+ }
1056
+ }
1057
+ #endif /* EXPECTED_KEY_TLV */
1058
+
1059
+ rc = bootutil_tlv_iter_begin (& it , hdr , fap , IMAGE_TLV_DECOMP_SIGNATURE , true);
1060
+ if (rc ) {
1061
+ goto out ;
1062
+ }
1063
+
1064
+ if (it .tlv_end > bootutil_max_image_size (state , fap )) {
1065
+ rc = -1 ;
1066
+ goto out ;
1067
+ }
1068
+
1069
+ while (true) {
1070
+ rc = bootutil_tlv_iter_next (& it , & off , & len , & type );
1071
+ if (rc < 0 ) {
1072
+ goto out ;
1073
+ } else if (rc > 0 ) {
1074
+ rc = 0 ;
1075
+ break ;
1076
+ }
1077
+
1078
+ if (type == IMAGE_TLV_DECOMP_SIGNATURE ) {
1079
+ /* Ignore this signature if it is out of bounds. */
1080
+ if (key_id < 0 || key_id >= bootutil_key_cnt ) {
1081
+ key_id = -1 ;
1082
+ continue ;
1083
+ }
1084
+
1085
+ if (!EXPECTED_SIG_LEN (len ) || len > sizeof (buf )) {
1086
+ rc = -1 ;
1087
+ goto out ;
1088
+ }
1089
+ rc = LOAD_IMAGE_DATA (hdr , fap , off , buf , len );
1090
+ if (rc ) {
1091
+ goto out ;
1092
+ }
1093
+
1094
+ FIH_CALL (bootutil_verify_sig , valid_signature , hash , sizeof (hash ),
1095
+ buf , len , key_id );
1096
+ key_id = -1 ;
1097
+ }
1098
+ }
1099
+ #endif /* EXPECTED_SIG_TLV */
1100
+ }
1101
+ #endif
1102
+
1103
+ #ifdef EXPECTED_SIG_TLV
1104
+ FIH_SET (fih_rc , valid_signature );
1105
+ #endif
1106
+
886
1107
out :
887
1108
if (rc ) {
888
1109
FIH_SET (fih_rc , FIH_FAILURE );
0 commit comments