bdb: Replace sha functions with vb2 library
[vboot.git] / firmware / bdb / host.c
1 /* Copyright 2015 The Chromium OS Authors. All rights reserved.
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 signing
6  */
7
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11
12 #include "2sha.h"
13 #include "bdb.h"
14 #include "host.h"
15
16 char *strzcpy(char *dest, const char *src, size_t size)
17 {
18         strncpy(dest, src, size);
19         dest[size - 1] = 0;
20         return dest;
21 }
22
23 uint8_t *read_file(const char *filename, uint32_t *size_ptr)
24 {
25         FILE *f;
26         uint8_t *buf;
27         long size;
28
29         *size_ptr = 0;
30
31         f = fopen(filename, "rb");
32         if (!f) {
33                 fprintf(stderr, "Unable to open file %s\n", filename);
34                 return NULL;
35         }
36
37         fseek(f, 0, SEEK_END);
38         size = ftell(f);
39         rewind(f);
40
41         if (size < 0 || size > UINT32_MAX) {
42                 fclose(f);
43                 return NULL;
44         }
45
46         buf = malloc(size);
47         if (!buf) {
48                 fclose(f);
49                 return NULL;
50         }
51
52         if (1 != fread(buf, size, 1, f)) {
53                 fprintf(stderr, "Unable to read file %s\n", filename);
54                 fclose(f);
55                 free(buf);
56                 return NULL;
57         }
58
59         fclose(f);
60
61         *size_ptr = size;
62         return buf;
63 }
64
65 int write_file(const char *filename, const void *buf, uint32_t size)
66 {
67         FILE *f = fopen(filename, "wb");
68
69         if (!f) {
70                 fprintf(stderr, "Unable to open file %s\n", filename);
71                 return 1;
72         }
73
74         if (1 != fwrite(buf, size, 1, f)) {
75                 fprintf(stderr, "Unable to write to file %s\n", filename);
76                 fclose(f);
77                 unlink(filename);  /* Delete any partial file */
78                 return 1;
79         }
80
81         fclose(f);
82         return 0;
83 }
84
85 struct rsa_st *read_pem(const char *filename)
86 {
87         struct rsa_st *pem;
88         FILE *f;
89
90         /* Read private key */
91         f = fopen(filename, "rb");
92         if (!f) {
93                 fprintf(stderr, "%s: unable to read key from %s\n",
94                         __func__, filename);
95                 return NULL;
96         }
97
98         pem = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
99         fclose(f);
100
101         return pem;
102 }
103
104 struct bdb_key *bdb_create_key(const char *filename,
105                                uint32_t key_version,
106                                const char *desc)
107 {
108         uint32_t sig_alg;
109         size_t key_size = sizeof(struct bdb_key);
110         struct bdb_key *k;
111         uint8_t *kdata;
112         uint32_t kdata_size = 0;
113
114         /*
115          * Read key data.  Somewhat lame assumption that we can determine the
116          * signature algorithm from the key size, but it's true right now.
117          */
118         kdata = read_file(filename, &kdata_size);
119         if (kdata_size == BDB_RSA4096_KEY_DATA_SIZE) {
120                 sig_alg = BDB_SIG_ALG_RSA4096;
121         } else if (kdata_size == BDB_RSA3072B_KEY_DATA_SIZE) {
122                 sig_alg = BDB_SIG_ALG_RSA3072B;
123         } else {
124                 fprintf(stderr, "%s: bad key size from %s\n",
125                         __func__, filename);
126                 return NULL;
127         }
128         key_size += kdata_size;
129
130         /* Allocate buffer */
131         k = (struct bdb_key *)calloc(key_size, 1);
132         if (!k) {
133                 free(kdata);
134                 return NULL;
135         }
136
137         k->struct_magic = BDB_KEY_MAGIC;
138         k->struct_major_version = BDB_KEY_VERSION_MAJOR;
139         k->struct_minor_version = BDB_KEY_VERSION_MINOR;
140         k->struct_size = key_size;
141         k->hash_alg = BDB_HASH_ALG_SHA256;
142         k->sig_alg = sig_alg;
143         k->key_version = key_version;
144
145         /* Copy description, if any */
146         if (desc)
147                 strzcpy(k->description, desc, sizeof(k->description));
148
149         /* Copy key data */
150         memcpy(k->key_data, kdata, kdata_size);
151         free(kdata);
152
153         return k;
154 }
155
156 struct bdb_sig *bdb_create_sig(const void *data,
157                                size_t size,
158                                struct rsa_st *key,
159                                uint32_t sig_alg,
160                                const char *desc)
161 {
162         static const uint8_t info[] = {
163                 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
164                 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
165                 0x00, 0x04, 0x20
166         };
167
168         size_t sig_size = sizeof(struct bdb_sig);
169         uint8_t digest[sizeof(info) + BDB_SHA256_DIGEST_SIZE];
170         struct bdb_sig *sig;
171
172         if (size >= UINT32_MAX)
173                 return NULL;
174
175         switch(sig_alg) {
176         case BDB_SIG_ALG_RSA4096:
177                 sig_size += BDB_RSA4096_SIG_SIZE;
178                 break;
179         case BDB_SIG_ALG_RSA3072B:
180                 sig_size += BDB_RSA3072B_SIG_SIZE;
181                 break;
182         default:
183                 fprintf(stderr, "%s: bad signature algorithm %d\n",
184                         __func__, sig_alg);
185                 return NULL;
186         }
187
188         /* Allocate buffer */
189         sig = (struct bdb_sig *)calloc(sig_size, 1);
190         if (!sig)
191                 return NULL;
192
193         sig->struct_magic = BDB_SIG_MAGIC;
194         sig->struct_major_version = BDB_SIG_VERSION_MAJOR;
195         sig->struct_minor_version = BDB_SIG_VERSION_MINOR;
196         sig->struct_size = sig_size;
197         sig->hash_alg = BDB_HASH_ALG_SHA256;
198         sig->sig_alg = sig_alg;
199         sig->signed_size = size;
200
201         /* Copy description, if any */
202         if (desc)
203                 strzcpy(sig->description, desc, sizeof(sig->description));
204
205         /* Calculate info-padded digest */
206         memcpy(digest, info, sizeof(info));
207         if (vb2_digest_buffer((uint8_t *)data, size,
208                               VB2_HASH_SHA256,
209                               digest + sizeof(info), BDB_SHA256_DIGEST_SIZE)) {
210                 free(sig);
211                 return NULL;
212         }
213
214         /* RSA-encrypt the signature */
215         if (RSA_private_encrypt(sizeof(digest),
216                                 digest,
217                                 sig->sig_data,
218                                 key,
219                                 RSA_PKCS1_PADDING) == -1) {
220                 free(sig);
221                 return NULL;
222         }
223         return sig;
224 }
225
226 struct bdb_header *bdb_create(struct bdb_create_params *p)
227 {
228         size_t bdb_size = 0;
229         size_t sig_size = sizeof(struct bdb_sig) + BDB_RSA4096_SIG_SIZE;
230         size_t hashes_size = sizeof(struct bdb_hash) * p->num_hashes;
231         uint8_t *buf, *bnext;
232         struct bdb_header *h;
233         struct bdb_sig *sig;
234         struct bdb_data *data;
235         const void *oem;
236
237         /* We can do some checks before we even allocate the buffer */
238
239         /* Make sure OEM sizes are aligned */
240         if ((p->oem_area_0_size & 3) || (p->oem_area_1_size & 3)) {
241                 fprintf(stderr, "%s: OEM areas not 32-bit aligned\n",
242                         __func__);
243                 return NULL;
244         }
245
246         /* Hash count must fit in uint8_t */
247         if (p->num_hashes > 255) {
248                 fprintf(stderr, "%s: too many hashes\n", __func__);
249                 return NULL;
250         }
251
252         /* Calculate BDB size */
253         bdb_size = sizeof(struct bdb_header);
254         bdb_size += p->bdbkey->struct_size;
255         bdb_size += p->oem_area_0_size;
256         bdb_size += p->subkey->struct_size;
257         bdb_size += sig_size;
258         bdb_size += sizeof(struct bdb_data);
259         bdb_size += p->oem_area_1_size;
260         bdb_size += sizeof(struct bdb_hash) * p->num_hashes;
261         bdb_size += sig_size;
262
263         /* Make sure it fits */
264         if (bdb_size > UINT32_MAX) {
265                 fprintf(stderr, "%s: BDB size > UINT32_MAX\n", __func__);
266                 return NULL;
267         }
268
269         /* Allocate a buffer */
270         bnext = buf = calloc(bdb_size, 1);
271         if (!buf) {
272                 fprintf(stderr, "%s: can't allocate buffer\n", __func__);
273                 return NULL;
274         }
275
276         /* Fill in the header */
277         h = (struct bdb_header *)bnext;
278         h->struct_magic = BDB_HEADER_MAGIC;
279         h->struct_major_version = BDB_HEADER_VERSION_MAJOR;
280         h->struct_minor_version = BDB_HEADER_VERSION_MINOR;
281         h->struct_size = sizeof(*h);
282         h->bdb_load_address = p->bdb_load_address;
283         h->bdb_size = bdb_size;
284         h->signed_size = p->oem_area_0_size + p->subkey->struct_size;
285         h->oem_area_0_size = p->oem_area_0_size;
286         bnext += h->struct_size;
287
288         /* Copy BDB key */
289         memcpy(bnext, p->bdbkey, p->bdbkey->struct_size);
290         bnext += p->bdbkey->struct_size;
291
292         /* Copy OEM area 0 */
293         oem = bnext;
294         if (p->oem_area_0_size) {
295                 memcpy(bnext, p->oem_area_0, p->oem_area_0_size);
296                 bnext += p->oem_area_0_size;
297         }
298
299         /* Copy subkey */
300         memcpy(bnext, p->subkey, p->subkey->struct_size);
301         bnext += p->subkey->struct_size;
302
303         /*
304          * Create header signature using private BDB key.
305          *
306          * TODO: create the header signature in a totally separate step.  That
307          * way, the private BDB key is not required each time a BDB is created.
308          */
309         sig = bdb_create_sig(oem, h->signed_size, p->private_bdbkey,
310                              p->bdbkey->sig_alg, p->header_sig_description);
311         memcpy(bnext, sig, sig->struct_size);
312         bnext += sig->struct_size;
313
314         /* Fill in the data */
315         data = (struct bdb_data *)bnext;
316         data->struct_magic = BDB_DATA_MAGIC;
317         data->struct_major_version = BDB_DATA_VERSION_MAJOR;
318         data->struct_minor_version = BDB_DATA_VERSION_MINOR;
319         data->struct_size = sizeof(struct bdb_data);
320         data->data_version = p->data_version;
321         data->oem_area_1_size = p->oem_area_1_size;
322         data->num_hashes = p->num_hashes;
323         data->hash_entry_size = sizeof(struct bdb_hash);
324         data->signed_size = data->struct_size + data->oem_area_1_size +
325                 hashes_size;
326         if (p->data_description) {
327                 strzcpy(data->description, p->data_description,
328                         sizeof(data->description));
329         }
330         bnext += data->struct_size;
331
332         /* Copy OEM area 1 */
333         oem = bnext;
334         if (p->oem_area_1_size) {
335                 memcpy(bnext, p->oem_area_1, p->oem_area_1_size);
336                 bnext += p->oem_area_1_size;
337         }
338
339         /* Copy hashes */
340         memcpy(bnext, p->hash, hashes_size);
341         bnext += hashes_size;
342
343         /* Create data signature using private subkey */
344         sig = bdb_create_sig(data, data->signed_size, p->private_subkey,
345                              p->subkey->sig_alg, p->data_sig_description);
346         memcpy(bnext, sig, sig->struct_size);
347
348         /* Return the BDB */
349         return h;
350 }