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 */
28static 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
79int 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
183int 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
199int 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
219int 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
243int 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