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