xref: /aosp_15_r20/external/vboot_reference/host/lib/util_misc.c (revision 8617a60d3594060b7ecbd21bc622a7c14f3cf2bc)
1 /* Copyright 2014 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  * Miscellaneous functions for userspace vboot utilities.
6  */
7 
8 #include <openssl/bn.h>
9 #include <openssl/rsa.h>
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <unistd.h>
15 
16 #include "2common.h"
17 #include "2sha.h"
18 #include "2sysincludes.h"
19 #include "host_common.h"
20 #include "host_key21.h"
21 #include "host_p11.h"
22 #include "openssl_compat.h"
23 #include "util_misc.h"
24 
packed_key_sha1_string(const struct vb2_packed_key * key)25 const char *packed_key_sha1_string(const struct vb2_packed_key *key)
26 {
27 	uint8_t *buf = ((uint8_t *)key) + key->key_offset;
28 	uint32_t buflen = key->key_size;
29 	struct vb2_hash hash;
30 	static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
31 
32 	vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash);
33 
34 	char *dnext = dest;
35 	int i;
36 	for (i = 0; i < sizeof(hash.sha1); i++)
37 		dnext += sprintf(dnext, "%02x", hash.sha1[i]);
38 
39 	return dest;
40 }
41 
private_key_sha1_string(const struct vb2_private_key * key)42 const char *private_key_sha1_string(const struct vb2_private_key *key)
43 {
44 	uint8_t *buf;
45 	uint32_t buflen;
46 	struct vb2_hash hash;
47 	static char dest[VB2_SHA1_DIGEST_SIZE * 2 + 1];
48 
49 	if (!key->rsa_private_key ||
50 	    vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen)) {
51 		return "<error>";
52 	}
53 
54 	vb2_hash_calculate(false, buf, buflen, VB2_HASH_SHA1, &hash);
55 
56 	char *dnext = dest;
57 	int i;
58 	for (i = 0; i < sizeof(hash.sha1); i++)
59 		dnext += sprintf(dnext, "%02x", hash.sha1[i]);
60 
61 	free(buf);
62 	return dest;
63 }
64 
vb_keyb_from_modulus(const BIGNUM * rsa_private_key_n,uint32_t modulus_size,uint8_t ** keyb_data,uint32_t * keyb_size)65 static int vb_keyb_from_modulus(const BIGNUM *rsa_private_key_n, uint32_t modulus_size,
66 				uint8_t **keyb_data, uint32_t *keyb_size)
67 {
68 	uint32_t i;
69 	uint32_t nwords = modulus_size / 4;
70 	BIGNUM *N = NULL;
71 	BIGNUM *Big1 = NULL, *Big2 = NULL, *Big32 = NULL, *BigMinus1 = NULL;
72 	BIGNUM *B = NULL;
73 	BIGNUM *N0inv = NULL, *R = NULL, *RR = NULL;
74 	BIGNUM *RRTemp = NULL, *NnumBits = NULL;
75 	BIGNUM *n = NULL, *rr = NULL;
76 	BN_CTX *bn_ctx = BN_CTX_new();
77 	uint32_t n0invout;
78 	uint32_t bufsize;
79 	uint32_t *outbuf;
80 	int retval = 1;
81 
82 	bufsize = (2 + nwords + nwords) * sizeof(uint32_t);
83 	outbuf = malloc(bufsize);
84 	if (!outbuf)
85 		goto done;
86 
87 	*keyb_data = (uint8_t *)outbuf;
88 	*keyb_size = bufsize;
89 
90 	*outbuf++ = nwords;
91 
92 	/* Initialize BIGNUMs */
93 #define NEW_BIGNUM(x) do { x = BN_new(); if (!x) goto done; } while (0)
94 	NEW_BIGNUM(N);
95 	NEW_BIGNUM(Big1);
96 	NEW_BIGNUM(Big2);
97 	NEW_BIGNUM(Big32);
98 	NEW_BIGNUM(BigMinus1);
99 	NEW_BIGNUM(N0inv);
100 	NEW_BIGNUM(R);
101 	NEW_BIGNUM(RR);
102 	NEW_BIGNUM(RRTemp);
103 	NEW_BIGNUM(NnumBits);
104 	NEW_BIGNUM(n);
105 	NEW_BIGNUM(rr);
106 	NEW_BIGNUM(B);
107 #undef NEW_BIGNUM
108 
109 	BN_copy(N, rsa_private_key_n);
110 	BN_set_word(Big1, 1L);
111 	BN_set_word(Big2, 2L);
112 	BN_set_word(Big32, 32L);
113 	BN_sub(BigMinus1, Big1, Big2);
114 
115 	BN_exp(B, Big2, Big32, bn_ctx); /* B = 2^32 */
116 
117 	/* Calculate and output N0inv = -1 / N[0] mod 2^32 */
118 	BN_mod_inverse(N0inv, N, B, bn_ctx);
119 	BN_sub(N0inv, B, N0inv);
120 	n0invout = BN_get_word(N0inv);
121 
122 	*outbuf++ = n0invout;
123 
124 	/* Calculate R = 2^(# of key bits) */
125 	BN_set_word(NnumBits, BN_num_bits(N));
126 	BN_exp(R, Big2, NnumBits, bn_ctx);
127 
128 	/* Calculate RR = R^2 mod N */
129 	BN_copy(RR, R);
130 	BN_mul(RRTemp, RR, R, bn_ctx);
131 	BN_mod(RR, RRTemp, N, bn_ctx);
132 
133 
134 	/* Write out modulus as little endian array of integers. */
135 	for (i = 0; i < nwords; ++i) {
136 		uint32_t nout;
137 
138 		BN_mod(n, N, B, bn_ctx); /* n = N mod B */
139 		nout = BN_get_word(n);
140 		*outbuf++ = nout;
141 
142 		BN_rshift(N, N, 32); /*  N = N/B */
143 	}
144 
145 	/* Write R^2 as little endian array of integers. */
146 	for (i = 0; i < nwords; ++i) {
147 		uint32_t rrout;
148 
149 		BN_mod(rr, RR, B, bn_ctx); /* rr = RR mod B */
150 		rrout = BN_get_word(rr);
151 		*outbuf++ = rrout;
152 
153 		BN_rshift(RR, RR, 32); /* RR = RR/B */
154 	}
155 
156 	outbuf = NULL;
157 	retval = 0;
158 
159 done:
160 	free(outbuf);
161 	/* Free BIGNUMs. */
162 	BN_free(Big1);
163 	BN_free(Big2);
164 	BN_free(Big32);
165 	BN_free(BigMinus1);
166 	BN_free(N0inv);
167 	BN_free(R);
168 	BN_free(RRTemp);
169 	BN_free(NnumBits);
170 	BN_free(n);
171 	BN_free(rr);
172 
173 	return retval;
174 }
175 
vb_keyb_from_p11_key(struct pkcs11_key * p11_key,uint8_t ** keyb_data,uint32_t * keyb_size)176 static int vb_keyb_from_p11_key(struct pkcs11_key *p11_key, uint8_t **keyb_data,
177 				uint32_t *keyb_size)
178 {
179 	int ret = 1;
180 	uint32_t modulus_size = 0;
181 	BIGNUM *N = NULL;
182 	uint8_t *modulus = pkcs11_get_modulus(p11_key, &modulus_size);
183 	if (!modulus) {
184 		fprintf(stderr, "Failed to get modulus from PKCS#11 key\n");
185 		goto done;
186 	}
187 
188 	N = BN_bin2bn(modulus, modulus_size, NULL);
189 	if (!N) {
190 		fprintf(stderr, "Failed to call BN_bin2bn()\n");
191 		goto done;
192 	}
193 	ret = vb_keyb_from_modulus(N, modulus_size, keyb_data, keyb_size);
194 done:
195 	BN_free(N);
196 	free(modulus);
197 	return ret;
198 }
199 
vb_keyb_from_rsa(struct rsa_st * rsa_private_key,uint8_t ** keyb_data,uint32_t * keyb_size)200 int vb_keyb_from_rsa(struct rsa_st *rsa_private_key, uint8_t **keyb_data, uint32_t *keyb_size)
201 {
202 	const BIGNUM *N;
203 	RSA_get0_key(rsa_private_key, &N, NULL, NULL);
204 	if (!N) {
205 		fprintf(stderr, "Failed to get N from RSA private key\n");
206 		return 1;
207 	}
208 	return vb_keyb_from_modulus(N, RSA_size(rsa_private_key), keyb_data, keyb_size);
209 }
210 
vb_keyb_from_private_key(struct vb2_private_key * private_key,uint8_t ** keyb_data,uint32_t * keyb_size)211 int vb_keyb_from_private_key(struct vb2_private_key *private_key, uint8_t **keyb_data,
212 			     uint32_t *keyb_size)
213 {
214 	switch (private_key->key_location) {
215 	case PRIVATE_KEY_P11:
216 		return vb_keyb_from_p11_key(private_key->p11_key, keyb_data, keyb_size);
217 	case PRIVATE_KEY_LOCAL:
218 		return vb_keyb_from_rsa(private_key->rsa_private_key, keyb_data, keyb_size);
219 	}
220 	return 1;
221 }
222 
vb2_get_sig_alg(uint32_t exp,uint32_t bits)223 enum vb2_signature_algorithm vb2_get_sig_alg(uint32_t exp, uint32_t bits)
224 {
225 	switch (exp) {
226 	case RSA_3:
227 		switch (bits) {
228 		case 2048:
229 			return VB2_SIG_RSA2048_EXP3;
230 		case 3072:
231 			return VB2_SIG_RSA3072_EXP3;
232 		}
233 		break;
234 	case RSA_F4:
235 		switch (bits) {
236 		case 1024:
237 			return VB2_SIG_RSA1024;
238 		case 2048:
239 			return VB2_SIG_RSA2048;
240 		case 4096:
241 			return VB2_SIG_RSA4096;
242 		case 8192:
243 			return VB2_SIG_RSA8192;
244 		}
245 	}
246 
247 	/* no clue */
248 	return VB2_SIG_INVALID;
249 }
250