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