• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * WPA Supplicant / Crypto wrapper for internal crypto implementation
3  * Copyright (c) 2006, Jouni Malinen <j@w1.fi>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14 
15 #include "includes.h"
16 
17 #include "common.h"
18 #include "crypto.h"
19 #include "md5.h"
20 #include "sha1.h"
21 #include "rc4.h"
22 #include "aes.h"
23 #include "rsa.h"
24 #include "bignum.h"
25 
26 
27 #ifdef EAP_TLS_FUNCS
28 
29 #ifdef CONFIG_TLS_INTERNAL
30 
31 /* from des.c */
32 struct des3_key_s {
33 	u32 ek[3][32];
34 	u32 dk[3][32];
35 };
36 
37 void des3_key_setup(const u8 *key, struct des3_key_s *dkey);
38 void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt);
39 void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain);
40 
41 
42 struct MD5Context {
43 	u32 buf[4];
44 	u32 bits[2];
45 	u8 in[64];
46 };
47 
48 struct SHA1Context {
49 	u32 state[5];
50 	u32 count[2];
51 	unsigned char buffer[64];
52 };
53 
54 
55 struct crypto_hash {
56 	enum crypto_hash_alg alg;
57 	union {
58 		struct MD5Context md5;
59 		struct SHA1Context sha1;
60 	} u;
61 	u8 key[64];
62 	size_t key_len;
63 };
64 
65 
crypto_hash_init(enum crypto_hash_alg alg,const u8 * key,size_t key_len)66 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
67 				      size_t key_len)
68 {
69 	struct crypto_hash *ctx;
70 	u8 k_pad[64];
71 	u8 tk[20];
72 	size_t i;
73 
74 	ctx = os_zalloc(sizeof(*ctx));
75 	if (ctx == NULL)
76 		return NULL;
77 
78 	ctx->alg = alg;
79 
80 	switch (alg) {
81 	case CRYPTO_HASH_ALG_MD5:
82 		MD5Init(&ctx->u.md5);
83 		break;
84 	case CRYPTO_HASH_ALG_SHA1:
85 		SHA1Init(&ctx->u.sha1);
86 		break;
87 	case CRYPTO_HASH_ALG_HMAC_MD5:
88 		if (key_len > sizeof(k_pad)) {
89 			MD5Init(&ctx->u.md5);
90 			MD5Update(&ctx->u.md5, key, key_len);
91 			MD5Final(tk, &ctx->u.md5);
92 			key = tk;
93 			key_len = 16;
94 		}
95 		os_memcpy(ctx->key, key, key_len);
96 		ctx->key_len = key_len;
97 
98 		os_memcpy(k_pad, key, key_len);
99 		os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
100 		for (i = 0; i < sizeof(k_pad); i++)
101 			k_pad[i] ^= 0x36;
102 		MD5Init(&ctx->u.md5);
103 		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
104 		break;
105 	case CRYPTO_HASH_ALG_HMAC_SHA1:
106 		if (key_len > sizeof(k_pad)) {
107 			SHA1Init(&ctx->u.sha1);
108 			SHA1Update(&ctx->u.sha1, key, key_len);
109 			SHA1Final(tk, &ctx->u.sha1);
110 			key = tk;
111 			key_len = 20;
112 		}
113 		os_memcpy(ctx->key, key, key_len);
114 		ctx->key_len = key_len;
115 
116 		os_memcpy(k_pad, key, key_len);
117 		os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
118 		for (i = 0; i < sizeof(k_pad); i++)
119 			k_pad[i] ^= 0x36;
120 		SHA1Init(&ctx->u.sha1);
121 		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
122 		break;
123 	default:
124 		os_free(ctx);
125 		return NULL;
126 	}
127 
128 	return ctx;
129 }
130 
131 
crypto_hash_update(struct crypto_hash * ctx,const u8 * data,size_t len)132 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
133 {
134 	if (ctx == NULL)
135 		return;
136 
137 	switch (ctx->alg) {
138 	case CRYPTO_HASH_ALG_MD5:
139 	case CRYPTO_HASH_ALG_HMAC_MD5:
140 		MD5Update(&ctx->u.md5, data, len);
141 		break;
142 	case CRYPTO_HASH_ALG_SHA1:
143 	case CRYPTO_HASH_ALG_HMAC_SHA1:
144 		SHA1Update(&ctx->u.sha1, data, len);
145 		break;
146 	}
147 }
148 
149 
crypto_hash_finish(struct crypto_hash * ctx,u8 * mac,size_t * len)150 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
151 {
152 	u8 k_pad[64];
153 	size_t i;
154 
155 	if (ctx == NULL)
156 		return -2;
157 
158 	if (mac == NULL || len == NULL) {
159 		os_free(ctx);
160 		return 0;
161 	}
162 
163 	switch (ctx->alg) {
164 	case CRYPTO_HASH_ALG_MD5:
165 		if (*len < 16) {
166 			*len = 16;
167 			os_free(ctx);
168 			return -1;
169 		}
170 		*len = 16;
171 		MD5Final(mac, &ctx->u.md5);
172 		break;
173 	case CRYPTO_HASH_ALG_SHA1:
174 		if (*len < 20) {
175 			*len = 20;
176 			os_free(ctx);
177 			return -1;
178 		}
179 		*len = 20;
180 		SHA1Final(mac, &ctx->u.sha1);
181 		break;
182 	case CRYPTO_HASH_ALG_HMAC_MD5:
183 		if (*len < 16) {
184 			*len = 16;
185 			os_free(ctx);
186 			return -1;
187 		}
188 		*len = 16;
189 
190 		MD5Final(mac, &ctx->u.md5);
191 
192 		os_memcpy(k_pad, ctx->key, ctx->key_len);
193 		os_memset(k_pad + ctx->key_len, 0,
194 			  sizeof(k_pad) - ctx->key_len);
195 		for (i = 0; i < sizeof(k_pad); i++)
196 			k_pad[i] ^= 0x5c;
197 		MD5Init(&ctx->u.md5);
198 		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
199 		MD5Update(&ctx->u.md5, mac, 16);
200 		MD5Final(mac, &ctx->u.md5);
201 		break;
202 	case CRYPTO_HASH_ALG_HMAC_SHA1:
203 		if (*len < 20) {
204 			*len = 20;
205 			os_free(ctx);
206 			return -1;
207 		}
208 		*len = 20;
209 
210 		SHA1Final(mac, &ctx->u.sha1);
211 
212 		os_memcpy(k_pad, ctx->key, ctx->key_len);
213 		os_memset(k_pad + ctx->key_len, 0,
214 			  sizeof(k_pad) - ctx->key_len);
215 		for (i = 0; i < sizeof(k_pad); i++)
216 			k_pad[i] ^= 0x5c;
217 		SHA1Init(&ctx->u.sha1);
218 		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
219 		SHA1Update(&ctx->u.sha1, mac, 20);
220 		SHA1Final(mac, &ctx->u.sha1);
221 		break;
222 	}
223 
224 	os_free(ctx);
225 
226 	return 0;
227 }
228 
229 
230 struct crypto_cipher {
231 	enum crypto_cipher_alg alg;
232 	union {
233 		struct {
234 			size_t used_bytes;
235 			u8 key[16];
236 			size_t keylen;
237 		} rc4;
238 		struct {
239 			u8 cbc[32];
240 			size_t block_size;
241 			void *ctx_enc;
242 			void *ctx_dec;
243 		} aes;
244 		struct {
245 			struct des3_key_s key;
246 			u8 cbc[8];
247 		} des3;
248 	} u;
249 };
250 
251 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)252 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
253 					  const u8 *iv, const u8 *key,
254 					  size_t key_len)
255 {
256 	struct crypto_cipher *ctx;
257 
258 	ctx = os_zalloc(sizeof(*ctx));
259 	if (ctx == NULL)
260 		return NULL;
261 
262 	ctx->alg = alg;
263 
264 	switch (alg) {
265 	case CRYPTO_CIPHER_ALG_RC4:
266 		if (key_len > sizeof(ctx->u.rc4.key)) {
267 			os_free(ctx);
268 			return NULL;
269 		}
270 		ctx->u.rc4.keylen = key_len;
271 		os_memcpy(ctx->u.rc4.key, key, key_len);
272 		break;
273 	case CRYPTO_CIPHER_ALG_AES:
274 		if (key_len > sizeof(ctx->u.aes.cbc)) {
275 			os_free(ctx);
276 			return NULL;
277 		}
278 		ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
279 		if (ctx->u.aes.ctx_enc == NULL) {
280 			os_free(ctx);
281 			return NULL;
282 		}
283 		ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
284 		if (ctx->u.aes.ctx_dec == NULL) {
285 			aes_encrypt_deinit(ctx->u.aes.ctx_enc);
286 			os_free(ctx);
287 			return NULL;
288 		}
289 		ctx->u.aes.block_size = key_len;
290 		os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
291 		break;
292 	case CRYPTO_CIPHER_ALG_3DES:
293 		if (key_len != 24) {
294 			os_free(ctx);
295 			return NULL;
296 		}
297 		des3_key_setup(key, &ctx->u.des3.key);
298 		os_memcpy(ctx->u.des3.cbc, iv, 8);
299 		break;
300 	default:
301 		os_free(ctx);
302 		return NULL;
303 	}
304 
305 	return ctx;
306 }
307 
308 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)309 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
310 			  u8 *crypt, size_t len)
311 {
312 	size_t i, j, blocks;
313 
314 	switch (ctx->alg) {
315 	case CRYPTO_CIPHER_ALG_RC4:
316 		if (plain != crypt)
317 			os_memcpy(crypt, plain, len);
318 		rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
319 			 ctx->u.rc4.used_bytes, crypt, len);
320 		ctx->u.rc4.used_bytes += len;
321 		break;
322 	case CRYPTO_CIPHER_ALG_AES:
323 		if (len % ctx->u.aes.block_size)
324 			return -1;
325 		blocks = len / ctx->u.aes.block_size;
326 		for (i = 0; i < blocks; i++) {
327 			for (j = 0; j < ctx->u.aes.block_size; j++)
328 				ctx->u.aes.cbc[j] ^= plain[j];
329 			aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
330 				    ctx->u.aes.cbc);
331 			os_memcpy(crypt, ctx->u.aes.cbc,
332 				  ctx->u.aes.block_size);
333 			plain += ctx->u.aes.block_size;
334 			crypt += ctx->u.aes.block_size;
335 		}
336 		break;
337 	case CRYPTO_CIPHER_ALG_3DES:
338 		if (len % 8)
339 			return -1;
340 		blocks = len / 8;
341 		for (i = 0; i < blocks; i++) {
342 			for (j = 0; j < 8; j++)
343 				ctx->u.des3.cbc[j] ^= plain[j];
344 			des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
345 				     ctx->u.des3.cbc);
346 			os_memcpy(crypt, ctx->u.des3.cbc, 8);
347 			plain += 8;
348 			crypt += 8;
349 		}
350 		break;
351 	default:
352 		return -1;
353 	}
354 
355 	return 0;
356 }
357 
358 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)359 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
360 			  u8 *plain, size_t len)
361 {
362 	size_t i, j, blocks;
363 	u8 tmp[32];
364 
365 	switch (ctx->alg) {
366 	case CRYPTO_CIPHER_ALG_RC4:
367 		if (plain != crypt)
368 			os_memcpy(plain, crypt, len);
369 		rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
370 			 ctx->u.rc4.used_bytes, plain, len);
371 		ctx->u.rc4.used_bytes += len;
372 		break;
373 	case CRYPTO_CIPHER_ALG_AES:
374 		if (len % ctx->u.aes.block_size)
375 			return -1;
376 		blocks = len / ctx->u.aes.block_size;
377 		for (i = 0; i < blocks; i++) {
378 			os_memcpy(tmp, crypt, ctx->u.aes.block_size);
379 			aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
380 			for (j = 0; j < ctx->u.aes.block_size; j++)
381 				plain[j] ^= ctx->u.aes.cbc[j];
382 			os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
383 			plain += ctx->u.aes.block_size;
384 			crypt += ctx->u.aes.block_size;
385 		}
386 		break;
387 	case CRYPTO_CIPHER_ALG_3DES:
388 		if (len % 8)
389 			return -1;
390 		blocks = len / 8;
391 		for (i = 0; i < blocks; i++) {
392 			os_memcpy(tmp, crypt, 8);
393 			des3_decrypt(crypt, &ctx->u.des3.key, plain);
394 			for (j = 0; j < 8; j++)
395 				plain[j] ^= ctx->u.des3.cbc[j];
396 			os_memcpy(ctx->u.des3.cbc, tmp, 8);
397 			plain += 8;
398 			crypt += 8;
399 		}
400 		break;
401 	default:
402 		return -1;
403 	}
404 
405 	return 0;
406 }
407 
408 
crypto_cipher_deinit(struct crypto_cipher * ctx)409 void crypto_cipher_deinit(struct crypto_cipher *ctx)
410 {
411 	switch (ctx->alg) {
412 	case CRYPTO_CIPHER_ALG_AES:
413 		aes_encrypt_deinit(ctx->u.aes.ctx_enc);
414 		aes_decrypt_deinit(ctx->u.aes.ctx_dec);
415 		break;
416 	case CRYPTO_CIPHER_ALG_3DES:
417 		break;
418 	default:
419 		break;
420 	}
421 	os_free(ctx);
422 }
423 
424 
425 /* Dummy structures; these are just typecast to struct crypto_rsa_key */
426 struct crypto_public_key;
427 struct crypto_private_key;
428 
429 
crypto_public_key_import(const u8 * key,size_t len)430 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
431 {
432 	return (struct crypto_public_key *)
433 		crypto_rsa_import_public_key(key, len);
434 }
435 
436 
crypto_private_key_import(const u8 * key,size_t len)437 struct crypto_private_key * crypto_private_key_import(const u8 *key,
438 						      size_t len)
439 {
440 	return (struct crypto_private_key *)
441 		crypto_rsa_import_private_key(key, len);
442 }
443 
444 
crypto_public_key_from_cert(const u8 * buf,size_t len)445 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
446 						       size_t len)
447 {
448 	/* No X.509 support in crypto_internal.c */
449 	return NULL;
450 }
451 
452 
pkcs1_generate_encryption_block(u8 block_type,size_t modlen,const u8 * in,size_t inlen,u8 * out,size_t * outlen)453 static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
454 					   const u8 *in, size_t inlen,
455 					   u8 *out, size_t *outlen)
456 {
457 	size_t ps_len;
458 	u8 *pos;
459 
460 	/*
461 	 * PKCS #1 v1.5, 8.1:
462 	 *
463 	 * EB = 00 || BT || PS || 00 || D
464 	 * BT = 00 or 01 for private-key operation; 02 for public-key operation
465 	 * PS = k-3-||D||; at least eight octets
466 	 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
467 	 * k = length of modulus in octets (modlen)
468 	 */
469 
470 	if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
471 		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
472 			   "lengths (modlen=%lu outlen=%lu inlen=%lu)",
473 			   __func__, (unsigned long) modlen,
474 			   (unsigned long) *outlen,
475 			   (unsigned long) inlen);
476 		return -1;
477 	}
478 
479 	pos = out;
480 	*pos++ = 0x00;
481 	*pos++ = block_type; /* BT */
482 	ps_len = modlen - inlen - 3;
483 	switch (block_type) {
484 	case 0:
485 		os_memset(pos, 0x00, ps_len);
486 		pos += ps_len;
487 		break;
488 	case 1:
489 		os_memset(pos, 0xff, ps_len);
490 		pos += ps_len;
491 		break;
492 	case 2:
493 		if (os_get_random(pos, ps_len) < 0) {
494 			wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
495 				   "random data for PS", __func__);
496 			return -1;
497 		}
498 		while (ps_len--) {
499 			if (*pos == 0x00)
500 				*pos = 0x01;
501 			pos++;
502 		}
503 		break;
504 	default:
505 		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
506 			   "%d", __func__, block_type);
507 		return -1;
508 	}
509 	*pos++ = 0x00;
510 	os_memcpy(pos, in, inlen); /* D */
511 
512 	return 0;
513 }
514 
515 
crypto_rsa_encrypt_pkcs1(int block_type,struct crypto_rsa_key * key,int use_private,const u8 * in,size_t inlen,u8 * out,size_t * outlen)516 static int crypto_rsa_encrypt_pkcs1(int block_type, struct crypto_rsa_key *key,
517 				    int use_private,
518 				    const u8 *in, size_t inlen,
519 				    u8 *out, size_t *outlen)
520 {
521 	size_t modlen;
522 
523 	modlen = crypto_rsa_get_modulus_len(key);
524 
525 	if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
526 					    out, outlen) < 0)
527 		return -1;
528 
529 	return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private);
530 }
531 
532 
crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)533 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
534 					const u8 *in, size_t inlen,
535 					u8 *out, size_t *outlen)
536 {
537 	return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key *) key,
538 					0, in, inlen, out, outlen);
539 }
540 
541 
crypto_private_key_sign_pkcs1(struct crypto_private_key * key,const u8 * in,size_t inlen,u8 * out,size_t * outlen)542 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
543 				  const u8 *in, size_t inlen,
544 				  u8 *out, size_t *outlen)
545 {
546 	return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key *) key,
547 					1, in, inlen, out, outlen);
548 }
549 
550 
crypto_public_key_free(struct crypto_public_key * key)551 void crypto_public_key_free(struct crypto_public_key *key)
552 {
553 	crypto_rsa_free((struct crypto_rsa_key *) key);
554 }
555 
556 
crypto_private_key_free(struct crypto_private_key * key)557 void crypto_private_key_free(struct crypto_private_key *key)
558 {
559 	crypto_rsa_free((struct crypto_rsa_key *) key);
560 }
561 
562 
crypto_public_key_decrypt_pkcs1(struct crypto_public_key * key,const u8 * crypt,size_t crypt_len,u8 * plain,size_t * plain_len)563 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
564 				    const u8 *crypt, size_t crypt_len,
565 				    u8 *plain, size_t *plain_len)
566 {
567 	size_t len;
568 	u8 *pos;
569 
570 	len = *plain_len;
571 	if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len,
572 			       (struct crypto_rsa_key *) key, 0) < 0)
573 		return -1;
574 
575 	/*
576 	 * PKCS #1 v1.5, 8.1:
577 	 *
578 	 * EB = 00 || BT || PS || 00 || D
579 	 * BT = 01
580 	 * PS = k-3-||D|| times FF
581 	 * k = length of modulus in octets
582 	 */
583 
584 	if (len < 3 + 8 + 16 /* min hash len */ ||
585 	    plain[0] != 0x00 || plain[1] != 0x01 || plain[2] != 0xff) {
586 		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
587 			   "structure");
588 		return -1;
589 	}
590 
591 	pos = plain + 3;
592 	while (pos < plain + len && *pos == 0xff)
593 		pos++;
594 	if (pos - plain - 2 < 8) {
595 		/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
596 		wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
597 			   "padding");
598 		return -1;
599 	}
600 
601 	if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
602 		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
603 			   "structure (2)");
604 		return -1;
605 	}
606 	pos++;
607 	len -= pos - plain;
608 
609 	/* Strip PKCS #1 header */
610 	os_memmove(plain, pos, len);
611 	*plain_len = len;
612 
613 	return 0;
614 }
615 
616 
crypto_global_init(void)617 int crypto_global_init(void)
618 {
619 	return 0;
620 }
621 
622 
crypto_global_deinit(void)623 void crypto_global_deinit(void)
624 {
625 }
626 
627 
628 #ifdef EAP_FAST
629 
crypto_mod_exp(const u8 * base,size_t base_len,const u8 * power,size_t power_len,const u8 * modulus,size_t modulus_len,u8 * result,size_t * result_len)630 int crypto_mod_exp(const u8 *base, size_t base_len,
631 		   const u8 *power, size_t power_len,
632 		   const u8 *modulus, size_t modulus_len,
633 		   u8 *result, size_t *result_len)
634 {
635 	struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result;
636 	int ret = 0;
637 
638 	bn_base = bignum_init();
639 	bn_exp = bignum_init();
640 	bn_modulus = bignum_init();
641 	bn_result = bignum_init();
642 
643 	if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
644 	    bn_result == NULL)
645 		goto error;
646 
647 	if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 ||
648 	    bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 ||
649 	    bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0)
650 		goto error;
651 
652 	if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0)
653 		goto error;
654 
655 	ret = bignum_get_unsigned_bin(bn_result, result, result_len);
656 
657 error:
658 	bignum_deinit(bn_base);
659 	bignum_deinit(bn_exp);
660 	bignum_deinit(bn_modulus);
661 	bignum_deinit(bn_result);
662 	return ret;
663 }
664 
665 #endif /* EAP_FAST */
666 
667 
668 #endif /* CONFIG_TLS_INTERNAL */
669 
670 #endif /* EAP_TLS_FUNCS */
671