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