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