1 /*
2  * Copyright (C) Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License.
3  *
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifdef ESP_PLATFORM
19 #include "mbedtls/bignum.h"
20 #endif
21 
22 #include "utils/includes.h"
23 #include "utils/common.h"
24 #include "crypto.h"
25 #include "common/defs.h"
26 
27 #ifdef USE_MBEDTLS_CRYPTO
28 #include "mbedtls/entropy.h"
29 #include "mbedtls/ctr_drbg.h"
30 
31 #include <mbedtls/error.h>
32 #include <mbedtls/x509_crt.h>
33 #include <mbedtls/platform.h>
34 #include <mbedtls/sha256.h>
35 
36 /* Dummy structures; these are just typecast to struct crypto_rsa_key */
37 struct crypto_public_key;
38 struct crypto_private_key;
39 
crypto_dump_verify_info(u32 flags)40 static void crypto_dump_verify_info(u32 flags)
41 {
42 	char dump_buffer[1024];
43 
44 	mbedtls_x509_crt_verify_info(dump_buffer, 1024, "  ! ", flags );
45 	wpa_printf(MSG_ERROR, "%s", dump_buffer);
46 }
47 
crypto_verify_cert(const u8 * cert_start,int certlen,const u8 * ca_cert_start,int ca_certlen)48 int crypto_verify_cert(const u8 *cert_start, int certlen, const u8 *ca_cert_start, int ca_certlen)
49 {
50 	int ret;
51 	u32 flags = 0;
52 
53 	mbedtls_x509_crt *cert = os_zalloc(sizeof(mbedtls_x509_crt));
54 	mbedtls_x509_crt *ca_cert = os_zalloc(sizeof(mbedtls_x509_crt));
55 
56 	if (!cert || !ca_cert) {
57 		if (cert)
58 			os_free(cert);
59 		if (ca_cert)
60 			os_free(ca_cert);
61 		wpa_printf(MSG_ERROR, "%s: memory allocation failed", __func__);
62 		return -1;
63 	}
64 	mbedtls_x509_crt_init(cert);
65 	mbedtls_x509_crt_init(ca_cert);
66 	ret = mbedtls_x509_crt_parse(cert, cert_start, certlen);
67 	if (ret < 0) {
68 		wpa_printf(MSG_ERROR, "peer cert parsing failed");
69 		goto cleanup;
70 	}
71 	ret = mbedtls_x509_crt_parse(ca_cert, ca_cert_start, ca_certlen);
72 	if (ret < 0) {
73 		wpa_printf(MSG_ERROR, "CA cert parsing failed");
74 		goto cleanup;
75 	}
76 
77 	ret = mbedtls_x509_crt_verify(cert, ca_cert, NULL, NULL, &flags, NULL, NULL );
78 
79 	/* Certification is failed, try to get some more info */
80 	if (ret != 0)
81 		crypto_dump_verify_info(flags);
82 
83 cleanup:
84 	mbedtls_x509_crt_free(cert);
85 	mbedtls_x509_crt_free(ca_cert);
86 
87 	os_free(cert);
88 	os_free(ca_cert);
89 
90 	return ret;
91 }
92 
crypto_public_key_import(const u8 * key,size_t len)93 struct crypto_public_key *  crypto_public_key_import(const u8 *key, size_t len)
94 {
95 	int ret;
96 	mbedtls_pk_context *pkey = os_zalloc(sizeof(*pkey));
97 
98 	if (!pkey)
99 		return NULL;
100 
101 	mbedtls_pk_init(pkey);
102 	ret = mbedtls_pk_parse_public_key(pkey, key, len);
103 
104 	if (ret < 0) {
105 		wpa_printf(MSG_ERROR, "failed to parse public key");
106 		os_free(pkey);
107 		return NULL;
108 	}
109 
110 	return (struct crypto_public_key *)pkey;
111 }
112 
crypto_private_key_import(const u8 * key,size_t len,const char * passwd)113 struct crypto_private_key *  crypto_private_key_import(const u8 *key,
114 		size_t len,
115 		const char *passwd)
116 {
117 	int ret;
118 	mbedtls_pk_context *pkey = os_zalloc(sizeof(mbedtls_pk_context));
119 	if (!pkey)
120 		return NULL;
121 
122 	mbedtls_pk_init(pkey);
123 
124 	ret = mbedtls_pk_parse_key(pkey, key, len, (const unsigned char *)passwd, passwd ? os_strlen(passwd) : 0);
125 
126 	if (ret < 0) {
127 		wpa_printf(MSG_ERROR, "failed to parse private key");
128 		os_free(pkey);
129 		pkey = NULL;
130 	}
131 
132 	return (struct crypto_private_key *)pkey;
133 }
134 
crypto_public_key_from_cert(const u8 * buf,size_t len)135 struct crypto_public_key *crypto_public_key_from_cert(const u8 *buf,
136 		size_t len)
137 {
138 	int ret;
139 	mbedtls_x509_crt *cert;
140 	mbedtls_pk_context *kctx = os_zalloc(sizeof(*kctx));
141 
142 	if (!kctx) {
143 		wpa_printf(MSG_ERROR, "failed to allocate memory");
144 		return NULL;
145 	}
146 
147 	cert = os_zalloc(sizeof(mbedtls_x509_crt));
148 	if (!cert) {
149 		wpa_printf(MSG_ERROR, "failed to allocate memory");
150 		goto fail;
151 	}
152 	mbedtls_x509_crt_init(cert);
153 
154 	ret = mbedtls_x509_crt_parse(cert, buf, len);
155 	if (ret < 0) {
156 		wpa_printf(MSG_ERROR, "cert parsing failed");
157 		goto fail;
158 	}
159 
160 	mbedtls_pk_init(kctx);
161 
162 	if(mbedtls_pk_setup(kctx, mbedtls_pk_info_from_type(mbedtls_pk_get_type(&cert->pk))) != 0) {
163 		wpa_printf(MSG_ERROR, "key setup failed");
164 		goto fail;
165 	}
166 	ret = mbedtls_rsa_copy(mbedtls_pk_rsa(*kctx), mbedtls_pk_rsa(cert->pk));
167 
168 	if (ret < 0) {
169 		wpa_printf(MSG_ERROR, "key copy failed");
170 		goto fail;
171 	}
172 
173 cleanup:
174 	mbedtls_x509_crt_free(cert);
175 	os_free(cert);
176 	return (struct crypto_public_key *)kctx;
177 fail:
178 	os_free(kctx);
179 	kctx = NULL;
180 	goto cleanup;
181 }
182 
crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)183 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
184 		const u8 *in, size_t inlen,
185 		u8 *out, size_t *outlen)
186 {
187 	int ret;
188 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
189 	const char *pers = "rsa_encrypt";
190 	mbedtls_entropy_context *entropy = os_zalloc(sizeof(*entropy));
191 	mbedtls_ctr_drbg_context *ctr_drbg = os_zalloc(sizeof(*ctr_drbg));
192 
193 	if (!pkey || !entropy || !ctr_drbg) {
194 		if (entropy)
195 			os_free(entropy);
196 		if (ctr_drbg)
197 			os_free(ctr_drbg);
198 		wpa_printf(MSG_ERROR, "failed to allocate memory");
199 		return -1;
200 	}
201 
202 	mbedtls_entropy_init( entropy );
203 	mbedtls_ctr_drbg_init( ctr_drbg );
204 
205 	ret = mbedtls_ctr_drbg_seed( ctr_drbg, mbedtls_entropy_func,
206 			entropy, (const unsigned char *) pers,
207 			strlen( pers ) );
208 	if( ret != 0 ) {
209 		wpa_printf(MSG_ERROR, " failed  ! mbedtls_ctr_drbg_seed returned %d",
210 				ret );
211 		goto cleanup;
212 	}
213 
214 	ret = mbedtls_rsa_pkcs1_encrypt(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random,
215 			ctr_drbg, MBEDTLS_RSA_PUBLIC, inlen, in, out);
216 
217 	if(ret != 0) {
218 		wpa_printf(MSG_ERROR, " failed  !  mbedtls_rsa_pkcs1_encrypt returned -0x%04x", -ret);
219 		goto cleanup;
220 	}
221 	*outlen = mbedtls_pk_rsa(*pkey)->len;
222 
223 cleanup:
224 	mbedtls_ctr_drbg_free( ctr_drbg );
225 	mbedtls_entropy_free( entropy );
226 	os_free(entropy);
227 	os_free(ctr_drbg);
228 
229 	return ret;
230 }
231 
232 
crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)233 int  crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
234 		const u8 *in, size_t inlen,
235 		u8 *out, size_t *outlen)
236 {
237 	int ret;
238 	size_t i;
239 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
240 	const char *pers = "rsa_decrypt";
241 	mbedtls_entropy_context *entropy = os_malloc(sizeof(*entropy));
242 	mbedtls_ctr_drbg_context *ctr_drbg = os_malloc(sizeof(*ctr_drbg));
243 
244 	if (!pkey || !entropy || !ctr_drbg) {
245 		if (entropy)
246 			os_free(entropy);
247 		if (ctr_drbg)
248 			os_free(ctr_drbg);
249 		return -1;
250 	}
251 	mbedtls_ctr_drbg_init( ctr_drbg );
252 	mbedtls_entropy_init( entropy );
253 	ret = mbedtls_ctr_drbg_seed(ctr_drbg, mbedtls_entropy_func,
254 			entropy, (const unsigned char *) pers,
255 			strlen(pers));
256 
257 	if (ret < 0)
258 		goto cleanup;
259 
260 	i =  mbedtls_pk_rsa(*pkey)->len;
261 	ret = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random,
262 			ctr_drbg, MBEDTLS_RSA_PRIVATE, &i, in, out, *outlen);
263 
264 	*outlen = i;
265 
266 cleanup:
267 	mbedtls_ctr_drbg_free( ctr_drbg );
268 	mbedtls_entropy_free( entropy );
269 	os_free(entropy);
270 	os_free(ctr_drbg);
271 
272 	return ret;
273 }
274 
275 
crypto_private_key_sign_pkcs1(struct crypto_private_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)276 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
277 		const u8 *in, size_t inlen,
278 		u8 *out, size_t *outlen)
279 {
280 	int ret;
281 	mbedtls_pk_context *pkey  = (mbedtls_pk_context *)key;
282 
283 	if((ret = mbedtls_rsa_pkcs1_sign(mbedtls_pk_rsa(*pkey), NULL, NULL, MBEDTLS_RSA_PRIVATE,
284 					(mbedtls_pk_rsa(*pkey))->hash_id,
285 					inlen, in, out)) != 0 ) {
286 		wpa_printf(MSG_ERROR, " failed  ! mbedtls_rsa_pkcs1_sign returned %d", ret );
287 		return -1;
288 	}
289 	*outlen = mbedtls_pk_rsa(*pkey)->len;
290 
291 	return 0;
292 }
293 
294 
crypto_public_key_free(struct crypto_public_key * key)295 void  crypto_public_key_free(struct crypto_public_key *key)
296 {
297 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
298 	if (!pkey)
299 		return;
300 
301 	mbedtls_pk_free(pkey);
302 	os_free(pkey);
303 }
304 
305 
crypto_private_key_free(struct crypto_private_key * key)306 void  crypto_private_key_free(struct crypto_private_key *key)
307 {
308 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
309 	if (!pkey)
310 		return;
311 
312 	mbedtls_pk_free(pkey);
313 	os_free(pkey);
314 }
315 
316 
crypto_public_key_decrypt_pkcs1(struct crypto_public_key * key,const u8 * crypt,size_t crypt_len,u8 * plain,size_t * plain_len)317 int  crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
318 		const u8 *crypt, size_t crypt_len,
319 		u8 *plain, size_t *plain_len)
320 {
321 	const char *pers = "rsa_decrypt";
322 	mbedtls_pk_context *pkey = (mbedtls_pk_context *)key;
323 	mbedtls_ctr_drbg_context ctr_drbg;
324 	mbedtls_entropy_context entropy;
325 	size_t i;
326 
327 	mbedtls_entropy_init( &entropy );
328 	mbedtls_ctr_drbg_init( &ctr_drbg );
329 
330 	int ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func,
331 			&entropy, (const unsigned char *) pers,
332 			strlen( pers ) );
333 	if(ret != 0) {
334 		wpa_printf(MSG_ERROR, " failed  ! mbedtls_ctr_drbg_seed returned %d",
335 				ret );
336 		goto cleanup;
337 	}
338 
339 	i =  mbedtls_pk_rsa(*pkey)->len;
340 	ret = mbedtls_rsa_pkcs1_decrypt(mbedtls_pk_rsa(*pkey), mbedtls_ctr_drbg_random,
341 			&ctr_drbg, MBEDTLS_RSA_PUBLIC, &i,
342 			crypt, plain, *plain_len);
343 	if( ret != 0 ) {
344 		wpa_printf(MSG_ERROR, " failed ! mbedtls_rsa_pkcs1_decrypt returned %d",
345 				ret );
346 		goto cleanup;
347 	}
348 	*plain_len = i;
349 
350 cleanup:
351 	mbedtls_entropy_free( &entropy );
352 	mbedtls_ctr_drbg_free( &ctr_drbg );
353 
354 	return ret;
355 }
356 #endif
357