1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2021 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker *
5*8617a60dSAndroid Build Coastguard Worker * Functions for reading, checking and verifying firmware and
6*8617a60dSAndroid Build Coastguard Worker * kernel data structures.
7*8617a60dSAndroid Build Coastguard Worker */
8*8617a60dSAndroid Build Coastguard Worker
9*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
10*8617a60dSAndroid Build Coastguard Worker
vb2_check_keyblock(const struct vb2_keyblock * block,uint32_t size,const struct vb2_signature * sig)11*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_check_keyblock(const struct vb2_keyblock *block, uint32_t size,
12*8617a60dSAndroid Build Coastguard Worker const struct vb2_signature *sig)
13*8617a60dSAndroid Build Coastguard Worker {
14*8617a60dSAndroid Build Coastguard Worker if (size < sizeof(*block)) {
15*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough space for keyblock header.\n");
16*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_TOO_SMALL_FOR_HEADER;
17*8617a60dSAndroid Build Coastguard Worker }
18*8617a60dSAndroid Build Coastguard Worker
19*8617a60dSAndroid Build Coastguard Worker if (memcmp(block->magic, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE)) {
20*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not a valid verified boot keyblock.\n");
21*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_MAGIC;
22*8617a60dSAndroid Build Coastguard Worker }
23*8617a60dSAndroid Build Coastguard Worker
24*8617a60dSAndroid Build Coastguard Worker if (block->header_version_major != VB2_KEYBLOCK_VERSION_MAJOR) {
25*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Incompatible keyblock header version.\n");
26*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_HEADER_VERSION;
27*8617a60dSAndroid Build Coastguard Worker }
28*8617a60dSAndroid Build Coastguard Worker
29*8617a60dSAndroid Build Coastguard Worker if (size < block->keyblock_size) {
30*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough data for keyblock.\n");
31*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_SIZE;
32*8617a60dSAndroid Build Coastguard Worker }
33*8617a60dSAndroid Build Coastguard Worker
34*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_signature_inside(block, block->keyblock_size, sig)) {
35*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Keyblock signature off end of block\n");
36*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_SIG_OUTSIDE;
37*8617a60dSAndroid Build Coastguard Worker }
38*8617a60dSAndroid Build Coastguard Worker
39*8617a60dSAndroid Build Coastguard Worker /* Make sure advertised signature data sizes are valid. */
40*8617a60dSAndroid Build Coastguard Worker if (block->keyblock_size < sig->data_size) {
41*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Signature calculated past end of block\n");
42*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_SIGNED_TOO_MUCH;
43*8617a60dSAndroid Build Coastguard Worker }
44*8617a60dSAndroid Build Coastguard Worker
45*8617a60dSAndroid Build Coastguard Worker /* Verify we signed enough data */
46*8617a60dSAndroid Build Coastguard Worker if (sig->data_size < sizeof(struct vb2_keyblock)) {
47*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Didn't sign enough data\n");
48*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_SIGNED_TOO_LITTLE;
49*8617a60dSAndroid Build Coastguard Worker }
50*8617a60dSAndroid Build Coastguard Worker
51*8617a60dSAndroid Build Coastguard Worker /* Verify data key is inside the block and inside signed data */
52*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_packed_key_inside(block, block->keyblock_size,
53*8617a60dSAndroid Build Coastguard Worker &block->data_key)) {
54*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Data key off end of keyblock\n");
55*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_DATA_KEY_OUTSIDE;
56*8617a60dSAndroid Build Coastguard Worker }
57*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_packed_key_inside(block, sig->data_size,
58*8617a60dSAndroid Build Coastguard Worker &block->data_key)) {
59*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Data key off end of signed data\n");
60*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_DATA_KEY_UNSIGNED;
61*8617a60dSAndroid Build Coastguard Worker }
62*8617a60dSAndroid Build Coastguard Worker
63*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
64*8617a60dSAndroid Build Coastguard Worker }
65*8617a60dSAndroid Build Coastguard Worker
66*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_verify_keyblock(struct vb2_keyblock * block,uint32_t size,const struct vb2_public_key * key,const struct vb2_workbuf * wb)67*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_verify_keyblock(struct vb2_keyblock *block, uint32_t size,
68*8617a60dSAndroid Build Coastguard Worker const struct vb2_public_key *key,
69*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
70*8617a60dSAndroid Build Coastguard Worker {
71*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig = &block->keyblock_signature;
72*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
73*8617a60dSAndroid Build Coastguard Worker
74*8617a60dSAndroid Build Coastguard Worker /* Validity check keyblock before attempting signature check of data */
75*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_check_keyblock(block, size, sig));
76*8617a60dSAndroid Build Coastguard Worker
77*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Checking keyblock signature...\n");
78*8617a60dSAndroid Build Coastguard Worker rv = vb2_verify_data((const uint8_t *)block, size, sig, key, wb);
79*8617a60dSAndroid Build Coastguard Worker if (rv) {
80*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Invalid keyblock signature.\n");
81*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_SIG_INVALID;
82*8617a60dSAndroid Build Coastguard Worker }
83*8617a60dSAndroid Build Coastguard Worker
84*8617a60dSAndroid Build Coastguard Worker /* Success */
85*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
86*8617a60dSAndroid Build Coastguard Worker }
87*8617a60dSAndroid Build Coastguard Worker
vb2_verify_fw_preamble(struct vb2_fw_preamble * preamble,uint32_t size,const struct vb2_public_key * key,const struct vb2_workbuf * wb)88*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_verify_fw_preamble(struct vb2_fw_preamble *preamble,
89*8617a60dSAndroid Build Coastguard Worker uint32_t size,
90*8617a60dSAndroid Build Coastguard Worker const struct vb2_public_key *key,
91*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
92*8617a60dSAndroid Build Coastguard Worker {
93*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig = &preamble->preamble_signature;
94*8617a60dSAndroid Build Coastguard Worker
95*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Verifying preamble.\n");
96*8617a60dSAndroid Build Coastguard Worker
97*8617a60dSAndroid Build Coastguard Worker /* Validity checks before attempting signature of data */
98*8617a60dSAndroid Build Coastguard Worker if (size < sizeof(*preamble)) {
99*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough data for preamble header\n");
100*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
101*8617a60dSAndroid Build Coastguard Worker }
102*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_major !=
103*8617a60dSAndroid Build Coastguard Worker VB2_FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR) {
104*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Incompatible firmware preamble header version.\n");
105*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_HEADER_VERSION;
106*8617a60dSAndroid Build Coastguard Worker }
107*8617a60dSAndroid Build Coastguard Worker
108*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_minor < 1) {
109*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Only preamble header 2.1+ supported\n");
110*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_HEADER_OLD;
111*8617a60dSAndroid Build Coastguard Worker }
112*8617a60dSAndroid Build Coastguard Worker
113*8617a60dSAndroid Build Coastguard Worker if (size < preamble->preamble_size) {
114*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough data for preamble.\n");
115*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIZE;
116*8617a60dSAndroid Build Coastguard Worker }
117*8617a60dSAndroid Build Coastguard Worker
118*8617a60dSAndroid Build Coastguard Worker /* Check signature */
119*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_signature_inside(preamble, preamble->preamble_size,
120*8617a60dSAndroid Build Coastguard Worker sig)) {
121*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Preamble signature off end of preamble\n");
122*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIG_OUTSIDE;
123*8617a60dSAndroid Build Coastguard Worker }
124*8617a60dSAndroid Build Coastguard Worker
125*8617a60dSAndroid Build Coastguard Worker /* Make sure advertised signature data sizes are valid. */
126*8617a60dSAndroid Build Coastguard Worker if (preamble->preamble_size < sig->data_size) {
127*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Signature calculated past end of the block\n");
128*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH;
129*8617a60dSAndroid Build Coastguard Worker }
130*8617a60dSAndroid Build Coastguard Worker
131*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) {
132*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Preamble signature validation failed\n");
133*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIG_INVALID;
134*8617a60dSAndroid Build Coastguard Worker }
135*8617a60dSAndroid Build Coastguard Worker
136*8617a60dSAndroid Build Coastguard Worker /* Verify we signed enough data */
137*8617a60dSAndroid Build Coastguard Worker if (sig->data_size < sizeof(struct vb2_fw_preamble)) {
138*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Didn't sign enough data\n");
139*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE;
140*8617a60dSAndroid Build Coastguard Worker }
141*8617a60dSAndroid Build Coastguard Worker
142*8617a60dSAndroid Build Coastguard Worker /* Verify body signature is inside the signed data */
143*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_signature_inside(preamble, sig->data_size,
144*8617a60dSAndroid Build Coastguard Worker &preamble->body_signature)) {
145*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Firmware body signature off end of preamble\n");
146*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE;
147*8617a60dSAndroid Build Coastguard Worker }
148*8617a60dSAndroid Build Coastguard Worker
149*8617a60dSAndroid Build Coastguard Worker /* Verify kernel subkey is inside the signed data */
150*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_packed_key_inside(preamble, sig->data_size,
151*8617a60dSAndroid Build Coastguard Worker &preamble->kernel_subkey)) {
152*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Kernel subkey off end of preamble\n");
153*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_KERNEL_SUBKEY_OUTSIDE;
154*8617a60dSAndroid Build Coastguard Worker }
155*8617a60dSAndroid Build Coastguard Worker
156*8617a60dSAndroid Build Coastguard Worker /* Success */
157*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
158*8617a60dSAndroid Build Coastguard Worker }
159*8617a60dSAndroid Build Coastguard Worker
vb2_kernel_get_flags(const struct vb2_kernel_preamble * preamble)160*8617a60dSAndroid Build Coastguard Worker uint32_t vb2_kernel_get_flags(const struct vb2_kernel_preamble *preamble)
161*8617a60dSAndroid Build Coastguard Worker {
162*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_minor < 2)
163*8617a60dSAndroid Build Coastguard Worker return 0;
164*8617a60dSAndroid Build Coastguard Worker
165*8617a60dSAndroid Build Coastguard Worker return preamble->flags;
166*8617a60dSAndroid Build Coastguard Worker }
167*8617a60dSAndroid Build Coastguard Worker
168*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_verify_keyblock_hash(const struct vb2_keyblock * block,uint32_t size,const struct vb2_workbuf * wb)169*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_verify_keyblock_hash(const struct vb2_keyblock *block,
170*8617a60dSAndroid Build Coastguard Worker uint32_t size,
171*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
172*8617a60dSAndroid Build Coastguard Worker {
173*8617a60dSAndroid Build Coastguard Worker const struct vb2_signature *sig = &block->keyblock_hash;
174*8617a60dSAndroid Build Coastguard Worker struct vb2_hash hash;
175*8617a60dSAndroid Build Coastguard Worker
176*8617a60dSAndroid Build Coastguard Worker /* Validity check keyblock before attempting hash check of data */
177*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_check_keyblock(block, size, sig));
178*8617a60dSAndroid Build Coastguard Worker
179*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Checking keyblock hash...\n");
180*8617a60dSAndroid Build Coastguard Worker
181*8617a60dSAndroid Build Coastguard Worker /* This is only used in developer mode, so hwcrypto not important. */
182*8617a60dSAndroid Build Coastguard Worker VB2_TRY(vb2_hash_calculate(false, block, sig->data_size,
183*8617a60dSAndroid Build Coastguard Worker VB2_HASH_SHA512, &hash));
184*8617a60dSAndroid Build Coastguard Worker
185*8617a60dSAndroid Build Coastguard Worker if (vb2_safe_memcmp(vb2_signature_data(sig), hash.sha512,
186*8617a60dSAndroid Build Coastguard Worker sizeof(hash.sha512)) != 0) {
187*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Invalid keyblock hash.\n");
188*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_KEYBLOCK_HASH_INVALID_IN_DEV_MODE;
189*8617a60dSAndroid Build Coastguard Worker }
190*8617a60dSAndroid Build Coastguard Worker
191*8617a60dSAndroid Build Coastguard Worker /* Success */
192*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
193*8617a60dSAndroid Build Coastguard Worker }
194*8617a60dSAndroid Build Coastguard Worker
195*8617a60dSAndroid Build Coastguard Worker test_mockable
vb2_verify_kernel_preamble(struct vb2_kernel_preamble * preamble,uint32_t size,const struct vb2_public_key * key,const struct vb2_workbuf * wb)196*8617a60dSAndroid Build Coastguard Worker vb2_error_t vb2_verify_kernel_preamble(struct vb2_kernel_preamble *preamble,
197*8617a60dSAndroid Build Coastguard Worker uint32_t size,
198*8617a60dSAndroid Build Coastguard Worker const struct vb2_public_key *key,
199*8617a60dSAndroid Build Coastguard Worker const struct vb2_workbuf *wb)
200*8617a60dSAndroid Build Coastguard Worker {
201*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sig = &preamble->preamble_signature;
202*8617a60dSAndroid Build Coastguard Worker uint32_t min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_0_SIZE;
203*8617a60dSAndroid Build Coastguard Worker
204*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Verifying kernel preamble.\n");
205*8617a60dSAndroid Build Coastguard Worker
206*8617a60dSAndroid Build Coastguard Worker /* Make sure it's even safe to look at the struct */
207*8617a60dSAndroid Build Coastguard Worker if (size < min_size) {
208*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough data for preamble header.\n");
209*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
210*8617a60dSAndroid Build Coastguard Worker }
211*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_major !=
212*8617a60dSAndroid Build Coastguard Worker VB2_KERNEL_PREAMBLE_HEADER_VERSION_MAJOR) {
213*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Incompatible kernel preamble header version.\n");
214*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_HEADER_VERSION;
215*8617a60dSAndroid Build Coastguard Worker }
216*8617a60dSAndroid Build Coastguard Worker
217*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_minor >= 2)
218*8617a60dSAndroid Build Coastguard Worker min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_2_SIZE;
219*8617a60dSAndroid Build Coastguard Worker else if (preamble->header_version_minor == 1)
220*8617a60dSAndroid Build Coastguard Worker min_size = EXPECTED_VB2_KERNEL_PREAMBLE_2_1_SIZE;
221*8617a60dSAndroid Build Coastguard Worker if (preamble->preamble_size < min_size) {
222*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Preamble size too small for header.\n");
223*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_TOO_SMALL_FOR_HEADER;
224*8617a60dSAndroid Build Coastguard Worker }
225*8617a60dSAndroid Build Coastguard Worker if (size < preamble->preamble_size) {
226*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Not enough data for preamble.\n");
227*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIZE;
228*8617a60dSAndroid Build Coastguard Worker }
229*8617a60dSAndroid Build Coastguard Worker
230*8617a60dSAndroid Build Coastguard Worker /* Check signature */
231*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_signature_inside(preamble, preamble->preamble_size,
232*8617a60dSAndroid Build Coastguard Worker sig)) {
233*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Preamble signature off end of preamble\n");
234*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIG_OUTSIDE;
235*8617a60dSAndroid Build Coastguard Worker }
236*8617a60dSAndroid Build Coastguard Worker
237*8617a60dSAndroid Build Coastguard Worker /* Make sure advertised signature data sizes are valid. */
238*8617a60dSAndroid Build Coastguard Worker if (preamble->preamble_size < sig->data_size) {
239*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Signature calculated past end of the block\n");
240*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIGNED_TOO_MUCH;
241*8617a60dSAndroid Build Coastguard Worker }
242*8617a60dSAndroid Build Coastguard Worker
243*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_data((const uint8_t *)preamble, size, sig, key, wb)) {
244*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Preamble signature validation failed\n");
245*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIG_INVALID;
246*8617a60dSAndroid Build Coastguard Worker }
247*8617a60dSAndroid Build Coastguard Worker
248*8617a60dSAndroid Build Coastguard Worker /* Verify we signed enough data */
249*8617a60dSAndroid Build Coastguard Worker if (sig->data_size < sizeof(struct vb2_fw_preamble)) {
250*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Didn't sign enough data\n");
251*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_SIGNED_TOO_LITTLE;
252*8617a60dSAndroid Build Coastguard Worker }
253*8617a60dSAndroid Build Coastguard Worker
254*8617a60dSAndroid Build Coastguard Worker /* Verify body signature is inside the signed data */
255*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_signature_inside(preamble, sig->data_size,
256*8617a60dSAndroid Build Coastguard Worker &preamble->body_signature)) {
257*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Body signature off end of preamble\n");
258*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_BODY_SIG_OUTSIDE;
259*8617a60dSAndroid Build Coastguard Worker }
260*8617a60dSAndroid Build Coastguard Worker
261*8617a60dSAndroid Build Coastguard Worker /*
262*8617a60dSAndroid Build Coastguard Worker * If bootloader is present, verify it's covered by the body
263*8617a60dSAndroid Build Coastguard Worker * signature.
264*8617a60dSAndroid Build Coastguard Worker */
265*8617a60dSAndroid Build Coastguard Worker if (preamble->bootloader_size) {
266*8617a60dSAndroid Build Coastguard Worker const void *body_ptr =
267*8617a60dSAndroid Build Coastguard Worker (const void *)(uintptr_t)preamble->body_load_address;
268*8617a60dSAndroid Build Coastguard Worker const void *bootloader_ptr =
269*8617a60dSAndroid Build Coastguard Worker (const void *)(uintptr_t)preamble->bootloader_address;
270*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_member_inside(body_ptr,
271*8617a60dSAndroid Build Coastguard Worker preamble->body_signature.data_size,
272*8617a60dSAndroid Build Coastguard Worker bootloader_ptr,
273*8617a60dSAndroid Build Coastguard Worker preamble->bootloader_size,
274*8617a60dSAndroid Build Coastguard Worker 0, 0)) {
275*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Bootloader off end of signed data\n");
276*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_BOOTLOADER_OUTSIDE;
277*8617a60dSAndroid Build Coastguard Worker }
278*8617a60dSAndroid Build Coastguard Worker }
279*8617a60dSAndroid Build Coastguard Worker
280*8617a60dSAndroid Build Coastguard Worker /*
281*8617a60dSAndroid Build Coastguard Worker * If vmlinuz header is present, verify it's covered by the body
282*8617a60dSAndroid Build Coastguard Worker * signature.
283*8617a60dSAndroid Build Coastguard Worker */
284*8617a60dSAndroid Build Coastguard Worker if (preamble->header_version_minor >= 1 &&
285*8617a60dSAndroid Build Coastguard Worker preamble->vmlinuz_header_size) {
286*8617a60dSAndroid Build Coastguard Worker const void *body_ptr =
287*8617a60dSAndroid Build Coastguard Worker (const void *)(uintptr_t)preamble->body_load_address;
288*8617a60dSAndroid Build Coastguard Worker const void *vmlinuz_header_ptr = (const void *)
289*8617a60dSAndroid Build Coastguard Worker (uintptr_t)preamble->vmlinuz_header_address;
290*8617a60dSAndroid Build Coastguard Worker if (vb2_verify_member_inside(body_ptr,
291*8617a60dSAndroid Build Coastguard Worker preamble->body_signature.data_size,
292*8617a60dSAndroid Build Coastguard Worker vmlinuz_header_ptr,
293*8617a60dSAndroid Build Coastguard Worker preamble->vmlinuz_header_size,
294*8617a60dSAndroid Build Coastguard Worker 0, 0)) {
295*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Vmlinuz header off end of signed data\n");
296*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_PREAMBLE_VMLINUZ_HEADER_OUTSIDE;
297*8617a60dSAndroid Build Coastguard Worker }
298*8617a60dSAndroid Build Coastguard Worker }
299*8617a60dSAndroid Build Coastguard Worker
300*8617a60dSAndroid Build Coastguard Worker /* Success */
301*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
302*8617a60dSAndroid Build Coastguard Worker }
303