@@ -1026,8 +1026,7 @@ void repack(Utf8CStr src_img, Utf8CStr out_img, bool skip_comp) {
10261026 vbmeta->flags = __builtin_bswap32 (3 );
10271027 }
10281028
1029- // Sync hash descriptor image_size with the new AOSP portion size.
1030- // Without this, some bootloaders (e.g. Motorola) reject images.
1029+ // Patch hash descriptor
10311030 for (auto &desc : vbmeta->descriptors ()) {
10321031 if (__builtin_bswap64 (desc.tag ) != AVB_DESCRIPTOR_TAG_HASH)
10331032 continue ;
@@ -1046,7 +1045,56 @@ void repack(Utf8CStr src_img, Utf8CStr out_img, bool skip_comp) {
10461045 }
10471046
10481047 auto &hd = reinterpret_cast <AvbHashDescriptor &>(desc);
1048+
1049+ // Update image_size
10491050 hd.image_size = __builtin_bswap64 (aosp_img_size);
1051+
1052+ // Recompute hash
1053+ auto *algo = reinterpret_cast <char *>(hd.hash_algorithm );
1054+ bool is_sha1 = memcmp (hd.hash_algorithm , " sha1" , 5 ) == 0 ;
1055+ bool is_sha256 = memcmp (hd.hash_algorithm , " sha256" , 7 ) == 0 ;
1056+
1057+ uint32_t name_len = __builtin_bswap32 (hd.partition_name_len );
1058+ uint32_t salt_len = __builtin_bswap32 (hd.salt_len );
1059+ uint32_t digest_len = __builtin_bswap32 (hd.digest_len );
1060+
1061+ // Get pointers to the (flexibly sized) payloads, checking each against desc_end
1062+ uint8_t *desc_end = reinterpret_cast <uint8_t *>(&desc) + sizeof (AvbDescriptor) + __builtin_bswap64 (desc.num_bytes );
1063+
1064+ uint8_t *name = reinterpret_cast <uint8_t *>(&hd + 1 );
1065+ if (name > desc_end) {
1066+ fprintf (stderr, " AVB hash descriptor overflows bounds\n " );
1067+ break ;
1068+ }
1069+ if ((size_t )(desc_end - name) < name_len) {
1070+ fprintf (stderr, " AVB hash descriptor name of %u bytes overflows bounds\n " , name_len);
1071+ break ;
1072+ }
1073+
1074+ uint8_t *salt = name + name_len;
1075+ if ((size_t )(desc_end - salt) < salt_len) {
1076+ fprintf (stderr, " AVB hash descriptor salt of %u bytes overflows bounds\n " , salt_len);
1077+ break ;
1078+ }
1079+
1080+ uint8_t *digest = salt + salt_len;
1081+ if ((size_t )(desc_end - digest) < digest_len) {
1082+ fprintf (stderr, " AVB hash descriptor digest of %u bytes overflows bounds\n " , digest_len);
1083+ break ;
1084+ }
1085+
1086+ if (is_sha1 || is_sha256) {
1087+ digest_len = is_sha1 ? 20 : 32 ;
1088+ hd.digest_len = __builtin_bswap32 (digest_len);
1089+
1090+ auto ctx = get_sha (is_sha1);
1091+ ctx->update (byte_view (salt, salt_len));
1092+ ctx->update (byte_view (out.data (), aosp_img_size));
1093+ ctx->finalize_into (byte_data (digest, digest_len));
1094+ } else {
1095+ fprintf (stderr, " Unsupported AVB hash algorithm: %.32s — zeroing digest\n " , algo);
1096+ memset (digest, 0 , desc_end - digest);
1097+ }
10501098 break ;
10511099 }
10521100 }
0 commit comments