update aosp modules from upstream

Goodbye 2022
a year of the Tiger
a year of lock down
a year of all the mess
pull/140/head
cfig 2 years ago
parent 078930b7c7
commit e14887192a
No known key found for this signature in database
GPG Key ID: A01F494E159CAD3C

@ -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

@ -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, <Br>Sep 2018)| [more ...](doc/additional_tricks.md#pixel-xl-marlin) |
| K3 (CPH1955) | OPPO | Y for recovery.img<Br> 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
<details>

@ -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.

@ -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-----

16
aosp/libavb.diff vendored

@ -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 <machine/endian.h>
+#else
#include <endian.h>
+#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

@ -1,5 +1,4 @@
apply plugin: "c"
apply plugin: "cpp"
model {
buildTypes {

@ -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);

@ -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);
}

@ -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;

@ -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;

@ -22,11 +22,7 @@
* SOFTWARE.
*/
#if defined(__APPLE__) && defined(__MACH__)
#include <machine/endian.h>
#else
#include <endian.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

@ -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;
}

@ -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;
}

@ -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_ */

@ -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.

@ -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;

@ -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);

@ -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;

@ -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);

@ -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')

@ -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",
],
},
}

@ -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 :=

@ -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
+---------------------+
```

@ -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__':

@ -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':

@ -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)

@ -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 <<EOF
Usage:
$0 --boot BOOT --init_boot INIT_BOOT --version {3,4} -o OUTPUT
$0 --boot BOOT --init_boot INIT_BOOT --vendor_boot VENDOR_BOOT --version 2 -o OUTPUT
Options:
--boot FILE
Path to the generic boot image.
--init_boot FILE
Path to the generic init_boot image.
--vendor_boot FILE
Path to the vendor boot image.
--version {2,3,4}
Boot image header version to retrofit to.
-o, --output FILE
Path to the output boot image.
-v, --verbose
Show debug messages.
-h, --help, --usage
Show this help message.
EOF
}
die() {
echo >&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:-<main>}(): \"${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}"
)

@ -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:-<main>}(): \"${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"

@ -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<KotlinCompile>().all {
kotlinOptions {
freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
freeCompilerArgs += "-opt-in=kotlin.ExperimentalUnsignedTypes"
jvmTarget = "11"
jvmTarget = "17"
}
}

@ -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

@ -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<KotlinCompile>().all {
kotlinOptions {
freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn"
freeCompilerArgs += "-opt-in=kotlin.ExperimentalUnsignedTypes"
jvmTarget = "11"
jvmTarget = "17"
}
}

@ -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

@ -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

Loading…
Cancel
Save