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