1 /* Copyright 2011 The ChromiumOS Authors
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 signature generation.
6 */
7
8 #include <openssl/rsa.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/types.h>
13 #include <sys/wait.h>
14 #include <unistd.h>
15
16 #include "2sysincludes.h"
17
18 #include "2common.h"
19 #include "2rsa.h"
20 #include "2sha.h"
21 #include "file_keys.h"
22 #include "host_common.h"
23 #include "host_key21.h"
24 #include "host_signature21.h"
25 #include "host_p11.h"
26
vb2_alloc_signature(uint32_t sig_size,uint32_t data_size)27 struct vb2_signature *vb2_alloc_signature(uint32_t sig_size,
28 uint32_t data_size)
29 {
30 struct vb2_signature *sig = (struct vb2_signature *)
31 calloc(sizeof(*sig) + sig_size, 1);
32 if (!sig)
33 return NULL;
34
35 sig->sig_offset = sizeof(*sig);
36 sig->sig_size = sig_size;
37 sig->data_size = data_size;
38
39 return sig;
40 }
41
vb2_init_signature(struct vb2_signature * sig,uint8_t * sig_data,uint32_t sig_size,uint32_t data_size)42 void vb2_init_signature(struct vb2_signature *sig, uint8_t *sig_data,
43 uint32_t sig_size, uint32_t data_size)
44 {
45 memset(sig, 0, sizeof(*sig));
46 sig->sig_offset = vb2_offset_of(sig, sig_data);
47 sig->sig_size = sig_size;
48 sig->data_size = data_size;
49 }
50
vb2_copy_signature(struct vb2_signature * dest,const struct vb2_signature * src)51 vb2_error_t vb2_copy_signature(struct vb2_signature *dest,
52 const struct vb2_signature *src)
53 {
54 if (dest->sig_size < src->sig_size)
55 return VB2_ERROR_SIG_SIZE;
56
57 dest->sig_size = src->sig_size;
58 dest->data_size = src->data_size;
59
60 memcpy(vb2_signature_data_mutable(dest),
61 vb2_signature_data(src),
62 src->sig_size);
63
64 return VB2_SUCCESS;
65 }
66
vb2_sha512_signature(const uint8_t * data,uint32_t size)67 struct vb2_signature *vb2_sha512_signature(const uint8_t *data, uint32_t size)
68 {
69 struct vb2_hash hash;
70 if (VB2_SUCCESS != vb2_hash_calculate(false, data, size,
71 VB2_HASH_SHA512, &hash))
72 return NULL;
73
74 struct vb2_signature *sig =
75 vb2_alloc_signature(sizeof(hash.sha512), size);
76 if (!sig)
77 return NULL;
78
79 memcpy(vb2_signature_data_mutable(sig), hash.sha512,
80 sizeof(hash.sha512));
81 return sig;
82 }
83
vb2_calculate_signature(const uint8_t * data,uint32_t size,const struct vb2_private_key * key)84 struct vb2_signature *vb2_calculate_signature(
85 const uint8_t *data, uint32_t size,
86 const struct vb2_private_key *key)
87 {
88 if (key->key_location == PRIVATE_KEY_P11) {
89 const uint32_t sig_size = vb2_rsa_sig_size(key->sig_alg);
90 struct vb2_signature *sig =
91 (struct vb2_signature *)vb2_alloc_signature(sig_size, size);
92 if (!sig)
93 return NULL;
94 if (pkcs11_sign(key->p11_key, key->hash_alg, data, size,
95 vb2_signature_data_mutable(sig), sig_size) != VB2_SUCCESS) {
96 fprintf(stderr, "%s: pkcs11_sign failed\n", __func__);
97 free(sig);
98 return NULL;
99 }
100 return sig;
101 }
102
103 struct vb2_hash hash;
104 uint32_t digest_size = vb2_digest_size(key->hash_alg);
105
106 uint32_t digest_info_size = 0;
107 const uint8_t *digest_info = NULL;
108 if (VB2_SUCCESS != vb2_digest_info(key->hash_alg,
109 &digest_info, &digest_info_size))
110 return NULL;
111
112 /* Calculate the digest */
113 if (VB2_SUCCESS != vb2_hash_calculate(false, data, size, key->hash_alg,
114 &hash))
115 return NULL;
116
117 /* Prepend the digest info to the digest */
118 int signature_digest_len = digest_size + digest_info_size;
119 uint8_t *signature_digest = malloc(signature_digest_len);
120 if (!signature_digest)
121 return NULL;
122
123 memcpy(signature_digest, digest_info, digest_info_size);
124 memcpy(signature_digest + digest_info_size, hash.raw, digest_size);
125
126 /* Allocate output signature */
127 struct vb2_signature *sig = (struct vb2_signature *)
128 vb2_alloc_signature(vb2_rsa_sig_size(key->sig_alg), size);
129 if (!sig) {
130 free(signature_digest);
131 return NULL;
132 }
133
134 /* Sign the signature_digest into our output buffer */
135 int rv = RSA_private_encrypt(signature_digest_len, /* Input length */
136 signature_digest, /* Input data */
137 vb2_signature_data_mutable(sig), /* Output sig */
138 key->rsa_private_key, /* Key to use */
139 RSA_PKCS1_PADDING); /* Padding */
140 free(signature_digest);
141
142 if (-1 == rv) {
143 fprintf(stderr, "%s: RSA_private_encrypt() failed\n", __func__);
144 free(sig);
145 return NULL;
146 }
147
148 /* Return the signature */
149 return sig;
150 }
151
152 struct vb2_signature *
vb2_create_signature_from_hash(const struct vb2_hash * hash)153 vb2_create_signature_from_hash(const struct vb2_hash *hash)
154 {
155 const uint32_t hsize = vb2_digest_size(hash->algo);
156
157 /* Unsupported algorithm */
158 if (!hsize)
159 return NULL;
160
161 const uint32_t full_hsize = offsetof(struct vb2_hash, raw) + hsize;
162
163 /* The body size is unknown, so set it to zero */
164 struct vb2_signature *sig =
165 (struct vb2_signature *)vb2_alloc_signature(full_hsize, 0);
166 if (!sig)
167 return NULL;
168
169 if (!memcpy(vb2_signature_data_mutable(sig), hash, full_hsize)) {
170 free(sig);
171 return NULL;
172 }
173
174 return sig;
175 }
176