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 keys.
6 */
7
8 #include <openssl/pem.h>
9
10 #include <errno.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14
15 #include "2common.h"
16 #include "2rsa.h"
17 #include "2sha.h"
18 #include "2sysincludes.h"
19 #include "host_common.h"
20 #include "host_common21.h"
21 #include "host_key21.h"
22 #include "host_key.h"
23 #include "host_misc.h"
24 #include "host_p11.h"
25
vb2_get_crypto_algorithm(enum vb2_hash_algorithm hash_alg,enum vb2_signature_algorithm sig_alg)26 enum vb2_crypto_algorithm vb2_get_crypto_algorithm(
27 enum vb2_hash_algorithm hash_alg,
28 enum vb2_signature_algorithm sig_alg)
29 {
30 /* Make sure algorithms are in the range supported by crypto alg */
31 if (sig_alg < VB2_SIG_RSA1024 || sig_alg >= VB2_SIG_ALG_COUNT)
32 return VB2_ALG_COUNT;
33 if (hash_alg < VB2_HASH_SHA1 || hash_alg > VB2_HASH_SHA512)
34 return VB2_ALG_COUNT;
35
36 return (sig_alg - VB2_SIG_RSA1024)
37 * (VB2_HASH_SHA512 - VB2_HASH_SHA1 + 1)
38 + (hash_alg - VB2_HASH_SHA1);
39 };
40
vb2_read_local_private_key(uint8_t * buf,uint32_t bufsize,struct vb2_private_key * key)41 static vb2_error_t vb2_read_local_private_key(uint8_t *buf, uint32_t bufsize,
42 struct vb2_private_key *key)
43 {
44 uint64_t alg = *(uint64_t *)buf;
45 key->key_location = PRIVATE_KEY_LOCAL;
46 key->hash_alg = vb2_crypto_to_hash(alg);
47 key->sig_alg = vb2_crypto_to_signature(alg);
48 const unsigned char *start = buf + sizeof(alg);
49
50 key->rsa_private_key = d2i_RSAPrivateKey(0, &start, bufsize - sizeof(alg));
51
52 if (!key->rsa_private_key) {
53 VB2_DEBUG("Unable to parse RSA private key\n");
54 return VB2_ERROR_UNKNOWN;
55 }
56 return VB2_SUCCESS;
57 }
58
vb2_read_p11_private_key(const char * key_info,struct vb2_private_key * key)59 static vb2_error_t vb2_read_p11_private_key(const char *key_info, struct vb2_private_key *key)
60 {
61 /* The format of p11 key info: "remote:{lib_path}:{slot_id}:{key_label}" */
62 char *p11_lib = NULL, *p11_label = NULL;
63 int p11_slot_id;
64 vb2_error_t ret = VB2_ERROR_UNKNOWN;
65 if (sscanf(key_info, "remote:%m[^:]:%i:%m[^:]", &p11_lib, &p11_slot_id, &p11_label) !=
66 3) {
67 VB2_DEBUG("Failed to parse pkcs11 key info\n");
68 goto done;
69 }
70
71 if (pkcs11_init(p11_lib) != VB2_SUCCESS) {
72 VB2_DEBUG("Unable to initialize pkcs11 library\n");
73 goto done;
74 }
75
76 struct pkcs11_key *p11_key = pkcs11_get_key(p11_slot_id, p11_label);
77 if (!p11_key) {
78 VB2_DEBUG("Unable to get pkcs11 key\n");
79 goto done;
80 }
81
82 key->key_location = PRIVATE_KEY_P11;
83 key->p11_key = p11_key;
84 key->sig_alg = pkcs11_get_sig_alg(p11_key);
85 key->hash_alg = pkcs11_get_hash_alg(p11_key);
86 if (key->sig_alg == VB2_SIG_INVALID || key->hash_alg == VB2_HASH_INVALID) {
87 VB2_DEBUG("Unable to get signature or hash algorithm\n");
88 pkcs11_free_key(p11_key);
89 goto done;
90 }
91 ret = VB2_SUCCESS;
92 done:
93 free(p11_lib);
94 free(p11_label);
95 return ret;
96 }
97
is_vb21_private_key(const uint8_t * buf,uint32_t bufsize)98 static bool is_vb21_private_key(const uint8_t *buf, uint32_t bufsize)
99 {
100 const struct vb21_packed_private_key *pkey =
101 (const struct vb21_packed_private_key *)buf;
102 return bufsize >= sizeof(pkey->c.magic) &&
103 pkey->c.magic == VB21_MAGIC_PACKED_PRIVATE_KEY;
104 }
105
vb2_read_private_key(const char * key_info)106 struct vb2_private_key *vb2_read_private_key(const char *key_info)
107 {
108 struct vb2_private_key *key = (struct vb2_private_key *)calloc(sizeof(*key), 1);
109 if (!key) {
110 VB2_DEBUG("Unable to allocate private key\n");
111 return NULL;
112 }
113
114 static const char p11_prefix[] = "remote";
115 static const char local_prefix[] = "local";
116 char *colon = strchr(key_info, ':');
117 if (colon) {
118 int prefix_size = colon - key_info;
119 if (!strncmp(key_info, p11_prefix, prefix_size)) {
120 if (vb2_read_p11_private_key(key_info, key) != VB2_SUCCESS) {
121 VB2_DEBUG("Unable to read pkcs11 private key\n");
122 free(key);
123 return NULL;
124 }
125 return key;
126 }
127 if (!strncmp(key_info, local_prefix, prefix_size))
128 key_info = colon + 1;
129 }
130
131 // Read the private key from local file.
132 uint8_t *buf = NULL;
133 uint32_t bufsize = 0;
134 if (vb2_read_file(key_info, &buf, &bufsize) != VB2_SUCCESS) {
135 VB2_DEBUG("unable to read from file %s\n", key_info);
136 return NULL;
137 }
138
139 vb2_error_t rv;
140 bool is_vb21 = is_vb21_private_key(buf, bufsize);
141 if (is_vb21)
142 rv = vb21_private_key_unpack_raw(buf, bufsize, key);
143 else
144 rv = vb2_read_local_private_key(buf, bufsize, key);
145
146 free(buf);
147 if (rv != VB2_SUCCESS) {
148 VB2_DEBUG("Unable to read local %s private key\n", is_vb21 ? "vb21" : "vb2");
149 free(key);
150 return NULL;
151 }
152 return key;
153 }
154
vb2_read_private_key_pem(const char * filename,enum vb2_crypto_algorithm algorithm)155 struct vb2_private_key *vb2_read_private_key_pem(
156 const char* filename,
157 enum vb2_crypto_algorithm algorithm)
158 {
159 if (algorithm >= VB2_ALG_COUNT) {
160 VB2_DEBUG("%s() called with invalid algorithm!\n",
161 __FUNCTION__);
162 return NULL;
163 }
164
165 /* Read private key */
166 FILE *f = fopen(filename, "r");
167 if (!f) {
168 VB2_DEBUG("%s(): Couldn't open key file: %s\n",
169 __FUNCTION__, filename);
170 return NULL;
171 }
172 struct rsa_st *rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
173 fclose(f);
174 if (!rsa_key) {
175 VB2_DEBUG("%s(): Couldn't read private key from file: %s\n",
176 __FUNCTION__, filename);
177 return NULL;
178 }
179
180 /* Store key and algorithm in our struct */
181 struct vb2_private_key *key =
182 (struct vb2_private_key *)calloc(sizeof(*key), 1);
183 if (!key) {
184 RSA_free(rsa_key);
185 return NULL;
186 }
187 key->rsa_private_key = rsa_key;
188 key->hash_alg = vb2_crypto_to_hash(algorithm);
189 key->sig_alg = vb2_crypto_to_signature(algorithm);
190
191 /* Return the key */
192 return key;
193 }
194
vb2_free_private_key(struct vb2_private_key * key)195 void vb2_free_private_key(struct vb2_private_key *key)
196 {
197 if (!key)
198 return;
199
200 if (key->key_location == PRIVATE_KEY_LOCAL && key->rsa_private_key)
201 RSA_free(key->rsa_private_key);
202 else if (key->key_location == PRIVATE_KEY_P11 && key->p11_key)
203 pkcs11_free_key(key->p11_key);
204
205 if (key->desc)
206 free(key->desc);
207
208 free(key);
209 }
210
vb2_write_private_key(const char * filename,const struct vb2_private_key * key)211 vb2_error_t vb2_write_private_key(const char *filename,
212 const struct vb2_private_key *key)
213 {
214 /* Convert back to legacy vb1 algorithm enum */
215 uint64_t alg = vb2_get_crypto_algorithm(key->hash_alg, key->sig_alg);
216 if (alg == VB2_ALG_COUNT) {
217 fprintf(stderr, "Can't find crypto algorithm\n");
218 return VB2_ERROR_VB1_CRYPTO_ALGORITHM;
219 }
220
221 uint8_t *outbuf = NULL;
222 int buflen = i2d_RSAPrivateKey(key->rsa_private_key, &outbuf);
223 if (buflen <= 0) {
224 fprintf(stderr, "Unable to write private key buffer\n");
225 return VB2_ERROR_PRIVATE_KEY_WRITE_RSA;
226 }
227
228 FILE *f = fopen(filename, "wb");
229 if (!f) {
230 fprintf(stderr, "Unable to open file %s\n", filename);
231 free(outbuf);
232 return VB2_ERROR_PRIVATE_KEY_WRITE_FILE;
233 }
234
235 if (1 != fwrite(&alg, sizeof(alg), 1, f) ||
236 1 != fwrite(outbuf, buflen, 1, f)) {
237 fprintf(stderr, "Unable to write to file %s\n", filename);
238 fclose(f);
239 unlink(filename); /* Delete any partial file */
240 free(outbuf);
241 return VB2_ERROR_PRIVATE_KEY_WRITE_FILE;
242 }
243
244 fclose(f);
245 free(outbuf);
246 return VB2_SUCCESS;
247 }
248
vb2_init_packed_key(struct vb2_packed_key * key,uint8_t * key_data,uint32_t key_size)249 void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data,
250 uint32_t key_size)
251 {
252 memset(key, 0, sizeof(*key));
253 key->key_offset = vb2_offset_of(key, key_data);
254 key->key_size = key_size;
255 key->algorithm = VB2_ALG_COUNT; /* Key not present yet */
256 }
257
vb2_alloc_packed_key(uint32_t key_size,uint32_t algorithm,uint32_t version)258 struct vb2_packed_key *vb2_alloc_packed_key(uint32_t key_size,
259 uint32_t algorithm,
260 uint32_t version)
261 {
262 struct vb2_packed_key *key =
263 (struct vb2_packed_key *)calloc(sizeof(*key) + key_size, 1);
264 if (!key)
265 return NULL;
266
267 key->algorithm = algorithm;
268 key->key_version = version;
269 key->key_size = key_size;
270 key->key_offset = sizeof(*key);
271 return key;
272 }
273
vb2_copy_packed_key(struct vb2_packed_key * dest,const struct vb2_packed_key * src)274 vb2_error_t vb2_copy_packed_key(struct vb2_packed_key *dest,
275 const struct vb2_packed_key *src)
276 {
277 if (dest->key_size < src->key_size)
278 return VB2_ERROR_COPY_KEY_SIZE;
279
280 dest->key_size = src->key_size;
281 dest->algorithm = src->algorithm;
282 dest->key_version = src->key_version;
283 memcpy(vb2_packed_key_data_mutable(dest),
284 vb2_packed_key_data(src),
285 src->key_size);
286 return VB2_SUCCESS;
287 }
288
vb2_read_packed_key(const char * filename)289 struct vb2_packed_key *vb2_read_packed_key(const char *filename)
290 {
291 struct vb2_packed_key *key = NULL;
292 uint32_t file_size = 0;
293
294 if (VB2_SUCCESS !=
295 vb2_read_file(filename, (uint8_t **)&key, &file_size)) {
296 return NULL;
297 }
298
299 if (vb2_packed_key_looks_ok(key, file_size) == VB2_SUCCESS)
300 return key;
301
302 /* Error */
303 free(key);
304 return NULL;
305 }
306
vb2_read_packed_keyb(const char * filename,uint32_t algorithm,uint32_t version)307 struct vb2_packed_key *vb2_read_packed_keyb(const char *filename,
308 uint32_t algorithm,
309 uint32_t version)
310 {
311 if (algorithm >= VB2_ALG_COUNT) {
312 fprintf(stderr, "%s() - invalid algorithm\n", __func__);
313 return NULL;
314 }
315 if (version > VB2_MAX_KEY_VERSION) {
316 /* Currently, TPM only supports 16-bit version */
317 fprintf(stderr, "%s() - invalid version %#x\n", __func__,
318 version);
319 return NULL;
320 }
321
322 uint8_t *key_data = NULL;
323 uint32_t key_size = 0;
324 if (VB2_SUCCESS != vb2_read_file(filename, &key_data, &key_size))
325 return NULL;
326
327 uint32_t expected_key_size =
328 vb2_packed_key_size(vb2_crypto_to_signature(algorithm));
329 if (!expected_key_size || expected_key_size != key_size) {
330 fprintf(stderr, "%s() - wrong key size %u for algorithm %u\n",
331 __func__, key_size, algorithm);
332 free(key_data);
333 return NULL;
334 }
335
336 struct vb2_packed_key *key =
337 vb2_alloc_packed_key(key_size, algorithm, version);
338 if (!key) {
339 free(key_data);
340 return NULL;
341 }
342 memcpy(vb2_packed_key_data_mutable(key), key_data, key_size);
343
344 free(key_data);
345 return key;
346 }
347
vb2_write_packed_key(const char * filename,const struct vb2_packed_key * key)348 vb2_error_t vb2_write_packed_key(const char *filename,
349 const struct vb2_packed_key *key)
350 {
351 /* Copy the key, so its data is contiguous with the header */
352 struct vb2_packed_key *kcopy =
353 vb2_alloc_packed_key(key->key_size, 0, 0);
354 if (!kcopy)
355 return VB2_ERROR_PACKED_KEY_ALLOC;
356 if (VB2_SUCCESS != vb2_copy_packed_key(kcopy, key)) {
357 free(kcopy);
358 return VB2_ERROR_PACKED_KEY_COPY;
359 }
360
361 /* Write the copy, then free it */
362 vb2_error_t rv = vb2_write_file(filename, kcopy,
363 kcopy->key_offset + kcopy->key_size);
364 free(kcopy);
365 return rv;
366 }
367
vb2_packed_key_looks_ok(const struct vb2_packed_key * key,uint32_t size)368 vb2_error_t vb2_packed_key_looks_ok(const struct vb2_packed_key *key,
369 uint32_t size)
370 {
371 struct vb2_public_key pubkey;
372 vb2_error_t rv;
373
374 rv = vb2_unpack_key_buffer(&pubkey, (const uint8_t *)key, size);
375 if (rv)
376 return rv;
377
378 if (key->key_version > VB2_MAX_KEY_VERSION) {
379 /* Currently, TPM only supports 16-bit version */
380 VB2_DEBUG("packed key invalid version\n");
381 return VB2_ERROR_PACKED_KEY_VERSION;
382 }
383
384 return VB2_SUCCESS;
385 }
386
vb2_unpack_key_data(struct vb2_public_key * key,const uint8_t * key_data,uint32_t key_size)387 vb2_error_t vb2_unpack_key_data(struct vb2_public_key *key,
388 const uint8_t *key_data, uint32_t key_size)
389 {
390 const uint32_t *buf32 = (const uint32_t *)key_data;
391 uint32_t expected_key_size = vb2_packed_key_size(key->sig_alg);
392
393 /* Make sure buffer is the correct length */
394 if (!expected_key_size || expected_key_size != key_size) {
395 VB2_DEBUG("Wrong key size for algorithm\n");
396 return VB2_ERROR_UNPACK_KEY_SIZE;
397 }
398
399 /* Check for alignment */
400 if (!vb2_aligned(buf32, sizeof(uint32_t)))
401 return VB2_ERROR_UNPACK_KEY_ALIGN;
402
403 key->arrsize = buf32[0];
404
405 /* Validity check key array size */
406 if (key->arrsize * sizeof(uint32_t) != vb2_rsa_sig_size(key->sig_alg))
407 return VB2_ERROR_UNPACK_KEY_ARRAY_SIZE;
408
409 key->n0inv = buf32[1];
410
411 /* Arrays point inside the key data */
412 key->n = buf32 + 2;
413 key->rr = buf32 + 2 + key->arrsize;
414
415 return VB2_SUCCESS;
416 }
417