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