futility: Use only vboot 2.0 APIs for keyblocks
[vboot.git] / host / lib / host_key2.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 keys.
6  */
7
8 /* TODO: change all 'return 0', 'return 1' into meaningful return codes */
9
10 #include <openssl/pem.h>
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15
16 #include "2sysincludes.h"
17 #include "2common.h"
18 #include "2rsa.h"
19 #include "2sha.h"
20 #include "cryptolib.h"
21 #include "host_common.h"
22 #include "host_key.h"
23 #include "host_key2.h"
24 #include "host_misc.h"
25 #include "vb2_common.h"
26 #include "vboot_common.h"
27
28 struct vb2_private_key *vb2_read_private_key(const char *filename)
29 {
30         uint8_t *buf = NULL;
31         uint32_t bufsize = 0;
32         if (VB2_SUCCESS != vb2_read_file(filename, &buf, &bufsize)) {
33                 VbExError("unable to read from file %s\n", filename);
34                 return NULL;
35         }
36
37         struct vb2_private_key *key =
38                 (struct vb2_private_key *)calloc(sizeof(*key), 1);
39         if (!key) {
40                 VbExError("Unable to allocate private key\n");
41                 free(buf);
42                 return NULL;
43         }
44
45         uint64_t alg = *(uint64_t *)buf;
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 =
51                 d2i_RSAPrivateKey(0, &start, bufsize - sizeof(alg));
52
53         if (!key->rsa_private_key) {
54                 VbExError("Unable to parse RSA private key\n");
55                 free(buf);
56                 free(key);
57                 return NULL;
58         }
59
60         free(buf);
61         return key;
62 }
63
64 struct vb2_private_key *vb2_read_private_key_pem(
65                 const char* filename,
66                 enum vb2_crypto_algorithm algorithm)
67 {
68         RSA *rsa_key;
69         FILE *f;
70
71         if (algorithm >= VB2_ALG_COUNT) {
72                 VB2_DEBUG("%s() called with invalid algorithm!\n",
73                           __FUNCTION__);
74                 return NULL;
75         }
76
77         /* Read private key */
78         f = fopen(filename, "r");
79         if (!f) {
80                 VB2_DEBUG("%s(): Couldn't open key file: %s\n",
81                           __FUNCTION__, filename);
82                 return NULL;
83         }
84         rsa_key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
85         fclose(f);
86         if (!rsa_key) {
87                 VB2_DEBUG("%s(): Couldn't read private key from file: %s\n",
88                          __FUNCTION__, filename);
89                 return NULL;
90         }
91
92         /* Store key and algorithm in our struct */
93         struct vb2_private_key *key =
94                 (struct vb2_private_key *)calloc(sizeof(*key), 1);
95         if (!key) {
96                 RSA_free(rsa_key);
97                 return NULL;
98         }
99         key->rsa_private_key = rsa_key;
100         key->hash_alg = vb2_crypto_to_hash(algorithm);
101         key->sig_alg = vb2_crypto_to_signature(algorithm);
102
103         /* Return the key */
104         return key;
105 }
106
107 void vb2_init_packed_key(struct vb2_packed_key *key, uint8_t *key_data,
108                          uint32_t key_size)
109 {
110         memset(key, 0, sizeof(*key));
111         key->key_offset = vb2_offset_of(key, key_data);
112         key->key_size = key_size;
113         key->algorithm = VB2_ALG_COUNT; /* Key not present yet */
114 }
115
116 int vb2_copy_packed_key(struct vb2_packed_key *dest,
117                         const struct vb2_packed_key *src)
118 {
119         if (dest->key_size < src->key_size)
120                 return VB2_ERROR_COPY_KEY_SIZE;
121
122         dest->key_size = src->key_size;
123         dest->algorithm = src->algorithm;
124         dest->key_version = src->key_version;
125         memcpy((uint8_t *)vb2_packed_key_data(dest),
126                vb2_packed_key_data(src), src->key_size);
127         return VB2_SUCCESS;
128 }
129
130 struct vb2_packed_key *vb2_read_packed_key(const char *filename)
131 {
132         struct vb2_packed_key *key;
133         uint32_t file_size;
134
135         if (VB2_SUCCESS !=
136             vb2_read_file(filename, (uint8_t **)&key, &file_size)) {
137                 return NULL;
138         }
139
140         if (packed_key_looks_ok(key, file_size))
141                 return key;
142
143         /* Error */
144         free(key);
145         return NULL;
146 }