blob: 057278905baf3967403d4260ab929a7d2ed78f73 [file] [log] [blame]
Alice Wangbf7fadd2023-01-13 12:18:24 +00001/*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Alice Wang2925b0a2023-01-19 10:44:24 +000017mod utils;
Alice Wangbf7fadd2023-01-13 12:18:24 +000018
Alice Wang2925b0a2023-01-19 10:44:24 +000019use anyhow::Result;
20use avb_bindgen::{AvbFooter, AvbVBMetaImageHeader};
Alice Wang5c1a7562023-01-13 17:19:57 +000021use pvmfw_avb::{AvbSlotVerifyError, DebugLevel};
Alice Wang2925b0a2023-01-19 10:44:24 +000022use std::{fs, mem::size_of, ptr};
23use utils::*;
24
Alice Wangbf7fadd2023-01-13 12:18:24 +000025const TEST_IMG_WITH_ONE_HASHDESC_PATH: &str = "test_image_with_one_hashdesc.img";
Alice Wang86383df2023-01-11 10:03:56 +000026const TEST_IMG_WITH_PROP_DESC_PATH: &str = "test_image_with_prop_desc.img";
27const TEST_IMG_WITH_NON_INITRD_HASHDESC_PATH: &str = "test_image_with_non_initrd_hashdesc.img";
Alice Wangbf7fadd2023-01-13 12:18:24 +000028const UNSIGNED_TEST_IMG_PATH: &str = "unsigned_test.img";
29
Alice Wangbf7fadd2023-01-13 12:18:24 +000030const RANDOM_FOOTER_POS: usize = 30;
31
32/// This test uses the Microdroid payload compiled on the fly to check that
33/// the latest payload can be verified successfully.
34#[test]
Alice Wang4e55dd92023-01-11 10:17:01 +000035fn latest_normal_payload_passes_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000036 assert_payload_verification_with_initrd_eq(
Alice Wang4e55dd92023-01-11 10:17:01 +000037 &load_latest_signed_kernel()?,
38 &load_latest_initrd_normal()?,
39 &load_trusted_public_key()?,
Alice Wang5c1a7562023-01-13 17:19:57 +000040 Ok(DebugLevel::None),
Alice Wang4e55dd92023-01-11 10:17:01 +000041 )
42}
Alice Wangbf7fadd2023-01-13 12:18:24 +000043
Alice Wang4e55dd92023-01-11 10:17:01 +000044#[test]
45fn latest_debug_payload_passes_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000046 assert_payload_verification_with_initrd_eq(
Alice Wang4e55dd92023-01-11 10:17:01 +000047 &load_latest_signed_kernel()?,
48 &load_latest_initrd_debug()?,
49 &load_trusted_public_key()?,
Alice Wang5c1a7562023-01-13 17:19:57 +000050 Ok(DebugLevel::Full),
Alice Wang4e55dd92023-01-11 10:17:01 +000051 )
Alice Wangbf7fadd2023-01-13 12:18:24 +000052}
53
54#[test]
55fn payload_expecting_no_initrd_passes_verification_with_no_initrd() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000056 assert_payload_verification_eq(
Alice Wang86383df2023-01-11 10:03:56 +000057 &fs::read(TEST_IMG_WITH_ONE_HASHDESC_PATH)?,
Alice Wang2925b0a2023-01-19 10:44:24 +000058 /*initrd=*/ None,
Alice Wang86383df2023-01-11 10:03:56 +000059 &load_trusted_public_key()?,
Alice Wang5c1a7562023-01-13 17:19:57 +000060 Ok(DebugLevel::None),
Alice Wang86383df2023-01-11 10:03:56 +000061 )
Alice Wangbf7fadd2023-01-13 12:18:24 +000062}
63
Alice Wang86383df2023-01-11 10:03:56 +000064#[test]
65fn payload_with_non_initrd_descriptor_passes_verification_with_no_initrd() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000066 assert_payload_verification_eq(
Alice Wang86383df2023-01-11 10:03:56 +000067 &fs::read(TEST_IMG_WITH_NON_INITRD_HASHDESC_PATH)?,
Alice Wang2925b0a2023-01-19 10:44:24 +000068 /*initrd=*/ None,
Alice Wang86383df2023-01-11 10:03:56 +000069 &load_trusted_public_key()?,
Alice Wang5c1a7562023-01-13 17:19:57 +000070 Ok(DebugLevel::None),
Alice Wang86383df2023-01-11 10:03:56 +000071 )
72}
73
74#[test]
75fn payload_with_prop_descriptor_fails_verification_with_no_initrd() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000076 assert_payload_verification_eq(
Alice Wang86383df2023-01-11 10:03:56 +000077 &fs::read(TEST_IMG_WITH_PROP_DESC_PATH)?,
Alice Wang2925b0a2023-01-19 10:44:24 +000078 /*initrd=*/ None,
Alice Wang86383df2023-01-11 10:03:56 +000079 &load_trusted_public_key()?,
80 Err(AvbSlotVerifyError::InvalidMetadata),
81 )
82}
83
84#[test]
85fn payload_expecting_initrd_fails_verification_with_no_initrd() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000086 assert_payload_verification_eq(
Alice Wang86383df2023-01-11 10:03:56 +000087 &load_latest_signed_kernel()?,
Alice Wang2925b0a2023-01-19 10:44:24 +000088 /*initrd=*/ None,
Alice Wang86383df2023-01-11 10:03:56 +000089 &load_trusted_public_key()?,
90 Err(AvbSlotVerifyError::InvalidMetadata),
91 )
92}
Alice Wangbf7fadd2023-01-13 12:18:24 +000093
94#[test]
95fn payload_with_empty_public_key_fails_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +000096 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +000097 &load_latest_signed_kernel()?,
98 &load_latest_initrd_normal()?,
99 /*trusted_public_key=*/ &[0u8; 0],
Alice Wang2925b0a2023-01-19 10:44:24 +0000100 Err(AvbSlotVerifyError::PublicKeyRejected),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000101 )
102}
103
104#[test]
105fn payload_with_an_invalid_public_key_fails_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +0000106 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000107 &load_latest_signed_kernel()?,
108 &load_latest_initrd_normal()?,
109 /*trusted_public_key=*/ &[0u8; 512],
Alice Wang2925b0a2023-01-19 10:44:24 +0000110 Err(AvbSlotVerifyError::PublicKeyRejected),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000111 )
112}
113
114#[test]
115fn payload_with_a_different_valid_public_key_fails_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +0000116 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000117 &load_latest_signed_kernel()?,
118 &load_latest_initrd_normal()?,
119 &fs::read(PUBLIC_KEY_RSA2048_PATH)?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000120 Err(AvbSlotVerifyError::PublicKeyRejected),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000121 )
122}
123
124#[test]
Alice Wang5c1a7562023-01-13 17:19:57 +0000125fn payload_with_an_invalid_initrd_fails_verification() -> Result<()> {
126 assert_payload_verification_with_initrd_eq(
127 &load_latest_signed_kernel()?,
128 /*initrd=*/ &fs::read(UNSIGNED_TEST_IMG_PATH)?,
129 &load_trusted_public_key()?,
130 Err(AvbSlotVerifyError::Verification),
131 )
132}
133
134#[test]
Alice Wangbf7fadd2023-01-13 12:18:24 +0000135fn unsigned_kernel_fails_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +0000136 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000137 &fs::read(UNSIGNED_TEST_IMG_PATH)?,
138 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000139 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000140 Err(AvbSlotVerifyError::Io),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000141 )
142}
143
144#[test]
145fn tampered_kernel_fails_verification() -> Result<()> {
146 let mut kernel = load_latest_signed_kernel()?;
147 kernel[1] = !kernel[1]; // Flip the bits
148
Alice Wang2925b0a2023-01-19 10:44:24 +0000149 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000150 &kernel,
151 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000152 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000153 Err(AvbSlotVerifyError::Verification),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000154 )
155}
156
157#[test]
Alice Wangfaceff42023-01-19 09:54:38 +0000158fn kernel_footer_with_vbmeta_offset_overwritten_fails_verification() -> Result<()> {
159 // Arrange.
160 let mut kernel = load_latest_signed_kernel()?;
161 let total_len = kernel.len() as u64;
162 let footer = extract_avb_footer(&kernel)?;
163 assert!(footer.vbmeta_offset < total_len);
164 let vbmeta_offset_addr = ptr::addr_of!(footer.vbmeta_offset) as *const u8;
165 // SAFETY: It is safe as both raw pointers `vbmeta_offset_addr` and `footer` are not null.
166 let vbmeta_offset_start =
167 unsafe { vbmeta_offset_addr.offset_from(ptr::addr_of!(footer) as *const u8) };
168 let footer_start = kernel.len() - size_of::<AvbFooter>();
169 let vbmeta_offset_start = footer_start + usize::try_from(vbmeta_offset_start)?;
170
171 let wrong_offsets = [total_len, u64::MAX];
172 for &wrong_offset in wrong_offsets.iter() {
173 // Act.
174 kernel[vbmeta_offset_start..(vbmeta_offset_start + size_of::<u64>())]
175 .copy_from_slice(&wrong_offset.to_be_bytes());
176
177 // Assert.
178 let footer = extract_avb_footer(&kernel)?;
179 assert_eq!(wrong_offset, footer.vbmeta_offset as u64);
180 assert_payload_verification_with_initrd_eq(
181 &kernel,
182 &load_latest_initrd_normal()?,
183 &load_trusted_public_key()?,
184 Err(AvbSlotVerifyError::Io),
185 )?;
186 }
187 Ok(())
188}
189
190#[test]
Alice Wangbf7fadd2023-01-13 12:18:24 +0000191fn tampered_kernel_footer_fails_verification() -> Result<()> {
192 let mut kernel = load_latest_signed_kernel()?;
193 let avb_footer_index = kernel.len() - size_of::<AvbFooter>() + RANDOM_FOOTER_POS;
194 kernel[avb_footer_index] = !kernel[avb_footer_index];
195
Alice Wang2925b0a2023-01-19 10:44:24 +0000196 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000197 &kernel,
198 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000199 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000200 Err(AvbSlotVerifyError::InvalidMetadata),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000201 )
202}
203
Alice Wang58dac082023-01-13 13:03:59 +0000204#[test]
Alice Wang75d05632023-01-25 13:31:18 +0000205fn extended_initrd_fails_verification() -> Result<()> {
206 let mut initrd = load_latest_initrd_normal()?;
207 initrd.extend(b"androidboot.vbmeta.digest=1111");
208
209 assert_payload_verification_with_initrd_eq(
210 &load_latest_signed_kernel()?,
211 &initrd,
212 &load_trusted_public_key()?,
213 Err(AvbSlotVerifyError::Verification),
214 )
215}
216
217#[test]
Alice Wang58dac082023-01-13 13:03:59 +0000218fn tampered_vbmeta_fails_verification() -> Result<()> {
219 let mut kernel = load_latest_signed_kernel()?;
220 let footer = extract_avb_footer(&kernel)?;
221 let vbmeta_index: usize = (footer.vbmeta_offset + 1).try_into()?;
222
223 kernel[vbmeta_index] = !kernel[vbmeta_index]; // Flip the bits
224
Alice Wang2925b0a2023-01-19 10:44:24 +0000225 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000226 &kernel,
227 &load_latest_initrd_normal()?,
228 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000229 Err(AvbSlotVerifyError::InvalidMetadata),
Alice Wang58dac082023-01-13 13:03:59 +0000230 )
231}
232
233#[test]
234fn vbmeta_with_public_key_overwritten_fails_verification() -> Result<()> {
235 let mut kernel = load_latest_signed_kernel()?;
236 let footer = extract_avb_footer(&kernel)?;
237 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
238 let public_key_offset = footer.vbmeta_offset as usize
239 + size_of::<AvbVBMetaImageHeader>()
240 + vbmeta_header.authentication_data_block_size as usize
241 + vbmeta_header.public_key_offset as usize;
242 let public_key_size: usize = vbmeta_header.public_key_size.try_into()?;
243 let empty_public_key = vec![0u8; public_key_size];
244
245 kernel[public_key_offset..(public_key_offset + public_key_size)]
246 .copy_from_slice(&empty_public_key);
247
Alice Wang2925b0a2023-01-19 10:44:24 +0000248 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000249 &kernel,
250 &load_latest_initrd_normal()?,
251 &empty_public_key,
Alice Wang2925b0a2023-01-19 10:44:24 +0000252 Err(AvbSlotVerifyError::Verification),
Alice Wang58dac082023-01-13 13:03:59 +0000253 )?;
Alice Wang2925b0a2023-01-19 10:44:24 +0000254 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000255 &kernel,
256 &load_latest_initrd_normal()?,
257 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000258 Err(AvbSlotVerifyError::Verification),
Alice Wang58dac082023-01-13 13:03:59 +0000259 )
260}
261
Alice Wangf06bfd72023-01-19 09:24:21 +0000262#[test]
263fn vbmeta_with_verification_flag_disabled_fails_verification() -> Result<()> {
264 // From external/avb/libavb/avb_vbmeta_image.h
265 const AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: u32 = 2;
266
267 // Arrange.
268 let mut kernel = load_latest_signed_kernel()?;
269 let footer = extract_avb_footer(&kernel)?;
270 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
271 assert_eq!(
272 0, vbmeta_header.flags as u32,
273 "The disable flag should not be set in the latest kernel."
274 );
275 let flags_addr = ptr::addr_of!(vbmeta_header.flags) as *const u8;
276 // SAFETY: It is safe as both raw pointers `flags_addr` and `vbmeta_header` are not null.
277 let flags_offset = unsafe { flags_addr.offset_from(ptr::addr_of!(vbmeta_header) as *const u8) };
278 let flags_offset = usize::try_from(footer.vbmeta_offset)? + usize::try_from(flags_offset)?;
279
280 // Act.
281 kernel[flags_offset..(flags_offset + size_of::<u32>())]
282 .copy_from_slice(&AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED.to_be_bytes());
283
284 // Assert.
285 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
286 assert_eq!(
287 AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED, vbmeta_header.flags as u32,
288 "VBMeta verification flag should be disabled now."
289 );
Alice Wang2925b0a2023-01-19 10:44:24 +0000290 assert_payload_verification_with_initrd_eq(
Alice Wangf06bfd72023-01-19 09:24:21 +0000291 &kernel,
292 &load_latest_initrd_normal()?,
293 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000294 Err(AvbSlotVerifyError::Verification),
Alice Wangf06bfd72023-01-19 09:24:21 +0000295 )
296}