diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 6fe314c..3e52760 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -28,7 +28,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
- java-version: 11
+ java-version: 17
- name: apt
run: sudo apt install device-tree-compiler p7zip-full
@@ -53,7 +53,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
- java-version: 11
+ java-version: 17
- name: brew
run: brew install dtc
@@ -76,7 +76,7 @@ jobs:
- name: Set up JDK
uses: actions/setup-java@v1
with:
- java-version: 11
+ java-version: 17
- name: Set up Python
uses: actions/setup-python@v2
diff --git a/README.md b/README.md
index 224ece1..0ac8e21 100644
--- a/README.md
+++ b/README.md
@@ -8,16 +8,16 @@ A tool for reverse engineering Android ROM images.
#### install required packages
-Linux: `sudo apt install git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-11-jdk gcc g++ python3 python-is-python3 p7zip-full`
+Linux: `sudo apt install git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-17-jdk gcc g++ python3 python-is-python3 p7zip-full`
Mac: `brew install lz4 xz dtc`
-Mac: Make sure you have `JDK9+` properly installed.
+Mac: Make sure you have `JDK9+` properly installed. JDK 17 is recommended.
-Windows Subsystem for Linux(WSL): `sudo apt install git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-11-jdk gcc g++ python`
+Windows Subsystem for Linux(WSL): `sudo apt install git device-tree-compiler lz4 xz-utils zlib1g-dev openjdk-17-jdk gcc g++ python`
Windows: Make sure you have `python3`, `JDK9+` and `openssl` properly installed.
-An easy way is to install [Anaconda](https://www.anaconda.com/products/individual#windows) and [Oracle JDK 11](https://www.oracle.com/java/technologies/javase-jdk11-downloads.html), then run the program under anaconda PowerShell.
+An easy way is to install [Anaconda](https://www.anaconda.com/products/individual#windows) and [Oracle JDK 17](https://www.oracle.com/java/technologies/downloads/#java17), then run the program under anaconda PowerShell.
Or install them with chocolate: `choco install openssl dtc-msys2`
#### Parsing and packing
@@ -95,11 +95,12 @@ This will enable c++ modules, which is necessary for working with sparse images.
| TS10 | Topway | Y | 10 | car headunit, @mariodantas |
| Pixel XL (marlin) | HTC | Y | 9.0.0 (PPR2.180905.006,
Sep 2018)| [more ...](doc/additional_tricks.md#pixel-xl-marlin) |
| K3 (CPH1955) | OPPO | Y for recovery.img
N for boot.img | Pie | [more](doc/additional_tricks.md#k3-cph1955) |
-| Z18 (NX606J) | ZTE | Y | 8.1.0 | [more...](doc/additional_tricks.md#nx606j) |
+| Z18 (NX606J) | ZTE | Y | 8.1.0 | [more...](doc/additional_tricks.md#nx606j) |
| Nexus 9 (volantis/flounder) | HTC | Y(with some tricks) | 7.1.1 (N9F27M, Oct 2017) | [tricks](doc/additional_tricks.md#tricks-for-nexus-9volantis)|
| Nexus 5x (bullhead) | LG | Y | 6.0.0_r12 (MDA89E) | |
| Moto X (2013) T-Mobile | Motorola | N | | |
| X7 (PD1602_A_3.12.8) | VIVO | N | ? | [Issue 35](https://github.com/cfig/Android_boot_image_editor/issues/35) |
+| Realme GT Neo 3 | Realme | N | 12 | [Issue 105](https://github.com/cfig/Android_boot_image_editor/issues/105) |
## more examples
diff --git a/aosp/avb/avbtool.v1.2.py b/aosp/avb/avbtool.v1.2.py
index f944af4..67416d4 100755
--- a/aosp/avb/avbtool.v1.2.py
+++ b/aosp/avb/avbtool.v1.2.py
@@ -930,18 +930,22 @@ class ImageHandler(object):
struct.calcsize(ImageChunk.FORMAT)))
self._read_header()
- def append_raw(self, data):
+ def append_raw(self, data, multiple_block_size=True):
"""Appends a RAW chunk to the sparse file.
- The length of the given data must be a multiple of the block size.
+ The length of the given data must be a multiple of the block size,
+ unless |multiple_block_size| is False.
Arguments:
data: Data to append as bytes.
+ multiple_block_size: whether to check the length of the
+ data is a multiple of the block size.
Raises:
OSError: If ImageHandler was initialized in read-only mode.
"""
- assert len(data) % self.block_size == 0
+ if multiple_block_size:
+ assert len(data) % self.block_size == 0
if self._read_only:
raise OSError('ImageHandler is in read-only mode.')
@@ -3684,7 +3688,12 @@ class Avb(object):
# Ensure image is multiple of block_size.
rounded_image_size = round_to_multiple(image.image_size, block_size)
if rounded_image_size > image.image_size:
- image.append_raw('\0' * (rounded_image_size - image.image_size))
+ # If we need to round up the image size, it means the length of the
+ # data to append is not a multiple of block size.
+ # Setting multiple_block_size to false, so append_raw() will not
+ # require it.
+ image.append_raw(b'\0' * (rounded_image_size - image.image_size),
+ multiple_block_size=False)
# If image size exceeds the maximum image size, fail.
if partition_size > 0:
@@ -3753,7 +3762,8 @@ class Avb(object):
padding_needed = (round_to_multiple(len(hash_tree), image.block_size) -
len(hash_tree))
hash_tree_with_padding = hash_tree + b'\0' * padding_needed
- image.append_raw(hash_tree_with_padding)
+ if len(hash_tree_with_padding) > 0:
+ image.append_raw(hash_tree_with_padding)
len_hashtree_and_fec = len(hash_tree_with_padding)
# Generate FEC codes, if requested.
diff --git a/aosp/avb/data/testkey_rsa4096_pub.bin b/aosp/avb/data/testkey_rsa4096_pub.bin
new file mode 100644
index 0000000..f2e8fbd
Binary files /dev/null and b/aosp/avb/data/testkey_rsa4096_pub.bin differ
diff --git a/aosp/avb/data/testkey_rsa4096_pub.pem b/aosp/avb/data/testkey_rsa4096_pub.pem
new file mode 100644
index 0000000..efd7144
--- /dev/null
+++ b/aosp/avb/data/testkey_rsa4096_pub.pem
@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2ASv49OEbH4NiT3CjNMS
+VeliyfEPXswWcqtEfCxlSpS1FisAuwbvEwdTTPlkuSh6G4SYiNhnpCP5p0vcSg/3
+OhiuVKgV/rCtrDXaO60nvK/o0y83NNZRK2xaJ9eWBq9ruIDK+jC0sYWzTaqqwxY0
+Grjnx/r5CXerl5PrRK7PILzwgBHbIwxHcblt1ntgR4cWVpO3wiqasEwBDDDYk4fw
+7W6LvjBb9qav3YB8RV6PkZNeRP64ggfuecq/MXNiWOPNxLzCER2hSr/+J32h9jWj
+XsrcVy8+8Mldhmr4r2an7c247aFfupuFGtUJrpROO8/LXMl5gPfMpkqoatjTMRH5
+9gJjKhot0RpmGxZBvb33TcBK5SdJX39Y4yct5clmDlI4Fjj7FutTP+b96aJeJVnY
+eUX/A0wmogBajsJRoRX5e/RcgZsYRzXYLQXprQ81dBWjjovMJ9p8XeT6BNMFC7o6
+sklFL0fHDUE/l4BNP8G1u3BfpzevSCISRS71D4eS4oQB+RIPFBUkzomZ7rnEF3Bw
+Feq+xmwfYrP0LRaH+1YeRauuMuReke1TZl697a3mEjkNg8noa2wtpe7EWmaujJfX
+DWxJx/XEkjGLCe4z2qk3tkkY+A5gRcgzke8gVxC+eC2DJtbKYfkv4L8FMFJaEhwA
+p13MfC7FlYujO/BDLl7dANsCAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/aosp/libavb.diff b/aosp/libavb.diff
deleted file mode 100644
index 5dddbd0..0000000
--- a/aosp/libavb.diff
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/aosp/libavb/src/avb/c/avb_sysdeps_posix.c b/aosp/libavb/src/avb/c/avb_sysdeps_posix.c
-index e26c3ef..f1572a5 100644
---- a/aosp/libavb/src/avb/c/avb_sysdeps_posix.c
-+++ b/aosp/libavb/src/avb/c/avb_sysdeps_posix.c
-@@ -22,7 +22,11 @@
- * SOFTWARE.
- */
-
-+#if defined(__APPLE__) && defined(__MACH__)
-+#include
-+#else
- #include
-+#endif
- #include
- #include
- #include
diff --git a/aosp/libavb1.2/build.gradle b/aosp/libavb1.2/build.gradle
index 3c5abcc..41c9e4d 100644
--- a/aosp/libavb1.2/build.gradle
+++ b/aosp/libavb1.2/build.gradle
@@ -1,5 +1,4 @@
apply plugin: "c"
-apply plugin: "cpp"
model {
buildTypes {
diff --git a/aosp/libavb1.2/src/avb/c/avb_cmdline.c b/aosp/libavb1.2/src/avb/c/avb_cmdline.c
index 5773a20..6613020 100644
--- a/aosp/libavb1.2/src/avb/c/avb_cmdline.c
+++ b/aosp/libavb1.2/src/avb/c/avb_cmdline.c
@@ -353,6 +353,10 @@ AvbSlotVerifyResult avb_append_options(
// remapped by avb_manage_hashtree_error_mode().
avb_assert_not_reached();
break;
+ case AVB_HASHTREE_ERROR_MODE_PANIC:
+ verity_mode = "panicking";
+ dm_verity_mode = "panic_on_corruption";
+ break;
}
new_ret = avb_replace(
slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode);
diff --git a/aosp/libavb1.2/src/avb/c/avb_crc32.c b/aosp/libavb1.2/src/avb/c/avb_crc32.c
index 7d4cb09..6b70383 100644
--- a/aosp/libavb1.2/src/avb/c/avb_crc32.c
+++ b/aosp/libavb1.2/src/avb/c/avb_crc32.c
@@ -1,114 +1,66 @@
-/*-
- * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
- * code or tables extracted from it, as desired without restriction.
- */
-
/*
- * First, the polynomial itself and its table of feedback terms. The
- * polynomial is
- * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
- *
- * Note that we take it "backwards" and put the highest-order term in
- * the lowest-order bit. The X^32 term is "implied"; the LSB is the
- * X^31 term, etc. The X^0 term (usually shown as "+1") results in
- * the MSB being 1
- *
- * Note that the usual hardware shift register implementation, which
- * is what we're using (we're merely optimizing it by doing eight-bit
- * chunks at a time) shifts bits into the lowest-order term. In our
- * implementation, that means shifting towards the right. Why do we
- * do it this way? Because the calculated CRC must be transmitted in
- * order from highest-order term to lowest-order term. UARTs transmit
- * characters in order from LSB to MSB. By storing the CRC this way
- * we hand it to the UART in the order low-byte to high-byte; the UART
- * sends each low-bit to hight-bit; and the result is transmission bit
- * by bit from highest- to lowest-order term without requiring any bit
- * shuffling on our part. Reception works similarly
+ * Copyright 2020 The Android Open Source Project
*
- * The feedback terms table consists of 256, 32-bit entries. Notes
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * The table can be generated at runtime if desired; code to do so
- * is shown later. It might not be obvious, but the feedback
- * terms simply represent the results of eight shift/xor opera
- * tions for all combinations of data and CRC register values
- *
- * The values must be right-shifted by eight bits by the "updcrc
- * logic; the shift must be unsigned (bring in zeroes). On some
- * hardware you could probably optimize the shift in assembler by
- * using byte-swap instructions
- * polynomial $edb88320
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* See https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
+ * for info on the general algorithm. We use the following configuration:
+ * 32-bit CRC
+ * Polynomial = 0x04C11DB7
+ * MSB-first
+ * Input and output complement
+ * Input and output bit reversal
*
- * CRC32 code derived from work by Gary S. Brown.
+ * This implementation optimizes for size and readability. We only need this for
+ * 28 bytes of A/B booting metadata, so efficiency is largely irrelevant whereas
+ * a 1KiB lookup table can be a significant cost for bootloaders.
*/
-#include "avb_sysdeps.h"
#include "avb_util.h"
-/* Code taken from FreeBSD 8 */
+/* Lookup table for reversing 4 bits. */
+/* clang-format off */
+static uint8_t reverse_4bit_table[] = {
+ 0x0, 0x8, 0x4, 0xC,
+ 0x2, 0xA, 0x6, 0xE,
+ 0x1, 0x9, 0x5, 0xD,
+ 0x3, 0xB, 0x7, 0xF
+};
+/* clang-format on */
-static uint32_t iavb_crc32_tab[] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
- 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
- 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
- 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
- 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
- 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
- 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
- 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
- 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
- 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
- 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
- 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
- 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
- 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
- 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
- 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
- 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
- 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
- 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
- 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
- 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
- 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
- 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
- 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
- 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
- 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
- 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
- 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
- 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
- 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
-
-/*
- * A function that calculates the CRC-32 based on the table above is
- * given below for documentation purposes. An equivalent implementation
- * of this function that's actually used in the kernel can be found
- * in sys/libkern.h, where it can be inlined.
- */
-
-static uint32_t iavb_crc32(uint32_t crc_in, const uint8_t* buf, int size) {
- const uint8_t* p = buf;
- uint32_t crc;
+static uint8_t reverse_byte(uint8_t val) {
+ return (reverse_4bit_table[val & 0xF] << 4) | reverse_4bit_table[val >> 4];
+}
- crc = crc_in ^ ~0U;
- while (size--)
- crc = iavb_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
- return crc ^ ~0U;
+static uint32_t reverse_uint32(uint32_t val) {
+ return (reverse_byte(val) << 24) | (reverse_byte(val >> 8) << 16) |
+ (reverse_byte(val >> 16) << 8) | reverse_byte(val >> 24);
}
uint32_t avb_crc32(const uint8_t* buf, size_t size) {
- return iavb_crc32(0, buf, size);
+ uint32_t crc = 0xFFFFFFFF;
+
+ for (size_t i = 0; i < size; ++i) {
+ crc = crc ^ ((uint32_t)reverse_byte(buf[i]) << 24);
+ for (int j = 0; j < 8; ++j) {
+ if (crc & 0x80000000) {
+ crc = (crc << 1) ^ 0x04C11DB7;
+ } else {
+ crc <<= 1;
+ }
+ }
+ }
+
+ return reverse_uint32(~crc);
}
diff --git a/aosp/libavb1.2/src/avb/c/avb_descriptor.c b/aosp/libavb1.2/src/avb/c/avb_descriptor.c
index cfc2aac..9a5a482 100644
--- a/aosp/libavb1.2/src/avb/c/avb_descriptor.c
+++ b/aosp/libavb1.2/src/avb/c/avb_descriptor.c
@@ -48,6 +48,8 @@ bool avb_descriptor_foreach(const uint8_t* image_data,
const uint8_t* desc_start;
const uint8_t* desc_end;
const uint8_t* p;
+ uint64_t desc_offset = 0;
+ uint64_t desc_size = 0;
if (image_data == NULL) {
avb_error("image_data is NULL\n.");
@@ -59,6 +61,9 @@ bool avb_descriptor_foreach(const uint8_t* image_data,
goto out;
}
+ /* The data is supposed to have been cryptographically verified at this point,
+ * This check is just adding defense in depth.
+ */
if (image_size < sizeof(AvbVBMetaImageHeader)) {
avb_error("Length is smaller than header.\n");
goto out;
@@ -75,23 +80,53 @@ bool avb_descriptor_foreach(const uint8_t* image_data,
header = (const AvbVBMetaImageHeader*)image_data;
image_end = image_data + image_size;
- desc_start = image_data + sizeof(AvbVBMetaImageHeader) +
- avb_be64toh(header->authentication_data_block_size) +
- avb_be64toh(header->descriptors_offset);
+ /* Since the data is supposed to have been cryptographically verified at this
+ * point, being overflow-safe is just for defense.
+ * The following lines are overflow-safe version of:
+ * desc_offset = sizeof(AvbVBMetaImageHeader) +
+ * avb_be64toh(header->authentication_data_block_size)) +
+ * avb_be64toh(header->descriptors_offset)
+ */
+ if (!avb_safe_add(&desc_offset,
+ sizeof(AvbVBMetaImageHeader),
+ avb_be64toh(header->authentication_data_block_size))) {
+ avb_error("Invalid authentication data block size.\n");
+ goto out;
+ }
+ if (!avb_safe_add_to(&desc_offset, avb_be64toh(header->descriptors_offset))) {
+ avb_error("Invalid descriptors offset.\n");
+ goto out;
+ }
+
+ if (desc_offset > (uint64_t)(image_end - image_data)) {
+ avb_error("Descriptors not inside passed-in data.\n");
+ goto out;
+ }
- desc_end = desc_start + avb_be64toh(header->descriptors_size);
+ desc_start = image_data + desc_offset;
- if (desc_start < image_data || desc_start > image_end ||
- desc_end < image_data || desc_end > image_end || desc_end < desc_start) {
+ desc_size = avb_be64toh(header->descriptors_size);
+ if (desc_size > (uint64_t)(image_end - desc_start)) {
avb_error("Descriptors not inside passed-in data.\n");
goto out;
}
+ desc_end = desc_start + desc_size;
+
for (p = desc_start; p < desc_end;) {
- const AvbDescriptor* dh = (const AvbDescriptor*)p;
- avb_assert_aligned(dh);
- uint64_t nb_following = avb_be64toh(dh->num_bytes_following);
+ uint64_t nb_following;
uint64_t nb_total = 0;
+ const AvbDescriptor* dh;
+
+ if (sizeof(AvbDescriptor) > (size_t)(desc_end - p)) {
+ avb_error("Invalid descriptor length.\n");
+ goto out;
+ }
+
+ dh = (const AvbDescriptor*)p;
+ avb_assert_aligned(dh);
+ nb_following = avb_be64toh(dh->num_bytes_following);
+
if (!avb_safe_add(&nb_total, sizeof(AvbDescriptor), nb_following)) {
avb_error("Invalid descriptor length.\n");
goto out;
@@ -102,7 +137,7 @@ bool avb_descriptor_foreach(const uint8_t* image_data,
goto out;
}
- if (nb_total + p < desc_start || nb_total + p > desc_end) {
+ if (nb_total > (uint64_t)(desc_end - p)) {
avb_error("Invalid data in descriptors array.\n");
goto out;
}
@@ -111,10 +146,7 @@ bool avb_descriptor_foreach(const uint8_t* image_data,
goto out;
}
- if (!avb_safe_add_to((uint64_t*)(&p), nb_total)) {
- avb_error("Invalid descriptor length.\n");
- goto out;
- }
+ p += nb_total;
}
ret = true;
diff --git a/aosp/libavb1.2/src/avb/c/avb_slot_verify.c b/aosp/libavb1.2/src/avb/c/avb_slot_verify.c
index fc4c564..8e0721d 100644
--- a/aosp/libavb1.2/src/avb/c/avb_slot_verify.c
+++ b/aosp/libavb1.2/src/avb/c/avb_slot_verify.c
@@ -468,6 +468,7 @@ out:
loaded_partition->data_size = image_size;
loaded_partition->data = image_buf;
loaded_partition->preloaded = image_preloaded;
+ loaded_partition->verify_result = ret;
image_buf = NULL;
}
@@ -1335,7 +1336,7 @@ out:
static bool has_system_partition(AvbOps* ops, const char* ab_suffix) {
char part_name[AVB_PART_NAME_MAX_SIZE];
- char* system_part_name = "system";
+ const char* system_part_name = "system";
char guid_buf[37];
AvbIOResult io_ret;
@@ -1706,7 +1707,7 @@ const char* avb_slot_verify_result_to_string(AvbSlotVerifyResult result) {
return ret;
}
-void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
+void avb_slot_verify_data_calculate_vbmeta_digest(const AvbSlotVerifyData* data,
AvbDigestType digest_type,
uint8_t* out_digest) {
bool ret = false;
diff --git a/aosp/libavb1.2/src/avb/c/avb_sysdeps_posix.c b/aosp/libavb1.2/src/avb/c/avb_sysdeps_posix.c
index f1572a5..e26c3ef 100644
--- a/aosp/libavb1.2/src/avb/c/avb_sysdeps_posix.c
+++ b/aosp/libavb1.2/src/avb/c/avb_sysdeps_posix.c
@@ -22,11 +22,7 @@
* SOFTWARE.
*/
-#if defined(__APPLE__) && defined(__MACH__)
-#include
-#else
#include
-#endif
#include
#include
#include
diff --git a/aosp/libavb1.2/src/avb/c/avb_sha256.c b/aosp/libavb1.2/src/avb/c/sha256_impl.c
similarity index 93%
rename from aosp/libavb1.2/src/avb/c/avb_sha256.c
rename to aosp/libavb1.2/src/avb/c/sha256_impl.c
index 8a1c3ae..4a3dba1 100644
--- a/aosp/libavb1.2/src/avb/c/avb_sha256.c
+++ b/aosp/libavb1.2/src/avb/c/sha256_impl.c
@@ -36,6 +36,7 @@
*/
#include "avb_sha.h"
+#include "avb_crypto_ops_impl.h"
#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
@@ -112,7 +113,8 @@ static const uint32_t sha256_k[64] = {
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
/* SHA-256 implementation */
-void avb_sha256_init(AvbSHA256Ctx* ctx) {
+void avb_sha256_init(AvbSHA256Ctx* avb_ctx) {
+ AvbSHA256ImplCtx* ctx = (AvbSHA256ImplCtx*)avb_ctx->reserved;
#ifndef UNROLL_LOOPS
int i;
for (i = 0; i < 8; i++) {
@@ -133,7 +135,7 @@ void avb_sha256_init(AvbSHA256Ctx* ctx) {
ctx->tot_len = 0;
}
-static void SHA256_transform(AvbSHA256Ctx* ctx,
+static void SHA256_transform(AvbSHA256ImplCtx* ctx,
const uint8_t* message,
size_t block_nb) {
uint32_t w[64];
@@ -332,7 +334,8 @@ static void SHA256_transform(AvbSHA256Ctx* ctx,
}
}
-void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len) {
+void avb_sha256_update(AvbSHA256Ctx* avb_ctx, const uint8_t* data, size_t len) {
+ AvbSHA256ImplCtx* ctx = (AvbSHA256ImplCtx*)avb_ctx->reserved;
size_t block_nb;
size_t new_len, rem_len, tmp_len;
const uint8_t* shifted_data;
@@ -363,7 +366,8 @@ void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len) {
ctx->tot_len += (block_nb + 1) << 6;
}
-uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) {
+uint8_t* avb_sha256_final(AvbSHA256Ctx* avb_ctx) {
+ AvbSHA256ImplCtx* ctx = (AvbSHA256ImplCtx*)avb_ctx->reserved;
size_t block_nb;
size_t pm_len;
uint64_t len_b;
@@ -385,18 +389,18 @@ uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) {
#ifndef UNROLL_LOOPS
for (i = 0; i < 8; i++) {
- UNPACK32(ctx->h[i], &ctx->buf[i << 2]);
+ UNPACK32(ctx->h[i], &avb_ctx->buf[i << 2]);
}
#else
- UNPACK32(ctx->h[0], &ctx->buf[0]);
- UNPACK32(ctx->h[1], &ctx->buf[4]);
- UNPACK32(ctx->h[2], &ctx->buf[8]);
- UNPACK32(ctx->h[3], &ctx->buf[12]);
- UNPACK32(ctx->h[4], &ctx->buf[16]);
- UNPACK32(ctx->h[5], &ctx->buf[20]);
- UNPACK32(ctx->h[6], &ctx->buf[24]);
- UNPACK32(ctx->h[7], &ctx->buf[28]);
+ UNPACK32(ctx->h[0], &avb_ctx->buf[0]);
+ UNPACK32(ctx->h[1], &avb_ctx->buf[4]);
+ UNPACK32(ctx->h[2], &avb_ctx->buf[8]);
+ UNPACK32(ctx->h[3], &avb_ctx->buf[12]);
+ UNPACK32(ctx->h[4], &avb_ctx->buf[16]);
+ UNPACK32(ctx->h[5], &avb_ctx->buf[20]);
+ UNPACK32(ctx->h[6], &avb_ctx->buf[24]);
+ UNPACK32(ctx->h[7], &avb_ctx->buf[28]);
#endif /* !UNROLL_LOOPS */
- return ctx->buf;
+ return avb_ctx->buf;
}
diff --git a/aosp/libavb1.2/src/avb/c/avb_sha512.c b/aosp/libavb1.2/src/avb/c/sha512_impl.c
similarity index 93%
rename from aosp/libavb1.2/src/avb/c/avb_sha512.c
rename to aosp/libavb1.2/src/avb/c/sha512_impl.c
index 6cdc494..3d66a53 100644
--- a/aosp/libavb1.2/src/avb/c/avb_sha512.c
+++ b/aosp/libavb1.2/src/avb/c/sha512_impl.c
@@ -36,6 +36,7 @@
*/
#include "avb_sha.h"
+#include "avb_crypto_ops_impl.h"
#define SHFR(x, n) (x >> n)
#define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n)))
@@ -131,7 +132,8 @@ static const uint64_t sha512_k[80] = {
/* SHA-512 implementation */
-void avb_sha512_init(AvbSHA512Ctx* ctx) {
+void avb_sha512_init(AvbSHA512Ctx* avb_ctx) {
+ AvbSHA512ImplCtx* ctx = (AvbSHA512ImplCtx*)avb_ctx->reserved;
#ifdef UNROLL_LOOPS_SHA512
ctx->h[0] = sha512_h0[0];
ctx->h[1] = sha512_h0[1];
@@ -152,7 +154,7 @@ void avb_sha512_init(AvbSHA512Ctx* ctx) {
ctx->tot_len = 0;
}
-static void SHA512_transform(AvbSHA512Ctx* ctx,
+static void SHA512_transform(AvbSHA512ImplCtx* ctx,
const uint8_t* message,
size_t block_nb) {
uint64_t w[80];
@@ -318,7 +320,8 @@ static void SHA512_transform(AvbSHA512Ctx* ctx,
}
}
-void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) {
+void avb_sha512_update(AvbSHA512Ctx* avb_ctx, const uint8_t* data, size_t len) {
+ AvbSHA512ImplCtx* ctx = (AvbSHA512ImplCtx*)avb_ctx->reserved;
size_t block_nb;
size_t new_len, rem_len, tmp_len;
const uint8_t* shifted_data;
@@ -349,7 +352,8 @@ void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) {
ctx->tot_len += (block_nb + 1) << 7;
}
-uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
+uint8_t* avb_sha512_final(AvbSHA512Ctx* avb_ctx) {
+ AvbSHA512ImplCtx* ctx = (AvbSHA512ImplCtx*)avb_ctx->reserved;
size_t block_nb;
size_t pm_len;
uint64_t len_b;
@@ -371,18 +375,18 @@ uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) {
SHA512_transform(ctx, ctx->block, block_nb);
#ifdef UNROLL_LOOPS_SHA512
- UNPACK64(ctx->h[0], &ctx->buf[0]);
- UNPACK64(ctx->h[1], &ctx->buf[8]);
- UNPACK64(ctx->h[2], &ctx->buf[16]);
- UNPACK64(ctx->h[3], &ctx->buf[24]);
- UNPACK64(ctx->h[4], &ctx->buf[32]);
- UNPACK64(ctx->h[5], &ctx->buf[40]);
- UNPACK64(ctx->h[6], &ctx->buf[48]);
- UNPACK64(ctx->h[7], &ctx->buf[56]);
+ UNPACK64(ctx->h[0], &avb_ctx->buf[0]);
+ UNPACK64(ctx->h[1], &avb_ctx->buf[8]);
+ UNPACK64(ctx->h[2], &avb_ctx->buf[16]);
+ UNPACK64(ctx->h[3], &avb_ctx->buf[24]);
+ UNPACK64(ctx->h[4], &avb_ctx->buf[32]);
+ UNPACK64(ctx->h[5], &avb_ctx->buf[40]);
+ UNPACK64(ctx->h[6], &avb_ctx->buf[48]);
+ UNPACK64(ctx->h[7], &avb_ctx->buf[56]);
#else
for (i = 0; i < 8; i++)
- UNPACK64(ctx->h[i], &ctx->buf[i << 3]);
+ UNPACK64(ctx->h[i], &avb_ctx->buf[i << 3]);
#endif /* UNROLL_LOOPS_SHA512 */
- return ctx->buf;
+ return avb_ctx->buf;
}
diff --git a/aosp/libavb1.2/src/avb/headers/avb_crypto_ops_impl.h b/aosp/libavb1.2/src/avb/headers/avb_crypto_ops_impl.h
new file mode 100644
index 0000000..675aa5b
--- /dev/null
+++ b/aosp/libavb1.2/src/avb/headers/avb_crypto_ops_impl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifdef AVB_INSIDE_LIBAVB_H
+#error "You can't include avb_crypto_ops_impl.h in the public header libavb.h."
+#endif
+
+#ifndef AVB_COMPILATION
+#error "Never include this file, it may only be used from internal avb code."
+#endif
+
+#ifndef AVB_CRYPTO_OPS_IMPL_H_
+#define AVB_CRYPTO_OPS_IMPL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "avb_sysdeps.h"
+
+/* Block size in bytes of a SHA-256 digest. */
+#define AVB_SHA256_BLOCK_SIZE 64
+
+/* Block size in bytes of a SHA-512 digest. */
+#define AVB_SHA512_BLOCK_SIZE 128
+
+/* Data structure used for SHA-256. */
+typedef struct {
+ uint32_t h[8];
+ uint64_t tot_len;
+ size_t len;
+ uint8_t block[2 * AVB_SHA256_BLOCK_SIZE];
+} AvbSHA256ImplCtx;
+
+/* Data structure used for SHA-512. */
+typedef struct {
+ uint64_t h[8];
+ uint64_t tot_len;
+ size_t len;
+ uint8_t block[2 * AVB_SHA512_BLOCK_SIZE];
+} AvbSHA512ImplCtx;
+
+#define AVB_SHA256_CONTEXT_SIZE sizeof(AvbSHA256ImplCtx)
+#define AVB_SHA512_CONTEXT_SIZE sizeof(AvbSHA512ImplCtx)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AVB_CRYPTO_OPS_IMPL_H_ */
diff --git a/aosp/libavb1.2/src/avb/headers/avb_hashtree_descriptor.h b/aosp/libavb1.2/src/avb/headers/avb_hashtree_descriptor.h
index d0f7e2c..6595f46 100644
--- a/aosp/libavb1.2/src/avb/headers/avb_hashtree_descriptor.h
+++ b/aosp/libavb1.2/src/avb/headers/avb_hashtree_descriptor.h
@@ -40,9 +40,12 @@ extern "C" {
* AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB: Do not apply the default A/B
* partition logic to this partition. This is intentionally a negative boolean
* because A/B should be both the default and most used in practice.
+ * AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE: supports to validate hashes
+ * at most once in DM-Verity.
*/
typedef enum {
AVB_HASHTREE_DESCRIPTOR_FLAGS_DO_NOT_USE_AB = (1 << 0),
+ AVB_HASHTREE_DESCRIPTOR_FLAGS_CHECK_AT_MOST_ONCE = (1 << 1),
} AvbHashtreeDescriptorFlags;
/* A descriptor containing information about a dm-verity hashtree.
diff --git a/aosp/libavb1.2/src/avb/headers/avb_sha.h b/aosp/libavb1.2/src/avb/headers/avb_sha.h
index 82ac9a5..f4c42ea 100644
--- a/aosp/libavb1.2/src/avb/headers/avb_sha.h
+++ b/aosp/libavb1.2/src/avb/headers/avb_sha.h
@@ -40,28 +40,28 @@ extern "C" {
#include "avb_crypto.h"
#include "avb_sysdeps.h"
-/* Block size in bytes of a SHA-256 digest. */
-#define AVB_SHA256_BLOCK_SIZE 64
-
-
-/* Block size in bytes of a SHA-512 digest. */
-#define AVB_SHA512_BLOCK_SIZE 128
+/* The following defines must be set to something appropriate
+ *
+ * AVB_SHA256_CONTEXT_SIZE - the size of AvbSHA256Ctx, excluding the buffer
+ * AVB_SHA512_CONTEXT_SIZE - the size of AvbSHA512Ctx, exclusing the buffer
+ *
+ * For example, if AvbSHA512Ctx is implemented using BoringSSL this would be
+ * defined as sizeof(SHA256_CTX).
+ *
+ * We expect the implementation to provide a header file with the name
+ * avb_crypto_ops_impl.h to do all this.
+ */
+#include "avb_crypto_ops_impl.h"
/* Data structure used for SHA-256. */
typedef struct {
- uint32_t h[8];
- uint64_t tot_len;
- size_t len;
- uint8_t block[2 * AVB_SHA256_BLOCK_SIZE];
+ uint8_t reserved[AVB_SHA256_CONTEXT_SIZE];
uint8_t buf[AVB_SHA256_DIGEST_SIZE]; /* Used for storing the final digest. */
} AvbSHA256Ctx;
/* Data structure used for SHA-512. */
typedef struct {
- uint64_t h[8];
- uint64_t tot_len;
- size_t len;
- uint8_t block[2 * AVB_SHA512_BLOCK_SIZE];
+ uint8_t reserved[AVB_SHA512_CONTEXT_SIZE];
uint8_t buf[AVB_SHA512_DIGEST_SIZE]; /* Used for storing the final digest. */
} AvbSHA512Ctx;
diff --git a/aosp/libavb1.2/src/avb/headers/avb_slot_verify.h b/aosp/libavb1.2/src/avb/headers/avb_slot_verify.h
index a2c98f4..c7f3f45 100644
--- a/aosp/libavb1.2/src/avb/headers/avb_slot_verify.h
+++ b/aosp/libavb1.2/src/avb/headers/avb_slot_verify.h
@@ -88,7 +88,8 @@ typedef enum {
AVB_HASHTREE_ERROR_MODE_RESTART,
AVB_HASHTREE_ERROR_MODE_EIO,
AVB_HASHTREE_ERROR_MODE_LOGGING,
- AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO
+ AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO,
+ AVB_HASHTREE_ERROR_MODE_PANIC
} AvbHashtreeErrorMode;
/* Flags that influence how avb_slot_verify() works.
@@ -157,6 +158,7 @@ typedef struct {
uint8_t* data;
size_t data_size;
bool preloaded;
+ AvbSlotVerifyResult verify_result;
} AvbPartitionData;
/* AvbVBMetaData contains a vbmeta struct loaded from a partition when
@@ -310,7 +312,7 @@ typedef struct {
* in |out_digest| which must be large enough to hold a digest
* of the requested type.
*/
-void avb_slot_verify_data_calculate_vbmeta_digest(AvbSlotVerifyData* data,
+void avb_slot_verify_data_calculate_vbmeta_digest(const AvbSlotVerifyData* data,
AvbDigestType digest_type,
uint8_t* out_digest);
diff --git a/aosp/libxbc/libxbc.c b/aosp/libxbc/libxbc.c
index 6e47dee..d80ac11 100644
--- a/aosp/libxbc/libxbc.c
+++ b/aosp/libxbc/libxbc.c
@@ -53,7 +53,7 @@ static bool isTrailerPresent(uint64_t bootconfig_end_addr) {
/*
* Add a string of boot config parameters to memory appended by the trailer.
*/
-int32_t addBootConfigParameters(char* params, uint32_t params_size,
+int32_t addBootConfigParameters(const char* params, uint32_t params_size,
uint64_t bootconfig_start_addr, uint32_t bootconfig_size) {
if (!params || !bootconfig_start_addr) {
return -1;
diff --git a/aosp/libxbc/libxbc.h b/aosp/libxbc/libxbc.h
index e60cd95..bd10adf 100644
--- a/aosp/libxbc/libxbc.h
+++ b/aosp/libxbc/libxbc.h
@@ -43,7 +43,7 @@ extern "C" {
* @param bootconfig_size size of the current bootconfig section in bytes.
* @return number of bytes added to the boot config section. -1 for error.
*/
-int addBootConfigParameters(char *params, uint32_t params_size,
+int addBootConfigParameters(const char *params, uint32_t params_size,
uint64_t bootconfig_start_addr,
uint32_t bootconfig_size);
diff --git a/aosp/system/libufdt/utils/src/mkdtboimg.py b/aosp/system/libufdt/utils/src/mkdtboimg.py
index bc33e1f..2634c76 100755
--- a/aosp/system/libufdt/utils/src/mkdtboimg.py
+++ b/aosp/system/libufdt/utils/src/mkdtboimg.py
@@ -1,4 +1,4 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
# Copyright 2017, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -1018,7 +1018,7 @@ def print_usage(cmd, _):
def main():
"""Main entry point for mkdtboimg."""
- parser = argparse.ArgumentParser(prog='mkdtboimg.py')
+ parser = argparse.ArgumentParser()
subparser = parser.add_subparsers(title='subcommand',
description='Valid subcommands')
diff --git a/aosp/system/tools/mkbootimg/gki/Android.bp b/aosp/system/tools/mkbootimg/gki/Android.bp
index c62e7d8..41a1c3e 100644
--- a/aosp/system/tools/mkbootimg/gki/Android.bp
+++ b/aosp/system/tools/mkbootimg/gki/Android.bp
@@ -45,59 +45,3 @@ python_binary_host {
"avbtool",
],
}
-
-sh_binary_host {
- name: "retrofit_gki",
- src: "retrofit_gki.sh",
- required: [
- "avbtool",
- "mkbootimg",
- "unpack_bootimg",
- ],
-}
-
-sh_test_host {
- name: "retrofit_gki_test",
- src: "retrofit_gki_test.sh",
- data: [
- "retrofit_gki.sh",
- ],
- data_bins: [
- "avbtool",
- "mkbootimg",
- "unpack_bootimg",
- ],
- test_suites: [
- "general-tests",
- ],
-}
-
-genrule {
- name: "gki_retrofitting_tools",
- tools: [
- "soong_zip",
- "retrofit_gki",
- "avbtool",
- "mkbootimg",
- "unpack_bootimg",
- ],
- srcs: [
- "README.md",
- ],
- cmd: "STAGE_DIR=$(genDir)/gki_retrofitting_tools && " +
- "rm -rf $${STAGE_DIR} && mkdir -p $${STAGE_DIR} && " +
- "cp $(location retrofit_gki) $${STAGE_DIR} && " +
- "cp $(location avbtool) $${STAGE_DIR} && " +
- "cp $(location mkbootimg) $${STAGE_DIR} && " +
- "cp $(location unpack_bootimg) $${STAGE_DIR} && " +
- "cp $(in) $${STAGE_DIR} && " +
- "$(location soong_zip) -o $(out) -C $(genDir) -D $${STAGE_DIR}",
- out: [
- "gki_retrofitting_tools.zip",
- ],
- dist: {
- targets: [
- "gki_retrofitting_tools",
- ],
- },
-}
diff --git a/aosp/system/tools/mkbootimg/gki/Android.mk b/aosp/system/tools/mkbootimg/gki/Android.mk
deleted file mode 100644
index c0af5ef..0000000
--- a/aosp/system/tools/mkbootimg/gki/Android.mk
+++ /dev/null
@@ -1,36 +0,0 @@
-#
-# Copyright (C) 2022 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-_gsi_gki_product_names := \
- aosp_arm \
- aosp_arm64 \
- aosp_x86 \
- aosp_x86_64 \
- gsi_arm \
- gsi_arm64 \
- gsi_x86 \
- gsi_x86_64 \
- gki_arm64 \
- gki_x86_64 \
-
-# Add gki_retrofitting_tools to `m dist` of GSI/GKI for easy pickup.
-ifneq (,$(filter $(_gsi_gki_product_names),$(TARGET_PRODUCT)))
-
-droidcore-unbundled: gki_retrofitting_tools
-
-endif
-
-_gsi_gki_product_names :=
diff --git a/aosp/system/tools/mkbootimg/gki/README.md b/aosp/system/tools/mkbootimg/gki/README.md
deleted file mode 100644
index 628e52a..0000000
--- a/aosp/system/tools/mkbootimg/gki/README.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# GKI boot image retrofitting tools for upgrading devices
-
-Starting from Android T the GKI boot images consist of the generic `boot.img`
-and `init_boot.img`. The `boot.img` contains the generic kernel, and
-`init_boot.img` contains the generic ramdisk.
-For upgrading devices whose `vendor_boot` partition is non-existent, this tool
-(or spec) can be used to retrofit a set of Android T GKI `boot`, `init_boot` and
-OEM `vendor_boot` partition images back into a single boot image containing the
-GKI kernel plus generic and vendor ramdisks.
-
-## Retrofitting the boot images
-
-1. Download the certified GKI `boot.img`.
-2. Go to the build artifacts page of `aosp_arm64` on `aosp-master` branch on
- https://ci.android.com/ and download `gki_retrofitting_tools.zip`.
-3. Unzip and make sure the tool is in `${PATH}`.
-
- ```bash
- unzip gki_retrofitting_tools.zip
- export PATH="$(pwd)/gki_retrofitting_tools:${PATH}"
- # See tool usage:
- retrofit_gki --help
- ```
-
-4. Create the retrofitted image. The `--version` argument lets you choose the
- boot image header version of the retrofitted boot image. Only version 2 is
- supported at the moment.
-
- ```bash
- retrofit_gki --boot boot.img --init_boot init_boot.img \
- --vendor_boot vendor_boot.img --version 2 -o boot.retrofitted.img
- ```
-
-## Spec of the retrofitted images
-
-* The SOURCE `boot.img` must be officially certified Android T (or later) GKI.
-* The DEST retrofitted boot image must not set the security patch level in its
- header. This is because the SOURCE images might have different SPL value, thus
- making the boot header SPL of the retrofitted image ill-defined. The SPL value
- must be defined by the chained vbmeta image of the `boot` partition.
-* The `boot signature` of the DEST image is the `boot signature` of the DEST
- `boot.img`.
-* The DEST retrofitted boot image must pass the `vts_gki_compliance_test`
- testcase.
-
-### Retrofit to boot image V2
-
-* The `kernel` of the DEST image must be from the SOURCE `boot.img`.
-* The `ramdisk` of the DEST image must be from the SOURCE `vendor_boot.img` and
- `init_boot.img`. The DEST `ramdisk` is the ramdisk concatenation of the vendor
- ramdisk and generic ramdisk.
-* The `recovery dtbo / acpio` must be empty.
-* The `dtb` of the DEST image must be from the SOURCE `vendor_boot.img`.
-* The `boot_signature` section must be appended to the end of the boot image,
- and its size is zero-padded to 16KiB.
-
-```
- +---------------------+
- | boot header | 1 page
- +---------------------+
- | kernel | n pages
- +---------------------+
- | * vendor ramdisk |
- | +generic ramdisk | m pages
- +---------------------+
- | second stage | o pages
- +---------------------+
- | recovery dtbo/acpio | 0 byte
- +---------------------+
- | dtb | q pages
- +---------------------+
- | * boot signature | 16384 (16K) bytes
- +---------------------+
-```
diff --git a/aosp/system/tools/mkbootimg/gki/certify_bootimg.py b/aosp/system/tools/mkbootimg/gki/certify_bootimg.py
index 39dcaeb..68a042e 100755
--- a/aosp/system/tools/mkbootimg/gki/certify_bootimg.py
+++ b/aosp/system/tools/mkbootimg/gki/certify_bootimg.py
@@ -132,7 +132,7 @@ def get_avb_image_size(image):
return 0
-def add_avb_footer(image, partition_size):
+def add_avb_footer(image, partition_size, extra_footer_args):
"""Appends a AVB hash footer to the image."""
avbtool_cmd = ['avbtool', 'add_hash_footer', '--image', image,
@@ -143,6 +143,7 @@ def add_avb_footer(image, partition_size):
else:
avbtool_cmd.extend(['--dynamic_partition_size'])
+ avbtool_cmd.extend(extra_footer_args)
subprocess.check_call(avbtool_cmd)
@@ -160,12 +161,24 @@ def load_dict_from_file(path):
return d
-def load_gki_info_file(gki_info_file, extra_args):
- """Loads extra args from |gki_info_file| into |extra_args|."""
+def load_gki_info_file(gki_info_file, extra_args, extra_footer_args):
+ """Loads extra arguments from the gki info file.
+
+ Args:
+ gki_info_file: path to a gki-info.txt.
+ extra_args: the extra arguments forwarded to avbtool when creating
+ the gki certificate.
+ extra_footer_args: the extra arguments forwarded to avbtool when
+ creating the avb footer.
+
+ """
info_dict = load_dict_from_file(gki_info_file)
if 'certify_bootimg_extra_args' in info_dict:
extra_args.extend(
shlex.split(info_dict['certify_bootimg_extra_args']))
+ if 'certify_bootimg_extra_footer_args' in info_dict:
+ extra_footer_args.extend(
+ shlex.split(info_dict['certify_bootimg_extra_footer_args']))
def get_archive_name_and_format_for_shutil(path):
@@ -206,6 +219,8 @@ def parse_cmdline():
# Optional args.
parser.add_argument('--extra_args', default=[], action='append',
help='extra arguments to be forwarded to avbtool')
+ parser.add_argument('--extra_footer_args', default=[], action='append',
+ help='extra arguments for adding the avb footer')
args = parser.parse_args()
@@ -218,13 +233,21 @@ def parse_cmdline():
extra_args.extend(shlex.split(a))
args.extra_args = extra_args
+ extra_footer_args = []
+ for a in args.extra_footer_args:
+ extra_footer_args.extend(shlex.split(a))
+ args.extra_footer_args = extra_footer_args
+
if args.gki_info:
- load_gki_info_file(args.gki_info, args.extra_args)
+ load_gki_info_file(args.gki_info,
+ args.extra_args,
+ args.extra_footer_args)
return args
-def certify_bootimg(boot_img, output_img, algorithm, key, extra_args):
+def certify_bootimg(boot_img, output_img, algorithm, key, extra_args,
+ extra_footer_args):
"""Certify a GKI boot image by generating and appending a boot_signature."""
with tempfile.TemporaryDirectory() as temp_dir:
boot_tmp = os.path.join(temp_dir, 'boot.tmp')
@@ -234,26 +257,27 @@ def certify_bootimg(boot_img, output_img, algorithm, key, extra_args):
add_certificate(boot_tmp, algorithm, key, extra_args)
avb_partition_size = get_avb_image_size(boot_img)
- add_avb_footer(boot_tmp, avb_partition_size)
+ add_avb_footer(boot_tmp, avb_partition_size, extra_footer_args)
# We're done, copy the temp image to the final output.
shutil.copy2(boot_tmp, output_img)
def certify_bootimg_archive(boot_img_archive, output_archive,
- algorithm, key, extra_args):
+ algorithm, key, extra_args, extra_footer_args):
"""Similar to certify_bootimg(), but for an archive of boot images."""
with tempfile.TemporaryDirectory() as unpack_dir:
shutil.unpack_archive(boot_img_archive, unpack_dir)
gki_info_file = os.path.join(unpack_dir, 'gki-info.txt')
if os.path.exists(gki_info_file):
- load_gki_info_file(gki_info_file, extra_args)
+ load_gki_info_file(gki_info_file, extra_args, extra_footer_args)
for boot_img in glob.glob(os.path.join(unpack_dir, 'boot*.img')):
print(f'Certifying {os.path.basename(boot_img)} ...')
certify_bootimg(boot_img=boot_img, output_img=boot_img,
- algorithm=algorithm, key=key, extra_args=extra_args)
+ algorithm=algorithm, key=key, extra_args=extra_args,
+ extra_footer_args=extra_footer_args)
print(f'Making certified archive: {output_archive}')
archive_file_name, archive_format = (
@@ -275,10 +299,11 @@ def main():
if args.boot_img_archive:
certify_bootimg_archive(args.boot_img_archive, args.output,
- args.algorithm, args.key, args.extra_args)
+ args.algorithm, args.key, args.extra_args,
+ args.extra_footer_args)
else:
certify_bootimg(args.boot_img, args.output, args.algorithm,
- args.key, args.extra_args)
+ args.key, args.extra_args, args.extra_footer_args)
if __name__ == '__main__':
diff --git a/aosp/system/tools/mkbootimg/gki/certify_bootimg_test.py b/aosp/system/tools/mkbootimg/gki/certify_bootimg_test.py
index fd7473b..ec5f505 100644
--- a/aosp/system/tools/mkbootimg/gki/certify_bootimg_test.py
+++ b/aosp/system/tools/mkbootimg/gki/certify_bootimg_test.py
@@ -219,6 +219,197 @@ class CertifyBootimgTest(unittest.TestCase):
# C0103: invalid-name for maxDiff.
self.maxDiff = None # pylint: disable=C0103
+ # For AVB footers, we don't sign it so the Authentication block
+ # is zero bytes and the Algorithm is NONE. The footer will be
+ # replaced by device-specific settings when being incorporated into
+ # a device codebase. The footer here is just to pass some GKI
+ # pre-release test.
+ self._EXPECTED_AVB_FOOTER_BOOT_CERTIFIED = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 131072 bytes\n'
+ 'Original image size: 24576 bytes\n'
+ 'VBMeta offset: 24576\n'
+ 'VBMeta size: 576 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 320 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 24576 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ 'c9b4ad78fae6f72f7eff939dee6078ed'
+ '8a75132e53f6c11ba1ec0f4b57f9eab0\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ )
+
+ self._EXPECTED_AVB_FOOTER_BOOT_CERTIFIED_2 = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 131072 bytes\n'
+ 'Original image size: 24576 bytes\n'
+ 'VBMeta offset: 24576\n'
+ 'VBMeta size: 576 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 320 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 24576 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ 'ae2538e78b2a30b1112cede30d858a5f'
+ '6f8dc2a1b109dd4a7bb28124b77d2ab0\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ )
+
+ self._EXPECTED_AVB_FOOTER_WITH_GKI_INFO = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 131072 bytes\n'
+ 'Original image size: 24576 bytes\n'
+ 'VBMeta offset: 24576\n'
+ 'VBMeta size: 704 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 448 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 24576 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ '363d4f246a4a5e1bba8ba8b86f5eb0cf'
+ '9817e4e51663ba26edccf71c3861090a\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ " Prop: com.android.build.boot.os_version -> '13'\n"
+ " Prop: com.android.build.boot.security_patch -> '2022-05-05'\n"
+ )
+
+ self._EXPECTED_AVB_FOOTER_BOOT = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 131072 bytes\n'
+ 'Original image size: 28672 bytes\n'
+ 'VBMeta offset: 28672\n'
+ 'VBMeta size: 704 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 448 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 28672 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ 'b93084707ba2367120e19547f17f1073'
+ '4c7ad8e56008ec2159d5f01b950335ad\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ " Prop: com.android.build.boot.os_version -> '13'\n"
+ " Prop: com.android.build.boot.security_patch -> '2022-05-05'\n"
+ )
+
+ self._EXPECTED_AVB_FOOTER_BOOT_LZ4 = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 262144 bytes\n'
+ 'Original image size: 36864 bytes\n'
+ 'VBMeta offset: 36864\n'
+ 'VBMeta size: 704 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 448 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 36864 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ '6b3f583f1bc5fbc284102e0185d02c6b'
+ '294f675c95b9337e89ea1e6b743af2ab\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ " Prop: com.android.build.boot.os_version -> '13'\n"
+ " Prop: com.android.build.boot.security_patch -> '2022-05-05'\n"
+ )
+
+ self._EXPECTED_AVB_FOOTER_BOOT_GZ = ( # pylint: disable=C0103
+ 'Footer version: 1.0\n'
+ 'Image size: 131072 bytes\n'
+ 'Original image size: 28672 bytes\n'
+ 'VBMeta offset: 28672\n'
+ 'VBMeta size: 576 bytes\n'
+ '--\n'
+ 'Minimum libavb version: 1.0\n'
+ 'Header Block: 256 bytes\n'
+ 'Authentication Block: 0 bytes\n'
+ 'Auxiliary Block: 320 bytes\n'
+ 'Algorithm: NONE\n'
+ 'Rollback Index: 0\n'
+ 'Flags: 0\n'
+ 'Rollback Index Location: 0\n'
+ "Release String: 'avbtool 1.2.0'\n"
+ 'Descriptors:\n'
+ ' Hash descriptor:\n'
+ ' Image Size: 28672 bytes\n'
+ ' Hash Algorithm: sha256\n'
+ ' Partition Name: boot\n'
+ ' Salt: a11ba11b\n'
+ ' Digest: '
+ 'd2098d507e039afc6b4d7ec3de129a8d'
+ 'd0e0cf889c9181ebee65ce2fb25de3f5\n'
+ ' Flags: 0\n'
+ " Prop: avb -> 'nice'\n"
+ " Prop: avb_space -> 'nice to meet you'\n"
+ )
+
self._EXPECTED_BOOT_SIGNATURE_RSA2048 = ( # pylint: disable=C0103
'Minimum libavb version: 1.0\n'
'Header Block: 256 bytes\n'
@@ -647,6 +838,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa2048.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--output', boot_certified_img,
]
subprocess.run(certify_bootimg_cmds, check=True, cwd=self._exec_dir)
@@ -655,7 +848,13 @@ class CertifyBootimgTest(unittest.TestCase):
self.assertTrue(has_avb_footer(boot_certified_img))
self.assertEqual(os.path.getsize(boot_img),
os.path.getsize(boot_certified_img))
+ # Checks the content in the AVB footer.
+ self._test_boot_signatures(
+ temp_out_dir,
+ {'boot-certified.img':
+ self._EXPECTED_AVB_FOOTER_BOOT_CERTIFIED})
+ # Checks the content in the GKI certificate.
extract_boot_signatures(boot_certified_img, temp_out_dir)
self._test_boot_signatures(
temp_out_dir,
@@ -672,6 +871,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa4096.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--output', boot_certified2_img,
]
subprocess.run(certify_bootimg_cmds, check=True, cwd=self._exec_dir)
@@ -680,7 +881,13 @@ class CertifyBootimgTest(unittest.TestCase):
self.assertTrue(has_avb_footer(boot_certified2_img))
self.assertEqual(os.path.getsize(boot_certified_img),
os.path.getsize(boot_certified2_img))
+ # Checks the content in the AVB footer.
+ self._test_boot_signatures(
+ temp_out_dir,
+ {'boot-certified2.img':
+ self._EXPECTED_AVB_FOOTER_BOOT_CERTIFIED_2})
+ # Checks the content in the GKI certificate.
extract_boot_signatures(boot_certified2_img, temp_out_dir)
self._test_boot_signatures(
temp_out_dir,
@@ -700,7 +907,11 @@ class CertifyBootimgTest(unittest.TestCase):
'-android13-0-00544-ged21d463f856 '
'--prop BRANCH:android13-5.10-2022-05 '
'--prop BUILD_NUMBER:ab8295296 '
- '--prop GKI_INFO:"added here"\n')
+ '--prop GKI_INFO:"added here"\n'
+ 'certify_bootimg_extra_footer_args='
+ '--prop com.android.build.boot.os_version:13 '
+ '--prop com.android.build.boot.security_patch:'
+ '2022-05-05\n')
gki_info_path = os.path.join(temp_out_dir, 'gki-info.txt')
with open(gki_info_path, 'w', encoding='utf-8') as f:
f.write(gki_info)
@@ -715,6 +926,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa4096.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--gki_info', gki_info_path,
'--output', boot_certified_img,
]
@@ -725,6 +938,12 @@ class CertifyBootimgTest(unittest.TestCase):
self.assertEqual(os.path.getsize(boot_img),
os.path.getsize(boot_certified_img))
+ # Checks the content in the AVB footer.
+ self._test_boot_signatures(
+ temp_out_dir,
+ {'boot-certified.img': self._EXPECTED_AVB_FOOTER_WITH_GKI_INFO})
+
+ # Checks the content in the GKI certificate.
extract_boot_signatures(boot_certified_img, temp_out_dir)
self._test_boot_signatures(
temp_out_dir,
@@ -771,7 +990,11 @@ class CertifyBootimgTest(unittest.TestCase):
'-android13-0-00544-ged21d463f856 '
'--prop BRANCH:android13-5.10-2022-05 '
'--prop BUILD_NUMBER:ab8295296 '
- '--prop SPACE:"nice to meet you"\n')
+ '--prop SPACE:"nice to meet you"\n'
+ 'certify_bootimg_extra_footer_args='
+ '--prop com.android.build.boot.os_version:13 '
+ '--prop com.android.build.boot.security_patch:'
+ '2022-05-05\n')
boot_img_archive_path = generate_test_boot_image_archive(
boot_img_archive_name,
'gztar',
@@ -790,6 +1013,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa4096.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--output', boot_certified_img_archive,
]
subprocess.run(certify_bootimg_cmds, check=True, cwd=self._exec_dir)
@@ -806,6 +1031,13 @@ class CertifyBootimgTest(unittest.TestCase):
self.assertTrue(has_avb_footer(boot_lz4_img))
self.assertEqual(os.path.getsize(boot_lz4_img), 256 * 1024)
+ # Checks the content in the AVB footer.
+ self._test_boot_signatures(
+ temp_out_dir,
+ {'boot.img': self._EXPECTED_AVB_FOOTER_BOOT,
+ 'boot-lz4.img': self._EXPECTED_AVB_FOOTER_BOOT_LZ4})
+
+ # Checks the content in the GKI certificate.
self._test_boot_signatures(
temp_out_dir,
{'boot/boot_signature1':
@@ -840,6 +1072,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa4096.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--output', boot_certified_img_archive,
]
subprocess.run(certify_bootimg_cmds, check=True, cwd=self._exec_dir)
@@ -863,6 +1097,8 @@ class CertifyBootimgTest(unittest.TestCase):
'--key', './testdata/testkey_rsa4096.pem',
'--extra_args', '--prop gki:nice '
'--prop space:"nice to meet you"',
+ '--extra_footer_args', '--salt a11ba11b --prop avb:nice '
+ '--prop avb_space:"nice to meet you"',
'--output', boot_certified_img_archive2,
]
subprocess.run(certify_bootimg_cmds, check=True, cwd=self._exec_dir)
@@ -875,6 +1111,12 @@ class CertifyBootimgTest(unittest.TestCase):
self.assertTrue(has_avb_footer(boot_3_img))
self.assertEqual(os.path.getsize(boot_3_img), 128 * 1024)
+ # Checks the content in the AVB footer.
+ self._test_boot_signatures(
+ temp_out_dir,
+ {'boot-gz.img': self._EXPECTED_AVB_FOOTER_BOOT_GZ})
+
+ # Checks the content in the GKI certificate.
self._test_boot_signatures(
temp_out_dir,
{'boot-gz/boot_signature1':
diff --git a/aosp/system/tools/mkbootimg/gki/generate_gki_certificate.py b/aosp/system/tools/mkbootimg/gki/generate_gki_certificate.py
index 17a40bc..2797cca 100755
--- a/aosp/system/tools/mkbootimg/gki/generate_gki_certificate.py
+++ b/aosp/system/tools/mkbootimg/gki/generate_gki_certificate.py
@@ -44,7 +44,6 @@ def generate_gki_certificate(image, avbtool, name, algorithm, key, salt,
avbtool_cmd += ['--salt', salt]
avbtool_cmd += additional_avb_args
- print(avbtool_cmd)
subprocess.check_call(avbtool_cmd)
diff --git a/aosp/system/tools/mkbootimg/gki/retrofit_gki.sh b/aosp/system/tools/mkbootimg/gki/retrofit_gki.sh
deleted file mode 100755
index 01af7fa..0000000
--- a/aosp/system/tools/mkbootimg/gki/retrofit_gki.sh
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2022 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-#
-# Retrofits GKI boot images for upgrading devices.
-#
-
-set -eo errtrace
-
-usage() {
- cat <&2 "ERROR:" "${@}"
- exit 1
-}
-
-file_size() {
- stat -c '%s' "$1"
-}
-
-get_arg() {
- local arg="$1"
- shift
- while [[ "$#" -gt 0 ]]; do
- if [[ "$1" == "${arg}" ]]; then
- shift
- echo "$1"
- return
- fi
- shift
- done
-}
-
-TEMP_DIR="$(mktemp -d --tmpdir retrofit_gki.XXXXXXXX)"
-readonly TEMP_DIR
-
-exit_handler() {
- readonly EXIT_CODE="$?"
- rm -rf "${TEMP_DIR}" ||:
- exit "${EXIT_CODE}"
-}
-
-trap exit_handler EXIT
-trap 'die "line ${LINENO}, ${FUNCNAME:-}(): \"${BASH_COMMAND}\" returned \"$?\"" ' ERR
-
-while [[ "$1" =~ ^- ]]; do
- case "$1" in
- --boot )
- shift
- BOOT_IMAGE="$1"
- ;;
- --init_boot )
- shift
- INIT_BOOT_IMAGE="$1"
- ;;
- --vendor_boot )
- shift
- VENDOR_BOOT_IMAGE="$1"
- ;;
- --version )
- shift
- OUTPUT_BOOT_IMAGE_VERSION="$1"
- ;;
- -o | --output )
- shift
- OUTPUT_BOOT_IMAGE="$1"
- ;;
- -v | --verbose )
- VERBOSE=true
- ;;
- -- )
- shift
- break
- ;;
- -h | --help | --usage )
- usage
- exit 0
- ;;
- * )
- echo >&2 "Unexpected flag: '$1'"
- usage >&2
- exit 1
- ;;
- esac
- shift
-done
-
-declare -ir OUTPUT_BOOT_IMAGE_VERSION
-readonly BOOT_IMAGE
-readonly INIT_BOOT_IMAGE
-readonly VENDOR_BOOT_IMAGE
-readonly OUTPUT_BOOT_IMAGE
-readonly VERBOSE
-
-# Make sure the input arguments make sense.
-[[ -f "${BOOT_IMAGE}" ]] ||
- die "argument '--boot': not a regular file: '${BOOT_IMAGE}'"
-[[ -f "${INIT_BOOT_IMAGE}" ]] ||
- die "argument '--init_boot': not a regular file: '${INIT_BOOT_IMAGE}'"
-if [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -lt 2 ]] || [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -gt 4 ]]; then
- die "argument '--version': valid choices are {2, 3, 4}"
-elif [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -eq 2 ]]; then
- [[ -f "${VENDOR_BOOT_IMAGE}" ]] ||
- die "argument '--vendor_boot': not a regular file: '${VENDOR_BOOT_IMAGE}'"
-fi
-[[ -z "${OUTPUT_BOOT_IMAGE}" ]] &&
- die "argument '--output': cannot be empty"
-
-readonly BOOT_IMAGE_WITHOUT_AVB_FOOTER="${TEMP_DIR}/boot.img.without_avb_footer"
-readonly BOOT_DIR="${TEMP_DIR}/boot"
-readonly INIT_BOOT_DIR="${TEMP_DIR}/init_boot"
-readonly VENDOR_BOOT_DIR="${TEMP_DIR}/vendor_boot"
-readonly VENDOR_BOOT_MKBOOTIMG_ARGS="${TEMP_DIR}/vendor_boot.mkbootimg_args"
-readonly OUTPUT_RAMDISK="${TEMP_DIR}/out.ramdisk"
-readonly OUTPUT_BOOT_SIGNATURE="${TEMP_DIR}/out.boot_signature"
-
-readonly AVBTOOL="${AVBTOOL:-avbtool}"
-readonly MKBOOTIMG="${MKBOOTIMG:-mkbootimg}"
-readonly UNPACK_BOOTIMG="${UNPACK_BOOTIMG:-unpack_bootimg}"
-
-# Fixed boot signature size for easy discovery in VTS.
-readonly BOOT_SIGNATURE_SIZE=$(( 16 << 10 ))
-
-
-#
-# Preparations are done. Now begin the actual work.
-#
-
-# Copy the boot image because `avbtool erase_footer` edits the file in-place.
-cp "${BOOT_IMAGE}" "${BOOT_IMAGE_WITHOUT_AVB_FOOTER}"
-( [[ -n "${VERBOSE}" ]] && set -x
- "${AVBTOOL}" erase_footer --image "${BOOT_IMAGE_WITHOUT_AVB_FOOTER}" 2>/dev/null ||:
- tail -c "${BOOT_SIGNATURE_SIZE}" "${BOOT_IMAGE_WITHOUT_AVB_FOOTER}" > "${OUTPUT_BOOT_SIGNATURE}"
- "${UNPACK_BOOTIMG}" --boot_img "${BOOT_IMAGE}" --out "${BOOT_DIR}" >/dev/null
- "${UNPACK_BOOTIMG}" --boot_img "${INIT_BOOT_IMAGE}" --out "${INIT_BOOT_DIR}" >/dev/null
-)
-if [[ "$(file_size "${OUTPUT_BOOT_SIGNATURE}")" -ne "${BOOT_SIGNATURE_SIZE}" ]]; then
- die "boot signature size must be equal to ${BOOT_SIGNATURE_SIZE}"
-fi
-
-declare -a mkbootimg_args=()
-
-if [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -eq 4 ]]; then
- mkbootimg_args+=( \
- --header_version 4 \
- --kernel "${BOOT_DIR}/kernel" \
- --ramdisk "${INIT_BOOT_DIR}/ramdisk" \
- )
-elif [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -eq 3 ]]; then
- mkbootimg_args+=( \
- --header_version 3 \
- --kernel "${BOOT_DIR}/kernel" \
- --ramdisk "${INIT_BOOT_DIR}/ramdisk" \
- )
-elif [[ "${OUTPUT_BOOT_IMAGE_VERSION}" -eq 2 ]]; then
- ( [[ -n "${VERBOSE}" ]] && set -x
- "${UNPACK_BOOTIMG}" --boot_img "${VENDOR_BOOT_IMAGE}" --out "${VENDOR_BOOT_DIR}" \
- --format=mkbootimg -0 > "${VENDOR_BOOT_MKBOOTIMG_ARGS}"
- cat "${VENDOR_BOOT_DIR}/vendor_ramdisk" "${INIT_BOOT_DIR}/ramdisk" > "${OUTPUT_RAMDISK}"
- )
-
- declare -a vendor_boot_args=()
- while IFS= read -r -d '' ARG; do
- vendor_boot_args+=("${ARG}")
- done < "${VENDOR_BOOT_MKBOOTIMG_ARGS}"
-
- pagesize="$(get_arg --pagesize "${vendor_boot_args[@]}")"
- kernel_offset="$(get_arg --kernel_offset "${vendor_boot_args[@]}")"
- ramdisk_offset="$(get_arg --ramdisk_offset "${vendor_boot_args[@]}")"
- tags_offset="$(get_arg --tags_offset "${vendor_boot_args[@]}")"
- dtb_offset="$(get_arg --dtb_offset "${vendor_boot_args[@]}")"
- kernel_cmdline="$(get_arg --vendor_cmdline "${vendor_boot_args[@]}")"
-
- mkbootimg_args+=( \
- --header_version 2 \
- --base 0 \
- --kernel_offset "${kernel_offset}" \
- --ramdisk_offset "${ramdisk_offset}" \
- --second_offset 0 \
- --tags_offset "${tags_offset}" \
- --dtb_offset "${dtb_offset}" \
- --cmdline "${kernel_cmdline}" \
- --pagesize "${pagesize}" \
- --kernel "${BOOT_DIR}/kernel" \
- --ramdisk "${OUTPUT_RAMDISK}" \
- )
- if [[ -f "${VENDOR_BOOT_DIR}/dtb" ]]; then
- mkbootimg_args+=(--dtb "${VENDOR_BOOT_DIR}/dtb")
- fi
-fi
-
-( [[ -n "${VERBOSE}" ]] && set -x
- "${MKBOOTIMG}" "${mkbootimg_args[@]}" --output "${OUTPUT_BOOT_IMAGE}"
- cat "${OUTPUT_BOOT_SIGNATURE}" >> "${OUTPUT_BOOT_IMAGE}"
-)
diff --git a/aosp/system/tools/mkbootimg/gki/retrofit_gki_test.sh b/aosp/system/tools/mkbootimg/gki/retrofit_gki_test.sh
deleted file mode 100755
index b3cb0a5..0000000
--- a/aosp/system/tools/mkbootimg/gki/retrofit_gki_test.sh
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2022 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-set -eo errtrace
-
-die() {
- echo >&2 "ERROR:" "${@}"
- exit 1
-}
-
-trap 'die "line ${LINENO}, ${FUNCNAME:-}(): \"${BASH_COMMAND}\" returned \"$?\"" ' ERR
-
-# Figure out where we are and where to look for test executables.
-cd "$(dirname "${BASH_SOURCE[0]}")"
-TEST_DIR="$(pwd)"
-readonly TEST_DIR
-readonly TEMP_DIR="${TEST_DIR}/stage.retrofit_gki_test"
-
-export PATH="${TEST_DIR}:${PATH}"
-rm -rf "${TEMP_DIR}"
-mkdir -p "${TEMP_DIR}"
-
-# Generate some test files.
-readonly TEST_DTB="${TEMP_DIR}/dtb"
-readonly TEST_KERNEL="${TEMP_DIR}/kernel"
-readonly TEST_RAMDISK="${TEMP_DIR}/ramdisk"
-readonly TEST_VENDOR_RAMDISK="${TEMP_DIR}/vendor_ramdisk"
-readonly TEST_BOOT_SIGNATURE="${TEMP_DIR}/boot.boot_signature"
-readonly TEST_V2_RETROFITTED_RAMDISK="${TEMP_DIR}/retrofitted.ramdisk"
-readonly TEST_BOOT_IMAGE="${TEMP_DIR}/boot.img"
-readonly TEST_INIT_BOOT_IMAGE="${TEMP_DIR}/init_boot.img"
-readonly TEST_VENDOR_BOOT_IMAGE="${TEMP_DIR}/vendor_boot.img"
-
-( # Run these in subshell because dd is noisy.
- dd if=/dev/urandom of="${TEST_DTB}" bs=1024 count=10
- dd if=/dev/urandom of="${TEST_KERNEL}" bs=1024 count=10
- dd if=/dev/urandom of="${TEST_RAMDISK}" bs=1024 count=10
- dd if=/dev/urandom of="${TEST_VENDOR_RAMDISK}" bs=1024 count=10
- dd if=/dev/urandom of="${TEST_BOOT_SIGNATURE}" bs=1024 count=16
-) 2> /dev/null
-
-cat "${TEST_VENDOR_RAMDISK}" "${TEST_RAMDISK}" > "${TEST_V2_RETROFITTED_RAMDISK}"
-
-mkbootimg \
- --header_version 4 \
- --kernel "${TEST_KERNEL}" \
- --output "${TEST_BOOT_IMAGE}"
-cat "${TEST_BOOT_SIGNATURE}" >> "${TEST_BOOT_IMAGE}"
-avbtool add_hash_footer --image "${TEST_BOOT_IMAGE}" --partition_name boot --partition_size $((20 << 20))
-
-mkbootimg \
- --header_version 4 \
- --ramdisk "${TEST_RAMDISK}" \
- --output "${TEST_INIT_BOOT_IMAGE}"
-mkbootimg \
- --header_version 4 \
- --pagesize 4096 \
- --dtb "${TEST_DTB}" \
- --vendor_ramdisk "${TEST_VENDOR_RAMDISK}" \
- --vendor_boot "${TEST_VENDOR_BOOT_IMAGE}"
-
-readonly RETROFITTED_IMAGE="${TEMP_DIR}/retrofitted_boot.img"
-readonly RETROFITTED_IMAGE_DIR="${TEMP_DIR}/retrofitted_boot.img.unpack"
-readonly BOOT_SIGNATURE_SIZE=$(( 16 << 10 ))
-
-
-#
-# Begin test.
-#
-echo >&2 "TEST: retrofit to boot v4"
-
-retrofit_gki.sh \
- --boot "${TEST_BOOT_IMAGE}" \
- --init_boot "${TEST_INIT_BOOT_IMAGE}" \
- --version 4 \
- --output "${RETROFITTED_IMAGE}"
-
-rm -rf "${RETROFITTED_IMAGE_DIR}"
-unpack_bootimg --boot_img "${RETROFITTED_IMAGE}" --out "${RETROFITTED_IMAGE_DIR}" > /dev/null
-tail -c "${BOOT_SIGNATURE_SIZE}" "${RETROFITTED_IMAGE}" > "${RETROFITTED_IMAGE_DIR}/boot_signature"
-
-cmp -s "${TEST_KERNEL}" "${RETROFITTED_IMAGE_DIR}/kernel" ||
- die "unexpected diff: kernel"
-cmp -s "${TEST_RAMDISK}" "${RETROFITTED_IMAGE_DIR}/ramdisk" ||
- die "unexpected diff: ramdisk"
-cmp -s "${TEST_BOOT_SIGNATURE}" "${RETROFITTED_IMAGE_DIR}/boot_signature" ||
- die "unexpected diff: boot signature"
-
-
-echo >&2 "TEST: retrofit to boot v3"
-
-retrofit_gki.sh \
- --boot "${TEST_BOOT_IMAGE}" \
- --init_boot "${TEST_INIT_BOOT_IMAGE}" \
- --version 3 \
- --output "${RETROFITTED_IMAGE}"
-
-rm -rf "${RETROFITTED_IMAGE_DIR}"
-unpack_bootimg --boot_img "${RETROFITTED_IMAGE}" --out "${RETROFITTED_IMAGE_DIR}" > /dev/null
-tail -c "${BOOT_SIGNATURE_SIZE}" "${RETROFITTED_IMAGE}" > "${RETROFITTED_IMAGE_DIR}/boot_signature"
-
-cmp -s "${TEST_KERNEL}" "${RETROFITTED_IMAGE_DIR}/kernel" ||
- die "unexpected diff: kernel"
-cmp -s "${TEST_RAMDISK}" "${RETROFITTED_IMAGE_DIR}/ramdisk" ||
- die "unexpected diff: ramdisk"
-cmp -s "${TEST_BOOT_SIGNATURE}" "${RETROFITTED_IMAGE_DIR}/boot_signature" ||
- die "unexpected diff: boot signature"
-
-
-echo >&2 "TEST: retrofit to boot v2"
-
-retrofit_gki.sh \
- --boot "${TEST_BOOT_IMAGE}" \
- --init_boot "${TEST_INIT_BOOT_IMAGE}" \
- --vendor_boot "${TEST_VENDOR_BOOT_IMAGE}" \
- --version 2 \
- --output "${RETROFITTED_IMAGE}"
-
-rm -rf "${RETROFITTED_IMAGE_DIR}"
-unpack_bootimg --boot_img "${RETROFITTED_IMAGE}" --out "${RETROFITTED_IMAGE_DIR}" > /dev/null
-tail -c "${BOOT_SIGNATURE_SIZE}" "${RETROFITTED_IMAGE}" > "${RETROFITTED_IMAGE_DIR}/boot_signature"
-
-cmp -s "${TEST_DTB}" "${RETROFITTED_IMAGE_DIR}/dtb" ||
- die "unexpected diff: dtb"
-cmp -s "${TEST_KERNEL}" "${RETROFITTED_IMAGE_DIR}/kernel" ||
- die "unexpected diff: kernel"
-cmp -s "${TEST_V2_RETROFITTED_RAMDISK}" "${RETROFITTED_IMAGE_DIR}/ramdisk" ||
- die "unexpected diff: ramdisk"
-cmp -s "${TEST_BOOT_SIGNATURE}" "${RETROFITTED_IMAGE_DIR}/boot_signature" ||
- die "unexpected diff: boot signature"
diff --git a/bbootimg/build.gradle.kts b/bbootimg/build.gradle.kts
index 9a3a060..c0a59b9 100644
--- a/bbootimg/build.gradle.kts
+++ b/bbootimg/build.gradle.kts
@@ -15,7 +15,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
- kotlin("jvm") version "1.7.20"
+ kotlin("jvm") version "1.8.0"
application
}
@@ -60,7 +60,7 @@ tasks.withType().all {
kotlinOptions {
freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
freeCompilerArgs += "-opt-in=kotlin.ExperimentalUnsignedTypes"
- jvmTarget = "11"
+ jvmTarget = "17"
}
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8049c68..070cb70 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/helper/build.gradle.kts b/helper/build.gradle.kts
index 4c897e8..61d0ba5 100644
--- a/helper/build.gradle.kts
+++ b/helper/build.gradle.kts
@@ -15,7 +15,7 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
- kotlin("jvm") version "1.7.20"
+ kotlin("jvm") version "1.8.0"
`java-library`
application
}
@@ -53,7 +53,7 @@ tasks.withType().all {
kotlinOptions {
freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
freeCompilerArgs += "-opt-in=kotlin.ExperimentalUnsignedTypes"
- jvmTarget = "11"
+ jvmTarget = "17"
}
}
diff --git a/integrationTest.py b/integrationTest.py
index 0b95c7b..c622cb8 100755
--- a/integrationTest.py
+++ b/integrationTest.py
@@ -161,8 +161,9 @@ def main():
verifySingleJson("%s/issue_59/recovery.json" % resDir2, func = lambda: shutil.rmtree("build/unzip_boot/root", ignore_errors = False))
# Issue 71: dtbo
if platform.system() != "Darwin":
- verifySingleDir(resDir2, "issue_71")
- verifySingleDir(resDir2, "issue_71/redfin")
+ pass
+ #verifySingleDir(resDir2, "issue_71")
+ #verifySingleDir(resDir2, "issue_71/redfin")
else:
log.info("dtbo not fully supported on MacOS, skip testing")
# Issue 83: init_boot
diff --git a/tools/work_from_China.diff b/tools/work_from_China.diff
index c674b6c..7db8da6 100644
--- a/tools/work_from_China.diff
+++ b/tools/work_from_China.diff
@@ -44,8 +44,8 @@ index 8049c68..2e33ce8 100644
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
--distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
-+distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip
+-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
++distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.6-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/helper/build.gradle.kts b/helper/build.gradle.kts