Home | History | Annotate | Download | only in wpa_supplicant
      1 /*
      2  * WPA Supplicant / Crypto wrapper for internal crypto implementation
      3  * Copyright (c) 2006, Jouni Malinen <j (at) 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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    551 void crypto_public_key_free(struct crypto_public_key *key)
    552 {
    553 	crypto_rsa_free((struct crypto_rsa_key *) key);
    554 }
    555 
    556 
    557 void crypto_private_key_free(struct crypto_private_key *key)
    558 {
    559 	crypto_rsa_free((struct crypto_rsa_key *) key);
    560 }
    561 
    562 
    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 
    617 int crypto_global_init(void)
    618 {
    619 	return 0;
    620 }
    621 
    622 
    623 void crypto_global_deinit(void)
    624 {
    625 }
    626 
    627 
    628 #ifdef EAP_FAST
    629 
    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