xref: /aosp_15_r20/external/vboot_reference/host/lib/host_common.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2013 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  * Host functions for verified boot.
6*8617a60dSAndroid Build Coastguard Worker  */
7*8617a60dSAndroid Build Coastguard Worker 
8*8617a60dSAndroid Build Coastguard Worker #include <string.h>
9*8617a60dSAndroid Build Coastguard Worker 
10*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
11*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
12*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
13*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
14*8617a60dSAndroid Build Coastguard Worker #include "host_key21.h"
15*8617a60dSAndroid Build Coastguard Worker 
vb2_create_fw_preamble(uint32_t firmware_version,const struct vb2_packed_key * kernel_subkey,const struct vb2_signature * body_signature,const struct vb2_private_key * signing_key,uint32_t flags)16*8617a60dSAndroid Build Coastguard Worker struct vb2_fw_preamble *vb2_create_fw_preamble(
17*8617a60dSAndroid Build Coastguard Worker 	uint32_t firmware_version,
18*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_packed_key *kernel_subkey,
19*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_signature *body_signature,
20*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_private_key *signing_key,
21*8617a60dSAndroid Build Coastguard Worker 	uint32_t flags)
22*8617a60dSAndroid Build Coastguard Worker {
23*8617a60dSAndroid Build Coastguard Worker 	uint32_t signed_size = (sizeof(struct vb2_fw_preamble) +
24*8617a60dSAndroid Build Coastguard Worker 				kernel_subkey->key_size +
25*8617a60dSAndroid Build Coastguard Worker 				body_signature->sig_size);
26*8617a60dSAndroid Build Coastguard Worker 	uint32_t block_size = signed_size +
27*8617a60dSAndroid Build Coastguard Worker 		vb2_rsa_sig_size(signing_key->sig_alg);
28*8617a60dSAndroid Build Coastguard Worker 
29*8617a60dSAndroid Build Coastguard Worker 	/* Allocate keyblock */
30*8617a60dSAndroid Build Coastguard Worker 	struct vb2_fw_preamble *h =
31*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_fw_preamble *)calloc(block_size, 1);
32*8617a60dSAndroid Build Coastguard Worker 	if (!h)
33*8617a60dSAndroid Build Coastguard Worker 		return NULL;
34*8617a60dSAndroid Build Coastguard Worker 
35*8617a60dSAndroid Build Coastguard Worker 	uint8_t *kernel_subkey_dest = (uint8_t *)(h + 1);
36*8617a60dSAndroid Build Coastguard Worker 	uint8_t *body_sig_dest = kernel_subkey_dest + kernel_subkey->key_size;
37*8617a60dSAndroid Build Coastguard Worker 	uint8_t *block_sig_dest = body_sig_dest + body_signature->sig_size;
38*8617a60dSAndroid Build Coastguard Worker 
39*8617a60dSAndroid Build Coastguard Worker 	h->header_version_major = VB2_FIRMWARE_PREAMBLE_HEADER_VERSION_MAJOR;
40*8617a60dSAndroid Build Coastguard Worker 	h->header_version_minor = VB2_FIRMWARE_PREAMBLE_HEADER_VERSION_MINOR;
41*8617a60dSAndroid Build Coastguard Worker 	h->preamble_size = block_size;
42*8617a60dSAndroid Build Coastguard Worker 	h->firmware_version = firmware_version;
43*8617a60dSAndroid Build Coastguard Worker 	h->flags = flags;
44*8617a60dSAndroid Build Coastguard Worker 
45*8617a60dSAndroid Build Coastguard Worker 	/* Copy data key */
46*8617a60dSAndroid Build Coastguard Worker 	vb2_init_packed_key(&h->kernel_subkey, kernel_subkey_dest,
47*8617a60dSAndroid Build Coastguard Worker 			    kernel_subkey->key_size);
48*8617a60dSAndroid Build Coastguard Worker 	if (VB2_SUCCESS !=
49*8617a60dSAndroid Build Coastguard Worker 	    vb2_copy_packed_key(&h->kernel_subkey, kernel_subkey)) {
50*8617a60dSAndroid Build Coastguard Worker 		free(h);
51*8617a60dSAndroid Build Coastguard Worker 		return NULL;
52*8617a60dSAndroid Build Coastguard Worker 	}
53*8617a60dSAndroid Build Coastguard Worker 
54*8617a60dSAndroid Build Coastguard Worker 	/* Copy body signature */
55*8617a60dSAndroid Build Coastguard Worker 	vb2_init_signature(&h->body_signature,
56*8617a60dSAndroid Build Coastguard Worker 			   body_sig_dest, body_signature->sig_size, 0);
57*8617a60dSAndroid Build Coastguard Worker 	if (VB2_SUCCESS !=
58*8617a60dSAndroid Build Coastguard Worker 	    vb2_copy_signature(&h->body_signature, body_signature)) {
59*8617a60dSAndroid Build Coastguard Worker 		free(h);
60*8617a60dSAndroid Build Coastguard Worker 		return NULL;
61*8617a60dSAndroid Build Coastguard Worker 	}
62*8617a60dSAndroid Build Coastguard Worker 
63*8617a60dSAndroid Build Coastguard Worker 	/* Set up signature struct so we can calculate the signature */
64*8617a60dSAndroid Build Coastguard Worker 	vb2_init_signature(&h->preamble_signature, block_sig_dest,
65*8617a60dSAndroid Build Coastguard Worker 			   vb2_rsa_sig_size(signing_key->sig_alg), signed_size);
66*8617a60dSAndroid Build Coastguard Worker 
67*8617a60dSAndroid Build Coastguard Worker 	/* Calculate signature */
68*8617a60dSAndroid Build Coastguard Worker 	struct vb2_signature *sig =
69*8617a60dSAndroid Build Coastguard Worker 		vb2_calculate_signature((uint8_t *)h, signed_size, signing_key);
70*8617a60dSAndroid Build Coastguard Worker 	vb2_copy_signature(&h->preamble_signature, sig);
71*8617a60dSAndroid Build Coastguard Worker 	free(sig);
72*8617a60dSAndroid Build Coastguard Worker 
73*8617a60dSAndroid Build Coastguard Worker 	/* Return the header */
74*8617a60dSAndroid Build Coastguard Worker 	return h;
75*8617a60dSAndroid Build Coastguard Worker }
76*8617a60dSAndroid Build Coastguard Worker 
vb2_create_kernel_preamble(uint32_t kernel_version,uint64_t body_load_address,uint64_t bootloader_address,uint32_t bootloader_size,const struct vb2_signature * body_signature,uint64_t vmlinuz_header_address,uint32_t vmlinuz_header_size,uint32_t flags,uint32_t desired_size,const struct vb2_private_key * signing_key)77*8617a60dSAndroid Build Coastguard Worker struct vb2_kernel_preamble *vb2_create_kernel_preamble(
78*8617a60dSAndroid Build Coastguard Worker 	uint32_t kernel_version,
79*8617a60dSAndroid Build Coastguard Worker 	uint64_t body_load_address,
80*8617a60dSAndroid Build Coastguard Worker 	uint64_t bootloader_address,
81*8617a60dSAndroid Build Coastguard Worker 	uint32_t bootloader_size,
82*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_signature *body_signature,
83*8617a60dSAndroid Build Coastguard Worker 	uint64_t vmlinuz_header_address,
84*8617a60dSAndroid Build Coastguard Worker 	uint32_t vmlinuz_header_size,
85*8617a60dSAndroid Build Coastguard Worker 	uint32_t flags,
86*8617a60dSAndroid Build Coastguard Worker 	uint32_t desired_size,
87*8617a60dSAndroid Build Coastguard Worker 	const struct vb2_private_key *signing_key)
88*8617a60dSAndroid Build Coastguard Worker {
89*8617a60dSAndroid Build Coastguard Worker 	uint64_t signed_size = (sizeof(struct vb2_kernel_preamble) +
90*8617a60dSAndroid Build Coastguard Worker 				body_signature->sig_size);
91*8617a60dSAndroid Build Coastguard Worker 	uint32_t sig_size = vb2_rsa_sig_size(signing_key->sig_alg);
92*8617a60dSAndroid Build Coastguard Worker 	uint32_t block_size = signed_size + sig_size;
93*8617a60dSAndroid Build Coastguard Worker 
94*8617a60dSAndroid Build Coastguard Worker 	/* If the block size is smaller than the desired size, pad it */
95*8617a60dSAndroid Build Coastguard Worker 	if (block_size < desired_size)
96*8617a60dSAndroid Build Coastguard Worker 		block_size = desired_size;
97*8617a60dSAndroid Build Coastguard Worker 
98*8617a60dSAndroid Build Coastguard Worker 	/* Allocate keyblock */
99*8617a60dSAndroid Build Coastguard Worker 	struct vb2_kernel_preamble *h =
100*8617a60dSAndroid Build Coastguard Worker 		(struct vb2_kernel_preamble *)calloc(block_size, 1);
101*8617a60dSAndroid Build Coastguard Worker 	if (!h)
102*8617a60dSAndroid Build Coastguard Worker 		return NULL;
103*8617a60dSAndroid Build Coastguard Worker 
104*8617a60dSAndroid Build Coastguard Worker 	uint8_t *body_sig_dest = (uint8_t *)(h + 1);
105*8617a60dSAndroid Build Coastguard Worker 	uint8_t *block_sig_dest = body_sig_dest + body_signature->sig_size;
106*8617a60dSAndroid Build Coastguard Worker 
107*8617a60dSAndroid Build Coastguard Worker 	h->header_version_major = VB2_KERNEL_PREAMBLE_HEADER_VERSION_MAJOR;
108*8617a60dSAndroid Build Coastguard Worker 	h->header_version_minor = VB2_KERNEL_PREAMBLE_HEADER_VERSION_MINOR;
109*8617a60dSAndroid Build Coastguard Worker 	h->preamble_size = block_size;
110*8617a60dSAndroid Build Coastguard Worker 	h->kernel_version = kernel_version;
111*8617a60dSAndroid Build Coastguard Worker 	h->body_load_address = body_load_address;
112*8617a60dSAndroid Build Coastguard Worker 	h->bootloader_address = bootloader_address;
113*8617a60dSAndroid Build Coastguard Worker 	h->bootloader_size = bootloader_size;
114*8617a60dSAndroid Build Coastguard Worker 	h->vmlinuz_header_address = vmlinuz_header_address;
115*8617a60dSAndroid Build Coastguard Worker 	h->vmlinuz_header_size = vmlinuz_header_size;
116*8617a60dSAndroid Build Coastguard Worker 	h->flags = flags;
117*8617a60dSAndroid Build Coastguard Worker 
118*8617a60dSAndroid Build Coastguard Worker 	/* Copy body signature */
119*8617a60dSAndroid Build Coastguard Worker 	vb2_init_signature(&h->body_signature, body_sig_dest,
120*8617a60dSAndroid Build Coastguard Worker 			   body_signature->sig_size, 0);
121*8617a60dSAndroid Build Coastguard Worker 	vb2_copy_signature(&h->body_signature, body_signature);
122*8617a60dSAndroid Build Coastguard Worker 
123*8617a60dSAndroid Build Coastguard Worker 	/* Set up signature struct so we can calculate the signature */
124*8617a60dSAndroid Build Coastguard Worker 	vb2_init_signature(&h->preamble_signature, block_sig_dest,
125*8617a60dSAndroid Build Coastguard Worker 			   sig_size, signed_size);
126*8617a60dSAndroid Build Coastguard Worker 
127*8617a60dSAndroid Build Coastguard Worker 	/* Calculate signature */
128*8617a60dSAndroid Build Coastguard Worker 	struct vb2_signature *sigtmp =
129*8617a60dSAndroid Build Coastguard Worker 		vb2_calculate_signature((uint8_t *)h, signed_size, signing_key);
130*8617a60dSAndroid Build Coastguard Worker 	vb2_copy_signature(&h->preamble_signature, sigtmp);
131*8617a60dSAndroid Build Coastguard Worker 	free(sigtmp);
132*8617a60dSAndroid Build Coastguard Worker 
133*8617a60dSAndroid Build Coastguard Worker 	/* Return the header */
134*8617a60dSAndroid Build Coastguard Worker 	return h;
135*8617a60dSAndroid Build Coastguard Worker }
136*8617a60dSAndroid Build Coastguard Worker 
vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble * preamble,uint64_t * vmlinuz_header_address,uint32_t * vmlinuz_header_size)137*8617a60dSAndroid Build Coastguard Worker void vb2_kernel_get_vmlinuz_header(const struct vb2_kernel_preamble *preamble,
138*8617a60dSAndroid Build Coastguard Worker 				   uint64_t *vmlinuz_header_address,
139*8617a60dSAndroid Build Coastguard Worker 				   uint32_t *vmlinuz_header_size)
140*8617a60dSAndroid Build Coastguard Worker {
141*8617a60dSAndroid Build Coastguard Worker 	if (preamble->header_version_minor < 1) {
142*8617a60dSAndroid Build Coastguard Worker 		*vmlinuz_header_address = 0;
143*8617a60dSAndroid Build Coastguard Worker 		*vmlinuz_header_size = 0;
144*8617a60dSAndroid Build Coastguard Worker 	} else {
145*8617a60dSAndroid Build Coastguard Worker 		/*
146*8617a60dSAndroid Build Coastguard Worker 		 * Set header and size only if the preamble header version is >
147*8617a60dSAndroid Build Coastguard Worker 		 * 2.1 as they don't exist in version 2.0 (Note that we don't
148*8617a60dSAndroid Build Coastguard Worker 		 * need to check header_version_major; if that's not 2 then
149*8617a60dSAndroid Build Coastguard Worker 		 * vb2_verify_kernel_preamble() would have already failed.
150*8617a60dSAndroid Build Coastguard Worker 		 */
151*8617a60dSAndroid Build Coastguard Worker 		*vmlinuz_header_address = preamble->vmlinuz_header_address;
152*8617a60dSAndroid Build Coastguard Worker 		*vmlinuz_header_size = preamble->vmlinuz_header_size;
153*8617a60dSAndroid Build Coastguard Worker 	}
154*8617a60dSAndroid Build Coastguard Worker }
155