• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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