blob: 2bd46d532591084f2a3f294695fc7b0ed72ca7b9 [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};
21use pvmfw_avb::AvbSlotVerifyError;
22use 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 Wang2925b0a2023-01-19 10:44:24 +000040 Ok(()),
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 Wang2925b0a2023-01-19 10:44:24 +000050 Ok(()),
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()?,
60 Ok(()),
61 )
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()?,
70 Ok(()),
71 )
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]
125fn unsigned_kernel_fails_verification() -> Result<()> {
Alice Wang2925b0a2023-01-19 10:44:24 +0000126 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000127 &fs::read(UNSIGNED_TEST_IMG_PATH)?,
128 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000129 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000130 Err(AvbSlotVerifyError::Io),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000131 )
132}
133
134#[test]
135fn tampered_kernel_fails_verification() -> Result<()> {
136 let mut kernel = load_latest_signed_kernel()?;
137 kernel[1] = !kernel[1]; // Flip the bits
138
Alice Wang2925b0a2023-01-19 10:44:24 +0000139 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000140 &kernel,
141 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000142 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000143 Err(AvbSlotVerifyError::Verification),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000144 )
145}
146
147#[test]
148fn tampered_kernel_footer_fails_verification() -> Result<()> {
149 let mut kernel = load_latest_signed_kernel()?;
150 let avb_footer_index = kernel.len() - size_of::<AvbFooter>() + RANDOM_FOOTER_POS;
151 kernel[avb_footer_index] = !kernel[avb_footer_index];
152
Alice Wang2925b0a2023-01-19 10:44:24 +0000153 assert_payload_verification_with_initrd_eq(
Alice Wangbf7fadd2023-01-13 12:18:24 +0000154 &kernel,
155 &load_latest_initrd_normal()?,
Alice Wang4e55dd92023-01-11 10:17:01 +0000156 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000157 Err(AvbSlotVerifyError::InvalidMetadata),
Alice Wangbf7fadd2023-01-13 12:18:24 +0000158 )
159}
160
Alice Wang58dac082023-01-13 13:03:59 +0000161#[test]
162fn tampered_vbmeta_fails_verification() -> Result<()> {
163 let mut kernel = load_latest_signed_kernel()?;
164 let footer = extract_avb_footer(&kernel)?;
165 let vbmeta_index: usize = (footer.vbmeta_offset + 1).try_into()?;
166
167 kernel[vbmeta_index] = !kernel[vbmeta_index]; // Flip the bits
168
Alice Wang2925b0a2023-01-19 10:44:24 +0000169 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000170 &kernel,
171 &load_latest_initrd_normal()?,
172 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000173 Err(AvbSlotVerifyError::InvalidMetadata),
Alice Wang58dac082023-01-13 13:03:59 +0000174 )
175}
176
177#[test]
178fn vbmeta_with_public_key_overwritten_fails_verification() -> Result<()> {
179 let mut kernel = load_latest_signed_kernel()?;
180 let footer = extract_avb_footer(&kernel)?;
181 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
182 let public_key_offset = footer.vbmeta_offset as usize
183 + size_of::<AvbVBMetaImageHeader>()
184 + vbmeta_header.authentication_data_block_size as usize
185 + vbmeta_header.public_key_offset as usize;
186 let public_key_size: usize = vbmeta_header.public_key_size.try_into()?;
187 let empty_public_key = vec![0u8; public_key_size];
188
189 kernel[public_key_offset..(public_key_offset + public_key_size)]
190 .copy_from_slice(&empty_public_key);
191
Alice Wang2925b0a2023-01-19 10:44:24 +0000192 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000193 &kernel,
194 &load_latest_initrd_normal()?,
195 &empty_public_key,
Alice Wang2925b0a2023-01-19 10:44:24 +0000196 Err(AvbSlotVerifyError::Verification),
Alice Wang58dac082023-01-13 13:03:59 +0000197 )?;
Alice Wang2925b0a2023-01-19 10:44:24 +0000198 assert_payload_verification_with_initrd_eq(
Alice Wang58dac082023-01-13 13:03:59 +0000199 &kernel,
200 &load_latest_initrd_normal()?,
201 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000202 Err(AvbSlotVerifyError::Verification),
Alice Wang58dac082023-01-13 13:03:59 +0000203 )
204}
205
Alice Wangf06bfd72023-01-19 09:24:21 +0000206#[test]
207fn vbmeta_with_verification_flag_disabled_fails_verification() -> Result<()> {
208 // From external/avb/libavb/avb_vbmeta_image.h
209 const AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: u32 = 2;
210
211 // Arrange.
212 let mut kernel = load_latest_signed_kernel()?;
213 let footer = extract_avb_footer(&kernel)?;
214 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
215 assert_eq!(
216 0, vbmeta_header.flags as u32,
217 "The disable flag should not be set in the latest kernel."
218 );
219 let flags_addr = ptr::addr_of!(vbmeta_header.flags) as *const u8;
220 // SAFETY: It is safe as both raw pointers `flags_addr` and `vbmeta_header` are not null.
221 let flags_offset = unsafe { flags_addr.offset_from(ptr::addr_of!(vbmeta_header) as *const u8) };
222 let flags_offset = usize::try_from(footer.vbmeta_offset)? + usize::try_from(flags_offset)?;
223
224 // Act.
225 kernel[flags_offset..(flags_offset + size_of::<u32>())]
226 .copy_from_slice(&AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED.to_be_bytes());
227
228 // Assert.
229 let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
230 assert_eq!(
231 AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED, vbmeta_header.flags as u32,
232 "VBMeta verification flag should be disabled now."
233 );
Alice Wang2925b0a2023-01-19 10:44:24 +0000234 assert_payload_verification_with_initrd_eq(
Alice Wangf06bfd72023-01-19 09:24:21 +0000235 &kernel,
236 &load_latest_initrd_normal()?,
237 &load_trusted_public_key()?,
Alice Wang2925b0a2023-01-19 10:44:24 +0000238 Err(AvbSlotVerifyError::Verification),
Alice Wangf06bfd72023-01-19 09:24:21 +0000239 )
240}