1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2011 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 <stdio.h>
9*8617a60dSAndroid Build Coastguard Worker
10*8617a60dSAndroid Build Coastguard Worker #include "2sysincludes.h"
11*8617a60dSAndroid Build Coastguard Worker
12*8617a60dSAndroid Build Coastguard Worker #include "2api.h"
13*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
14*8617a60dSAndroid Build Coastguard Worker #include "2rsa.h"
15*8617a60dSAndroid Build Coastguard Worker #include "2sha.h"
16*8617a60dSAndroid Build Coastguard Worker #include "host_common.h"
17*8617a60dSAndroid Build Coastguard Worker #include "host_key21.h"
18*8617a60dSAndroid Build Coastguard Worker #include "host_keyblock.h"
19*8617a60dSAndroid Build Coastguard Worker #include "host_key.h"
20*8617a60dSAndroid Build Coastguard Worker
vb2_create_keyblock(const struct vb2_packed_key * data_key,const struct vb2_private_key * signing_key,uint32_t flags)21*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *vb2_create_keyblock(
22*8617a60dSAndroid Build Coastguard Worker const struct vb2_packed_key *data_key,
23*8617a60dSAndroid Build Coastguard Worker const struct vb2_private_key *signing_key,
24*8617a60dSAndroid Build Coastguard Worker uint32_t flags)
25*8617a60dSAndroid Build Coastguard Worker {
26*8617a60dSAndroid Build Coastguard Worker /* Allocate keyblock */
27*8617a60dSAndroid Build Coastguard Worker uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
28*8617a60dSAndroid Build Coastguard Worker uint32_t sig_data_size =
29*8617a60dSAndroid Build Coastguard Worker (signing_key ? vb2_rsa_sig_size(signing_key->sig_alg) : 0);
30*8617a60dSAndroid Build Coastguard Worker uint32_t block_size =
31*8617a60dSAndroid Build Coastguard Worker signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
32*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *h = (struct vb2_keyblock *)calloc(block_size, 1);
33*8617a60dSAndroid Build Coastguard Worker if (!h)
34*8617a60dSAndroid Build Coastguard Worker return NULL;
35*8617a60dSAndroid Build Coastguard Worker
36*8617a60dSAndroid Build Coastguard Worker uint8_t *data_key_dest = (uint8_t *)(h + 1);
37*8617a60dSAndroid Build Coastguard Worker uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
38*8617a60dSAndroid Build Coastguard Worker uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
39*8617a60dSAndroid Build Coastguard Worker
40*8617a60dSAndroid Build Coastguard Worker memcpy(h->magic, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE);
41*8617a60dSAndroid Build Coastguard Worker h->header_version_major = VB2_KEYBLOCK_VERSION_MAJOR;
42*8617a60dSAndroid Build Coastguard Worker h->header_version_minor = VB2_KEYBLOCK_VERSION_MINOR;
43*8617a60dSAndroid Build Coastguard Worker h->keyblock_size = block_size;
44*8617a60dSAndroid Build Coastguard Worker h->keyblock_flags = flags;
45*8617a60dSAndroid Build Coastguard Worker
46*8617a60dSAndroid Build Coastguard Worker /* Copy data key */
47*8617a60dSAndroid Build Coastguard Worker vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
48*8617a60dSAndroid Build Coastguard Worker vb2_copy_packed_key(&h->data_key, data_key);
49*8617a60dSAndroid Build Coastguard Worker
50*8617a60dSAndroid Build Coastguard Worker /* Set up signature structs so we can calculate the signatures */
51*8617a60dSAndroid Build Coastguard Worker vb2_init_signature(&h->keyblock_hash, block_chk_dest,
52*8617a60dSAndroid Build Coastguard Worker VB2_SHA512_DIGEST_SIZE, signed_size);
53*8617a60dSAndroid Build Coastguard Worker if (signing_key) {
54*8617a60dSAndroid Build Coastguard Worker vb2_init_signature(&h->keyblock_signature, block_sig_dest,
55*8617a60dSAndroid Build Coastguard Worker sig_data_size, signed_size);
56*8617a60dSAndroid Build Coastguard Worker } else {
57*8617a60dSAndroid Build Coastguard Worker memset(&h->keyblock_signature, 0,
58*8617a60dSAndroid Build Coastguard Worker sizeof(h->keyblock_signature));
59*8617a60dSAndroid Build Coastguard Worker }
60*8617a60dSAndroid Build Coastguard Worker
61*8617a60dSAndroid Build Coastguard Worker /* Calculate hash */
62*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *chk =
63*8617a60dSAndroid Build Coastguard Worker vb2_sha512_signature((uint8_t*)h, signed_size);
64*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->keyblock_hash, chk);
65*8617a60dSAndroid Build Coastguard Worker free(chk);
66*8617a60dSAndroid Build Coastguard Worker
67*8617a60dSAndroid Build Coastguard Worker /* Calculate signature */
68*8617a60dSAndroid Build Coastguard Worker if (signing_key) {
69*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sigtmp =
70*8617a60dSAndroid Build Coastguard Worker vb2_calculate_signature((uint8_t*)h,
71*8617a60dSAndroid Build Coastguard Worker signed_size,
72*8617a60dSAndroid Build Coastguard Worker signing_key);
73*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->keyblock_signature, sigtmp);
74*8617a60dSAndroid Build Coastguard Worker free(sigtmp);
75*8617a60dSAndroid Build Coastguard Worker }
76*8617a60dSAndroid Build Coastguard Worker
77*8617a60dSAndroid Build Coastguard Worker /* Return the header */
78*8617a60dSAndroid Build Coastguard Worker return h;
79*8617a60dSAndroid Build Coastguard Worker }
80*8617a60dSAndroid Build Coastguard Worker
81*8617a60dSAndroid Build Coastguard Worker /* TODO(gauravsh): This could easily be integrated into the function above
82*8617a60dSAndroid Build Coastguard Worker * since the code is almost a mirror - I have kept it as such to avoid changing
83*8617a60dSAndroid Build Coastguard Worker * the existing interface. */
vb2_create_keyblock_external(const struct vb2_packed_key * data_key,const char * signing_key_pem_file,uint32_t algorithm,uint32_t flags,const char * external_signer)84*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *vb2_create_keyblock_external(
85*8617a60dSAndroid Build Coastguard Worker const struct vb2_packed_key *data_key,
86*8617a60dSAndroid Build Coastguard Worker const char *signing_key_pem_file,
87*8617a60dSAndroid Build Coastguard Worker uint32_t algorithm,
88*8617a60dSAndroid Build Coastguard Worker uint32_t flags,
89*8617a60dSAndroid Build Coastguard Worker const char *external_signer)
90*8617a60dSAndroid Build Coastguard Worker {
91*8617a60dSAndroid Build Coastguard Worker if (!signing_key_pem_file || !data_key || !external_signer)
92*8617a60dSAndroid Build Coastguard Worker return NULL;
93*8617a60dSAndroid Build Coastguard Worker
94*8617a60dSAndroid Build Coastguard Worker uint32_t signed_size = sizeof(struct vb2_keyblock) + data_key->key_size;
95*8617a60dSAndroid Build Coastguard Worker uint32_t sig_data_size = vb2_rsa_sig_size(vb2_crypto_to_signature(algorithm));
96*8617a60dSAndroid Build Coastguard Worker uint32_t block_size =
97*8617a60dSAndroid Build Coastguard Worker signed_size + VB2_SHA512_DIGEST_SIZE + sig_data_size;
98*8617a60dSAndroid Build Coastguard Worker
99*8617a60dSAndroid Build Coastguard Worker /* Allocate keyblock */
100*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *h = (struct vb2_keyblock *)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 *data_key_dest = (uint8_t *)(h + 1);
105*8617a60dSAndroid Build Coastguard Worker uint8_t *block_chk_dest = data_key_dest + data_key->key_size;
106*8617a60dSAndroid Build Coastguard Worker uint8_t *block_sig_dest = block_chk_dest + VB2_SHA512_DIGEST_SIZE;
107*8617a60dSAndroid Build Coastguard Worker
108*8617a60dSAndroid Build Coastguard Worker memcpy(h->magic, VB2_KEYBLOCK_MAGIC, VB2_KEYBLOCK_MAGIC_SIZE);
109*8617a60dSAndroid Build Coastguard Worker h->header_version_major = VB2_KEYBLOCK_VERSION_MAJOR;
110*8617a60dSAndroid Build Coastguard Worker h->header_version_minor = VB2_KEYBLOCK_VERSION_MINOR;
111*8617a60dSAndroid Build Coastguard Worker h->keyblock_size = block_size;
112*8617a60dSAndroid Build Coastguard Worker h->keyblock_flags = flags;
113*8617a60dSAndroid Build Coastguard Worker
114*8617a60dSAndroid Build Coastguard Worker /* Copy data key */
115*8617a60dSAndroid Build Coastguard Worker vb2_init_packed_key(&h->data_key, data_key_dest, data_key->key_size);
116*8617a60dSAndroid Build Coastguard Worker vb2_copy_packed_key(&h->data_key, data_key);
117*8617a60dSAndroid Build Coastguard Worker
118*8617a60dSAndroid Build Coastguard Worker /* Set up signature structs so we can calculate the signatures */
119*8617a60dSAndroid Build Coastguard Worker vb2_init_signature(&h->keyblock_hash, block_chk_dest,
120*8617a60dSAndroid Build Coastguard Worker VB2_SHA512_DIGEST_SIZE, signed_size);
121*8617a60dSAndroid Build Coastguard Worker vb2_init_signature(&h->keyblock_signature, block_sig_dest,
122*8617a60dSAndroid Build Coastguard Worker sig_data_size, signed_size);
123*8617a60dSAndroid Build Coastguard Worker
124*8617a60dSAndroid Build Coastguard Worker /* Calculate checksum */
125*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *chk =
126*8617a60dSAndroid Build Coastguard Worker vb2_sha512_signature((uint8_t*)h, signed_size);
127*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->keyblock_hash, chk);
128*8617a60dSAndroid Build Coastguard Worker free(chk);
129*8617a60dSAndroid Build Coastguard Worker
130*8617a60dSAndroid Build Coastguard Worker /* Calculate signature */
131*8617a60dSAndroid Build Coastguard Worker struct vb2_signature *sigtmp =
132*8617a60dSAndroid Build Coastguard Worker vb2_external_signature((uint8_t*)h, signed_size,
133*8617a60dSAndroid Build Coastguard Worker signing_key_pem_file, algorithm,
134*8617a60dSAndroid Build Coastguard Worker external_signer);
135*8617a60dSAndroid Build Coastguard Worker vb2_copy_signature(&h->keyblock_signature, sigtmp);
136*8617a60dSAndroid Build Coastguard Worker free(sigtmp);
137*8617a60dSAndroid Build Coastguard Worker
138*8617a60dSAndroid Build Coastguard Worker /* Return the header */
139*8617a60dSAndroid Build Coastguard Worker return h;
140*8617a60dSAndroid Build Coastguard Worker }
141*8617a60dSAndroid Build Coastguard Worker
vb2_read_keyblock(const char * filename)142*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *vb2_read_keyblock(const char *filename)
143*8617a60dSAndroid Build Coastguard Worker {
144*8617a60dSAndroid Build Coastguard Worker uint8_t workbuf[VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE]
145*8617a60dSAndroid Build Coastguard Worker __attribute__((aligned(VB2_WORKBUF_ALIGN)));
146*8617a60dSAndroid Build Coastguard Worker struct vb2_workbuf wb;
147*8617a60dSAndroid Build Coastguard Worker vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
148*8617a60dSAndroid Build Coastguard Worker
149*8617a60dSAndroid Build Coastguard Worker struct vb2_keyblock *block;
150*8617a60dSAndroid Build Coastguard Worker uint32_t file_size;
151*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS !=
152*8617a60dSAndroid Build Coastguard Worker vb2_read_file(filename, (uint8_t **)&block, &file_size)) {
153*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Error reading keyblock file: %s\n", filename);
154*8617a60dSAndroid Build Coastguard Worker return NULL;
155*8617a60dSAndroid Build Coastguard Worker }
156*8617a60dSAndroid Build Coastguard Worker
157*8617a60dSAndroid Build Coastguard Worker /* Verify the hash of the keyblock, since we can do that without
158*8617a60dSAndroid Build Coastguard Worker * the public signing key. */
159*8617a60dSAndroid Build Coastguard Worker if (VB2_SUCCESS != vb2_verify_keyblock_hash(block, file_size, &wb)) {
160*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Invalid keyblock file: %s\n", filename);
161*8617a60dSAndroid Build Coastguard Worker free(block);
162*8617a60dSAndroid Build Coastguard Worker return NULL;
163*8617a60dSAndroid Build Coastguard Worker }
164*8617a60dSAndroid Build Coastguard Worker
165*8617a60dSAndroid Build Coastguard Worker return block;
166*8617a60dSAndroid Build Coastguard Worker }
167*8617a60dSAndroid Build Coastguard Worker
168*8617a60dSAndroid Build Coastguard Worker
vb2_write_keyblock(const char * filename,const struct vb2_keyblock * keyblock)169*8617a60dSAndroid Build Coastguard Worker int vb2_write_keyblock(const char *filename,
170*8617a60dSAndroid Build Coastguard Worker const struct vb2_keyblock *keyblock)
171*8617a60dSAndroid Build Coastguard Worker {
172*8617a60dSAndroid Build Coastguard Worker return vb2_write_file(filename, keyblock, keyblock->keyblock_size);
173*8617a60dSAndroid Build Coastguard Worker }
174