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