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