1 /*
2  * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifdef ESP_PLATFORM
8 #include "mbedtls/bignum.h"
9 #endif
10 
11 #include "utils/includes.h"
12 #include "utils/common.h"
13 #include "crypto.h"
14 #include "common/defs.h"
15 
16 #ifdef CONFIG_CRYPTO_MBEDTLS
17 #include "mbedtls/entropy.h"
18 #include "mbedtls/ctr_drbg.h"
19 
20 #include <mbedtls/error.h>
21 #include <mbedtls/x509_crt.h>
22 #include <mbedtls/platform.h>
23 #include <mbedtls/sha256.h>
24 
25 /* Dummy structures; these are just typecast to struct crypto_rsa_key */
26 struct crypto_public_key;
27 struct crypto_private_key;
28 
29 #ifdef DEBUG_PRINT
crypto_dump_verify_info(u32 flags)30 static void crypto_dump_verify_info(u32 flags)
31 {
32 	char dump_buffer[1024];
33 
34 	mbedtls_x509_crt_verify_info(dump_buffer, 1024, "  ! ", flags );
35 	wpa_printf(MSG_ERROR, "%s", dump_buffer);
36 }
37 #else
crypto_dump_verify_info(u32 flags)38 static void crypto_dump_verify_info(u32 flags) { }
39 #endif
40 
crypto_rng_wrapper(void * ctx,unsigned char * buf,size_t len)41 static int crypto_rng_wrapper(void *ctx, unsigned char *buf, size_t len)
42 {
43 	return os_get_random(buf, len);
44 }
45 
crypto_verify_cert(const u8 * cert_start,int certlen,const u8 * ca_cert_start,int ca_certlen)46 int crypto_verify_cert(const u8 *cert_start, int certlen, const u8 *ca_cert_start, int ca_certlen)
47 {
48 	int ret;
49 	u32 flags = 0;
50 
51 	mbedtls_x509_crt *cert = os_zalloc(sizeof(mbedtls_x509_crt));
52 	mbedtls_x509_crt *ca_cert = os_zalloc(sizeof(mbedtls_x509_crt));
53 
54 	if (!cert || !ca_cert) {
55 		if (cert)
56 			os_free(cert);
57 		if (ca_cert)
58 			os_free(ca_cert);
59 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
60 		return -1;
61 	}
62 	mbedtls_x509_crt_init(cert);
63 	mbedtls_x509_crt_init(ca_cert);
64 	ret = mbedtls_x509_crt_parse(cert, cert_start, certlen);
65 	if (ret < 0) {
66 		wpa_printf(MSG_ERROR, "peer cert parsing failed");
67 		goto cleanup;
68 	}
69 	ret = mbedtls_x509_crt_parse(ca_cert, ca_cert_start, ca_certlen);
70 	if (ret < 0) {
71 		wpa_printf(MSG_ERROR, "CA cert parsing failed");
72 		goto cleanup;
73 	}
74 
75 	ret = mbedtls_x509_crt_verify(cert, ca_cert, NULL, NULL, &flags, NULL, NULL );
76 
77 	/* Certification is failed, try to get some more info */
78 	if (ret != 0)
79 		crypto_dump_verify_info(flags);
80 
81 cleanup:
82 	mbedtls_x509_crt_free(cert);
83 	mbedtls_x509_crt_free(ca_cert);
84 
85 	os_free(cert);
86 	os_free(ca_cert);
87 
88 	return ret;
89 }
90 
crypto_public_key_import(const u8 * key,size_t len)91 struct crypto_public_key *  crypto_public_key_import(const u8 *key, size_t len)
92 {
93 	int ret;
94 	mbedtls_pk_context *pkey = os_zalloc(sizeof(*pkey));
95 
96 	if (!pkey)
97 		return NULL;
98 
99 	mbedtls_pk_init(pkey);
100 	ret = mbedtls_pk_parse_public_key(pkey, key, len);
101 
102 	if (ret < 0) {
103 		wpa_printf(MSG_ERROR, "failed to parse public key");
104 		os_free(pkey);
105 		return NULL;
106 	}
107 
108 	return (struct crypto_public_key *)pkey;
109 }
110 
crypto_private_key_import(const u8 * key,size_t len,const char * passwd)111 struct crypto_private_key *  crypto_private_key_import(const u8 *key,
112 		size_t len,
113 		const char *passwd)
114 {
115 	int ret;
116 	mbedtls_pk_context *pkey = os_zalloc(sizeof(mbedtls_pk_context));
117 	if (!pkey)
118 		return NULL;
119 
120 	mbedtls_pk_init(pkey);
121 
122 	ret = mbedtls_pk_parse_key(pkey, key, len, (const unsigned char *)passwd,
123 			passwd ? os_strlen(passwd) : 0, crypto_rng_wrapper, NULL);
124 
125 	if (ret < 0) {
126 		wpa_printf(MSG_ERROR, "failed to parse private key");
127 		os_free(pkey);
128 		pkey = NULL;
129 	}
130 
131 	return (struct crypto_private_key *)pkey;
132 }
133 
crypto_public_key_from_cert(const u8 * buf,size_t len)134 struct crypto_public_key *crypto_public_key_from_cert(const u8 *buf,
135 		size_t len)
136 {
137 	int ret;
138 	mbedtls_x509_crt *cert;
139 	mbedtls_pk_context *kctx = os_zalloc(sizeof(*kctx));
140 
141 	if (!kctx) {
142 		wpa_printf(MSG_ERROR, "failed to allocate memory");
143 		return NULL;
144 	}
145 
146 	cert = os_zalloc(sizeof(mbedtls_x509_crt));
147 	if (!cert) {
148 		wpa_printf(MSG_ERROR, "failed to allocate memory");
149 		goto fail;
150 	}
151 	mbedtls_x509_crt_init(cert);
152 
153 	ret = mbedtls_x509_crt_parse(cert, buf, len);
154 	if (ret < 0) {
155 		wpa_printf(MSG_ERROR, "cert parsing failed");
156 		goto fail;
157 	}
158 
159 	mbedtls_pk_init(kctx);
160 
161 	if(mbedtls_pk_setup(kctx, mbedtls_pk_info_from_type(mbedtls_pk_get_type(&cert->pk))) != 0) {
162 		wpa_printf(MSG_ERROR, "key setup failed");
163 		goto fail;
164 	}
165 	ret = mbedtls_rsa_copy(mbedtls_pk_rsa(*kctx), mbedtls_pk_rsa(cert->pk));
166 
167 	if (ret < 0) {
168 		wpa_printf(MSG_ERROR, "key copy failed");
169 		goto fail;
170 	}
171 
172 cleanup:
173 	mbedtls_x509_crt_free(cert);
174 	os_free(cert);
175 	return (struct crypto_public_key *)kctx;
176 fail:
177 	os_free(kctx);
178 	kctx = NULL;
179 	goto cleanup;
180 }
181 
crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)182 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
183 		const u8 *in, size_t inlen,
184 		u8 *out, size_t *outlen)
185 {
186 	int ret;
187 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
188 	const char *pers = "rsa_encrypt";
189 	mbedtls_entropy_context *entropy = os_zalloc(sizeof(*entropy));
190 	mbedtls_ctr_drbg_context *ctr_drbg = os_zalloc(sizeof(*ctr_drbg));
191 
192 	if (!pkey || !entropy || !ctr_drbg) {
193 		if (entropy)
194 			os_free(entropy);
195 		if (ctr_drbg)
196 			os_free(ctr_drbg);
197 		wpa_printf(MSG_ERROR, "failed to allocate memory");
198 		return -1;
199 	}
200 
201 	mbedtls_entropy_init( entropy );
202 	mbedtls_ctr_drbg_init( ctr_drbg );
203 
204 	ret = mbedtls_ctr_drbg_seed( ctr_drbg, mbedtls_entropy_func,
205 			entropy, (const unsigned char *) pers,
206 			strlen( pers ) );
207 	if( ret != 0 ) {
208 		wpa_printf(MSG_ERROR, " failed  ! mbedtls_ctr_drbg_seed returned %d",
209 				ret );
210 		goto cleanup;
211 	}
212 
213 	ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random,
214 					ctr_drbg, inlen, in, out);
215 
216 	if(ret != 0) {
217 		wpa_printf(MSG_ERROR, " failed  !  mbedtls_rsa_pkcs1_encrypt returned -0x%04x", -ret);
218 		goto cleanup;
219 	}
220 	*outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey));
221 
222 cleanup:
223 	mbedtls_ctr_drbg_free( ctr_drbg );
224 	mbedtls_entropy_free( entropy );
225 	os_free(entropy);
226 	os_free(ctr_drbg);
227 
228 	return ret;
229 }
230 
231 
crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)232 int  crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
233 		const u8 *in, size_t inlen,
234 		u8 *out, size_t *outlen)
235 {
236 	int ret;
237 	size_t i;
238 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
239 	const char *pers = "rsa_decrypt";
240 	mbedtls_entropy_context *entropy = os_malloc(sizeof(*entropy));
241 	mbedtls_ctr_drbg_context *ctr_drbg = os_malloc(sizeof(*ctr_drbg));
242 
243 	if (!pkey || !entropy || !ctr_drbg) {
244 		if (entropy)
245 			os_free(entropy);
246 		if (ctr_drbg)
247 			os_free(ctr_drbg);
248 		return -1;
249 	}
250 	mbedtls_ctr_drbg_init( ctr_drbg );
251 	mbedtls_entropy_init( entropy );
252 	ret = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func,
253 			entropy, (const unsigned char *) pers,
254 			strlen(pers));
255 
256 	if (ret < 0)
257 		goto cleanup;
258 
259 	i = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey));
260 	ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random,
261 			ctr_drbg, &i, in, out, *outlen);
262 
263 	*outlen = i;
264 
265 cleanup:
266 	mbedtls_ctr_drbg_free( ctr_drbg );
267 	mbedtls_entropy_free( entropy );
268 	os_free(entropy);
269 	os_free(ctr_drbg);
270 
271 	return ret;
272 }
273 
274 
crypto_private_key_sign_pkcs1(struct crypto_private_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)275 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
276 		const u8 *in, size_t inlen,
277 		u8 *out, size_t *outlen)
278 {
279 	int ret;
280 	const char *pers = "rsa_encrypt";
281 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
282 	mbedtls_entropy_context *entropy = os_malloc(sizeof(*entropy));
283 	mbedtls_ctr_drbg_context *ctr_drbg = os_malloc(sizeof(*ctr_drbg));
284 
285 	if (!pkey || !entropy || !ctr_drbg) {
286 		if (entropy)
287 			os_free(entropy);
288 		if (ctr_drbg)
289 			os_free(ctr_drbg);
290 		return -1;
291 	}
292 	mbedtls_ctr_drbg_init( ctr_drbg );
293 	mbedtls_entropy_init( entropy );
294 	ret = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func,
295 			entropy, (const unsigned char *) pers,
296 			strlen(pers));
297 
298 	if((ret = mbedtls_rsa_pkcs1_sign(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random, ctr_drbg,
299 					(mbedtls_pk_rsa(*pkey))->MBEDTLS_PRIVATE(hash_id),
300 					inlen, in, out)) != 0 ) {
301 		wpa_printf(MSG_ERROR, " failed  ! mbedtls_rsa_pkcs1_sign returned %d", ret );
302 		goto cleanup;
303 	}
304 	*outlen = mbedtls_rsa_get_len(mbedtls_pk_rsa(*pkey));
305 
306 cleanup:
307 	mbedtls_ctr_drbg_free( ctr_drbg );
308 	mbedtls_entropy_free( entropy );
309 	os_free(entropy);
310 	os_free(ctr_drbg);
311 	return ret;
312 }
313 
314 
crypto_public_key_free(struct crypto_public_key * key)315 void  crypto_public_key_free(struct crypto_public_key *key)
316 {
317 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
318 	if (!pkey)
319 		return;
320 
321 	mbedtls_pk_free(pkey);
322 	os_free(pkey);
323 }
324 
325 
crypto_private_key_free(struct crypto_private_key * key)326 void  crypto_private_key_free(struct crypto_private_key *key)
327 {
328 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
329 	if (!pkey)
330 		return;
331 
332 	mbedtls_pk_free(pkey);
333 	os_free(pkey);
334 }
335 
crypto_public_key_decrypt_pkcs1(struct crypto_public_key * key,const u8 * crypt,size_t crypt_len,u8 * plain,size_t * plain_len)336 int  crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
337 		const u8 *crypt, size_t crypt_len,
338 		u8 *plain, size_t *plain_len)
339 {
340 	size_t len;
341 	u8 *pos;
342 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
343 	len = mbedtls_pk_rsa(*pkey)->MBEDTLS_PRIVATE(len);
344 	if (len != crypt_len) {
345 		return -1;
346 	}
347 
348 	if (mbedtls_rsa_public(mbedtls_pk_rsa(*pkey), crypt, plain) < 0)
349 		return -1;
350 
351 	/*
352 	 * PKCS #1 v1.5, 8.1:
353 	 *
354 	 * EB = 00 || BT || PS || 00 || D
355 	 * BT = 00 or 01
356 	 * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
357 	 * k = length of modulus in octets
358 	 *
359 	 * Based on 10.1.3, "The block type shall be 01" for a signature.
360 	 */
361 
362 	if (len < 3 + 8 + 16 /* min hash len */ ||
363 	    plain[0] != 0x00 || plain[1] != 0x01) {
364 		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
365 			   "structure");
366 		wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
367 		return -1;
368 	}
369 
370 	pos = plain + 3;
371 	/* BT = 01 */
372 	if (plain[2] != 0xff) {
373 		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
374 			   "PS (BT=01)");
375 		wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
376 		return -1;
377 	}
378 	while (pos < plain + len && *pos == 0xff)
379 		pos++;
380 
381 	if (pos - plain - 2 < 8) {
382 		/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
383 		wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
384 			   "padding");
385 		wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
386 		return -1;
387 	}
388 
389 	if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
390 		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
391 			   "structure (2)");
392 		wpa_hexdump_key(MSG_DEBUG, "Signature EB", plain, len);
393 		return -1;
394 	}
395 	pos++;
396 	len -= pos - plain;
397 
398 	/* Strip PKCS #1 header */
399 	os_memmove(plain, pos, len);
400 	*plain_len = len;
401 
402 	return 0;
403 }
404 #endif
405