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