xref: /aosp_15_r20/external/vboot_reference/host/lib/host_signature2.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
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