1 /* Copyright (c) 2014 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 signatures.
6 */
7
8 #include <openssl/rsa.h>
9
10 #include "2sysincludes.h"
11 #include "2common.h"
12 #include "2rsa.h"
13 #include "2sha.h"
14 #include "vb2_common.h"
15 #include "host_common.h"
16 #include "host_key2.h"
17 #include "host_signature2.h"
18 #include "host_misc.h"
19
20 /**
21 * Get the digest info for a hash algorithm
22 *
23 * @param hash_alg Hash algorithm
24 * @param buf_ptr On success, points to the digest info
25 * @param size_ptr On success, contains the info size in bytes
26 * @return VB2_SUCCESS, or non-zero error code on failure.
27 */
vb2_digest_info(enum vb2_hash_algorithm hash_alg,const uint8_t ** buf_ptr,uint32_t * size_ptr)28 static int vb2_digest_info(enum vb2_hash_algorithm hash_alg,
29 const uint8_t **buf_ptr,
30 uint32_t *size_ptr)
31 {
32 *buf_ptr = NULL;
33 *size_ptr = 0;
34
35 switch (hash_alg) {
36 #if VB2_SUPPORT_SHA1
37 case VB2_HASH_SHA1:
38 {
39 static const uint8_t info[] = {
40 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
41 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
42 };
43 *buf_ptr = info;
44 *size_ptr = sizeof(info);
45 return VB2_SUCCESS;
46 }
47 #endif
48 #if VB2_SUPPORT_SHA256
49 case VB2_HASH_SHA256:
50 {
51 static const uint8_t info[] = {
52 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
53 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
54 0x00, 0x04, 0x20
55 };
56 *buf_ptr = info;
57 *size_ptr = sizeof(info);
58 return VB2_SUCCESS;
59 }
60 #endif
61 #if VB2_SUPPORT_SHA512
62 case VB2_HASH_SHA512:
63 {
64 static const uint8_t info[] = {
65 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
66 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
67 0x00, 0x04, 0x40
68 };
69 *buf_ptr = info;
70 *size_ptr = sizeof(info);
71 return VB2_SUCCESS;
72 }
73 #endif
74 default:
75 return VB2_ERROR_DIGEST_INFO;
76 }
77 }
78
vb2_sign_data(struct vb2_signature ** sig_ptr,const uint8_t * data,uint32_t size,const struct vb2_private_key * key,const char * desc)79 int vb2_sign_data(struct vb2_signature **sig_ptr,
80 const uint8_t *data,
81 uint32_t size,
82 const struct vb2_private_key *key,
83 const char *desc)
84 {
85 struct vb2_signature s = {
86 .c.magic = VB2_MAGIC_SIGNATURE,
87 .c.struct_version_major = VB2_SIGNATURE_VERSION_MAJOR,
88 .c.struct_version_minor = VB2_SIGNATURE_VERSION_MINOR,
89 .c.fixed_size = sizeof(s),
90 .sig_alg = key->sig_alg,
91 .hash_alg = key->hash_alg,
92 .data_size = size,
93 .guid = key->guid,
94 };
95
96 struct vb2_digest_context dc;
97 uint32_t digest_size;
98 const uint8_t *info = NULL;
99 uint32_t info_size = 0;
100 uint32_t sig_digest_size;
101 uint8_t *sig_digest;
102 uint8_t *buf;
103
104 *sig_ptr = NULL;
105
106 /* Use key description if no description supplied */
107 if (!desc)
108 desc = key->desc;
109
110 s.c.desc_size = vb2_desc_size(desc);
111
112 s.sig_offset = s.c.fixed_size + s.c.desc_size;
113 s.sig_size = vb2_sig_size(key->sig_alg, key->hash_alg);
114 if (!s.sig_size)
115 return VB2_SIGN_DATA_SIG_SIZE;
116
117 s.c.total_size = s.sig_offset + s.sig_size;
118
119 /* Determine digest size and allocate buffer */
120 if (s.sig_alg != VB2_SIG_NONE) {
121 if (vb2_digest_info(s.hash_alg, &info, &info_size))
122 return VB2_SIGN_DATA_DIGEST_INFO;
123 }
124
125 digest_size = vb2_digest_size(key->hash_alg);
126 if (!digest_size)
127 return VB2_SIGN_DATA_DIGEST_SIZE;
128
129 sig_digest_size = info_size + digest_size;
130 sig_digest = malloc(sig_digest_size);
131 if (!sig_digest)
132 return VB2_SIGN_DATA_DIGEST_ALLOC;
133
134 /* Prepend digest info, if any */
135 if (info_size)
136 memcpy(sig_digest, info, info_size);
137
138 /* Calculate hash digest */
139 if (vb2_digest_init(&dc, s.hash_alg)) {
140 free(sig_digest);
141 return VB2_SIGN_DATA_DIGEST_INIT;
142 }
143
144 if (vb2_digest_extend(&dc, data, size)) {
145 free(sig_digest);
146 return VB2_SIGN_DATA_DIGEST_EXTEND;
147 }
148
149 if (vb2_digest_finalize(&dc, sig_digest + info_size, digest_size)) {
150 free(sig_digest);
151 return VB2_SIGN_DATA_DIGEST_FINALIZE;
152 }
153
154 /* Allocate signature buffer and copy header */
155 buf = calloc(1, s.c.total_size);
156 memcpy(buf, &s, sizeof(s));
157
158 /* strcpy() is ok because we allocated buffer based on desc length */
159 if (desc)
160 strcpy((char *)buf + s.c.fixed_size, desc);
161
162 if (s.sig_alg == VB2_SIG_NONE) {
163 /* Bare hash signature is just the digest */
164 memcpy(buf + s.sig_offset, sig_digest, sig_digest_size);
165 } else {
166 /* RSA-encrypt the signature */
167 if (RSA_private_encrypt(sig_digest_size,
168 sig_digest,
169 buf + s.sig_offset,
170 key->rsa_private_key,
171 RSA_PKCS1_PADDING) == -1) {
172 free(sig_digest);
173 free(buf);
174 return VB2_SIGN_DATA_RSA_ENCRYPT;
175 }
176 }
177
178 free(sig_digest);
179 *sig_ptr = (struct vb2_signature *)buf;
180 return VB2_SUCCESS;
181 }
182
vb2_sig_size_for_key(uint32_t * size_ptr,const struct vb2_private_key * key,const char * desc)183 int vb2_sig_size_for_key(uint32_t *size_ptr,
184 const struct vb2_private_key *key,
185 const char *desc)
186 {
187 uint32_t size = vb2_sig_size(key->sig_alg, key->hash_alg);
188
189 if (!size)
190 return VB2_ERROR_SIG_SIZE_FOR_KEY;
191
192 size += sizeof(struct vb2_signature);
193 size += vb2_desc_size(desc ? desc : key->desc);
194
195 *size_ptr = size;
196 return VB2_SUCCESS;
197 }
198
vb2_sig_size_for_keys(uint32_t * size_ptr,const struct vb2_private_key ** key_list,uint32_t key_count)199 int vb2_sig_size_for_keys(uint32_t *size_ptr,
200 const struct vb2_private_key **key_list,
201 uint32_t key_count)
202 {
203 uint32_t total = 0, size = 0;
204 int rv, i;
205
206 *size_ptr = 0;
207
208 for (i = 0; i < key_count; i++) {
209 rv = vb2_sig_size_for_key(&size, key_list[i], NULL);
210 if (rv)
211 return rv;
212 total += size;
213 }
214
215 *size_ptr = total;
216 return VB2_SUCCESS;
217 }
218
vb2_sign_object(uint8_t * buf,uint32_t sig_offset,const struct vb2_private_key * key,const char * desc)219 int vb2_sign_object(uint8_t *buf,
220 uint32_t sig_offset,
221 const struct vb2_private_key *key,
222 const char *desc)
223 {
224 struct vb2_struct_common *c = (struct vb2_struct_common *)buf;
225 struct vb2_signature *sig = NULL;
226 int rv;
227
228 rv = vb2_sign_data(&sig, buf, sig_offset, key, desc);
229 if (rv)
230 return rv;
231
232 if (sig_offset + sig->c.total_size > c->total_size) {
233 free(sig);
234 return VB2_SIGN_OBJECT_OVERFLOW;
235 }
236
237 memcpy(buf + sig_offset, sig, sig->c.total_size);
238 free(sig);
239
240 return VB2_SUCCESS;
241 }
242
vb2_sign_object_multiple(uint8_t * buf,uint32_t sig_offset,const struct vb2_private_key ** key_list,uint32_t key_count)243 int vb2_sign_object_multiple(uint8_t *buf,
244 uint32_t sig_offset,
245 const struct vb2_private_key **key_list,
246 uint32_t key_count)
247 {
248 struct vb2_struct_common *c = (struct vb2_struct_common *)buf;
249 uint32_t sig_next = sig_offset;
250 int rv, i;
251
252 for (i = 0; i < key_count; i++) {
253 struct vb2_signature *sig = NULL;
254
255 rv = vb2_sign_data(&sig, buf, sig_offset, key_list[i], NULL);
256 if (rv)
257 return rv;
258
259 if (sig_next + sig->c.total_size > c->total_size) {
260 free(sig);
261 return VB2_SIGN_OBJECT_OVERFLOW;
262 }
263
264 memcpy(buf + sig_next, sig, sig->c.total_size);
265 sig_next += sig->c.total_size;
266 free(sig);
267 }
268
269 return VB2_SUCCESS;
270 }
271