crypto_internal.c revision 189261
1/*
2 * WPA Supplicant / Crypto wrapper for internal crypto implementation
3 * Copyright (c) 2006-2007, 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 "tls/rsa.h"
24#include "tls/bignum.h"
25#include "tls/asn1.h"
26
27
28#ifdef EAP_TLS_FUNCS
29
30#ifdef CONFIG_TLS_INTERNAL
31
32/* from des.c */
33struct des3_key_s {
34	u32 ek[3][32];
35	u32 dk[3][32];
36};
37
38void des3_key_setup(const u8 *key, struct des3_key_s *dkey);
39void des3_encrypt(const u8 *plain, const struct des3_key_s *key, u8 *crypt);
40void des3_decrypt(const u8 *crypt, const struct des3_key_s *key, u8 *plain);
41
42
43struct MD5Context {
44	u32 buf[4];
45	u32 bits[2];
46	u8 in[64];
47};
48
49struct SHA1Context {
50	u32 state[5];
51	u32 count[2];
52	unsigned char buffer[64];
53};
54
55
56struct crypto_hash {
57	enum crypto_hash_alg alg;
58	union {
59		struct MD5Context md5;
60		struct SHA1Context sha1;
61	} u;
62	u8 key[64];
63	size_t key_len;
64};
65
66
67struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
68				      size_t key_len)
69{
70	struct crypto_hash *ctx;
71	u8 k_pad[64];
72	u8 tk[20];
73	size_t i;
74
75	ctx = os_zalloc(sizeof(*ctx));
76	if (ctx == NULL)
77		return NULL;
78
79	ctx->alg = alg;
80
81	switch (alg) {
82	case CRYPTO_HASH_ALG_MD5:
83		MD5Init(&ctx->u.md5);
84		break;
85	case CRYPTO_HASH_ALG_SHA1:
86		SHA1Init(&ctx->u.sha1);
87		break;
88	case CRYPTO_HASH_ALG_HMAC_MD5:
89		if (key_len > sizeof(k_pad)) {
90			MD5Init(&ctx->u.md5);
91			MD5Update(&ctx->u.md5, key, key_len);
92			MD5Final(tk, &ctx->u.md5);
93			key = tk;
94			key_len = 16;
95		}
96		os_memcpy(ctx->key, key, key_len);
97		ctx->key_len = key_len;
98
99		os_memcpy(k_pad, key, key_len);
100		os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
101		for (i = 0; i < sizeof(k_pad); i++)
102			k_pad[i] ^= 0x36;
103		MD5Init(&ctx->u.md5);
104		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
105		break;
106	case CRYPTO_HASH_ALG_HMAC_SHA1:
107		if (key_len > sizeof(k_pad)) {
108			SHA1Init(&ctx->u.sha1);
109			SHA1Update(&ctx->u.sha1, key, key_len);
110			SHA1Final(tk, &ctx->u.sha1);
111			key = tk;
112			key_len = 20;
113		}
114		os_memcpy(ctx->key, key, key_len);
115		ctx->key_len = key_len;
116
117		os_memcpy(k_pad, key, key_len);
118		os_memset(k_pad + key_len, 0, sizeof(k_pad) - key_len);
119		for (i = 0; i < sizeof(k_pad); i++)
120			k_pad[i] ^= 0x36;
121		SHA1Init(&ctx->u.sha1);
122		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
123		break;
124	default:
125		os_free(ctx);
126		return NULL;
127	}
128
129	return ctx;
130}
131
132
133void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
134{
135	if (ctx == NULL)
136		return;
137
138	switch (ctx->alg) {
139	case CRYPTO_HASH_ALG_MD5:
140	case CRYPTO_HASH_ALG_HMAC_MD5:
141		MD5Update(&ctx->u.md5, data, len);
142		break;
143	case CRYPTO_HASH_ALG_SHA1:
144	case CRYPTO_HASH_ALG_HMAC_SHA1:
145		SHA1Update(&ctx->u.sha1, data, len);
146		break;
147	}
148}
149
150
151int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
152{
153	u8 k_pad[64];
154	size_t i;
155
156	if (ctx == NULL)
157		return -2;
158
159	if (mac == NULL || len == NULL) {
160		os_free(ctx);
161		return 0;
162	}
163
164	switch (ctx->alg) {
165	case CRYPTO_HASH_ALG_MD5:
166		if (*len < 16) {
167			*len = 16;
168			os_free(ctx);
169			return -1;
170		}
171		*len = 16;
172		MD5Final(mac, &ctx->u.md5);
173		break;
174	case CRYPTO_HASH_ALG_SHA1:
175		if (*len < 20) {
176			*len = 20;
177			os_free(ctx);
178			return -1;
179		}
180		*len = 20;
181		SHA1Final(mac, &ctx->u.sha1);
182		break;
183	case CRYPTO_HASH_ALG_HMAC_MD5:
184		if (*len < 16) {
185			*len = 16;
186			os_free(ctx);
187			return -1;
188		}
189		*len = 16;
190
191		MD5Final(mac, &ctx->u.md5);
192
193		os_memcpy(k_pad, ctx->key, ctx->key_len);
194		os_memset(k_pad + ctx->key_len, 0,
195			  sizeof(k_pad) - ctx->key_len);
196		for (i = 0; i < sizeof(k_pad); i++)
197			k_pad[i] ^= 0x5c;
198		MD5Init(&ctx->u.md5);
199		MD5Update(&ctx->u.md5, k_pad, sizeof(k_pad));
200		MD5Update(&ctx->u.md5, mac, 16);
201		MD5Final(mac, &ctx->u.md5);
202		break;
203	case CRYPTO_HASH_ALG_HMAC_SHA1:
204		if (*len < 20) {
205			*len = 20;
206			os_free(ctx);
207			return -1;
208		}
209		*len = 20;
210
211		SHA1Final(mac, &ctx->u.sha1);
212
213		os_memcpy(k_pad, ctx->key, ctx->key_len);
214		os_memset(k_pad + ctx->key_len, 0,
215			  sizeof(k_pad) - ctx->key_len);
216		for (i = 0; i < sizeof(k_pad); i++)
217			k_pad[i] ^= 0x5c;
218		SHA1Init(&ctx->u.sha1);
219		SHA1Update(&ctx->u.sha1, k_pad, sizeof(k_pad));
220		SHA1Update(&ctx->u.sha1, mac, 20);
221		SHA1Final(mac, &ctx->u.sha1);
222		break;
223	}
224
225	os_free(ctx);
226
227	return 0;
228}
229
230
231struct crypto_cipher {
232	enum crypto_cipher_alg alg;
233	union {
234		struct {
235			size_t used_bytes;
236			u8 key[16];
237			size_t keylen;
238		} rc4;
239		struct {
240			u8 cbc[32];
241			size_t block_size;
242			void *ctx_enc;
243			void *ctx_dec;
244		} aes;
245		struct {
246			struct des3_key_s key;
247			u8 cbc[8];
248		} des3;
249	} u;
250};
251
252
253struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
254					  const u8 *iv, const u8 *key,
255					  size_t key_len)
256{
257	struct crypto_cipher *ctx;
258
259	ctx = os_zalloc(sizeof(*ctx));
260	if (ctx == NULL)
261		return NULL;
262
263	ctx->alg = alg;
264
265	switch (alg) {
266	case CRYPTO_CIPHER_ALG_RC4:
267		if (key_len > sizeof(ctx->u.rc4.key)) {
268			os_free(ctx);
269			return NULL;
270		}
271		ctx->u.rc4.keylen = key_len;
272		os_memcpy(ctx->u.rc4.key, key, key_len);
273		break;
274	case CRYPTO_CIPHER_ALG_AES:
275		if (key_len > sizeof(ctx->u.aes.cbc)) {
276			os_free(ctx);
277			return NULL;
278		}
279		ctx->u.aes.ctx_enc = aes_encrypt_init(key, key_len);
280		if (ctx->u.aes.ctx_enc == NULL) {
281			os_free(ctx);
282			return NULL;
283		}
284		ctx->u.aes.ctx_dec = aes_decrypt_init(key, key_len);
285		if (ctx->u.aes.ctx_dec == NULL) {
286			aes_encrypt_deinit(ctx->u.aes.ctx_enc);
287			os_free(ctx);
288			return NULL;
289		}
290		ctx->u.aes.block_size = key_len;
291		os_memcpy(ctx->u.aes.cbc, iv, ctx->u.aes.block_size);
292		break;
293	case CRYPTO_CIPHER_ALG_3DES:
294		if (key_len != 24) {
295			os_free(ctx);
296			return NULL;
297		}
298		des3_key_setup(key, &ctx->u.des3.key);
299		os_memcpy(ctx->u.des3.cbc, iv, 8);
300		break;
301	default:
302		os_free(ctx);
303		return NULL;
304	}
305
306	return ctx;
307}
308
309
310int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
311			  u8 *crypt, size_t len)
312{
313	size_t i, j, blocks;
314
315	switch (ctx->alg) {
316	case CRYPTO_CIPHER_ALG_RC4:
317		if (plain != crypt)
318			os_memcpy(crypt, plain, len);
319		rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
320			 ctx->u.rc4.used_bytes, crypt, len);
321		ctx->u.rc4.used_bytes += len;
322		break;
323	case CRYPTO_CIPHER_ALG_AES:
324		if (len % ctx->u.aes.block_size)
325			return -1;
326		blocks = len / ctx->u.aes.block_size;
327		for (i = 0; i < blocks; i++) {
328			for (j = 0; j < ctx->u.aes.block_size; j++)
329				ctx->u.aes.cbc[j] ^= plain[j];
330			aes_encrypt(ctx->u.aes.ctx_enc, ctx->u.aes.cbc,
331				    ctx->u.aes.cbc);
332			os_memcpy(crypt, ctx->u.aes.cbc,
333				  ctx->u.aes.block_size);
334			plain += ctx->u.aes.block_size;
335			crypt += ctx->u.aes.block_size;
336		}
337		break;
338	case CRYPTO_CIPHER_ALG_3DES:
339		if (len % 8)
340			return -1;
341		blocks = len / 8;
342		for (i = 0; i < blocks; i++) {
343			for (j = 0; j < 8; j++)
344				ctx->u.des3.cbc[j] ^= plain[j];
345			des3_encrypt(ctx->u.des3.cbc, &ctx->u.des3.key,
346				     ctx->u.des3.cbc);
347			os_memcpy(crypt, ctx->u.des3.cbc, 8);
348			plain += 8;
349			crypt += 8;
350		}
351		break;
352	default:
353		return -1;
354	}
355
356	return 0;
357}
358
359
360int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
361			  u8 *plain, size_t len)
362{
363	size_t i, j, blocks;
364	u8 tmp[32];
365
366	switch (ctx->alg) {
367	case CRYPTO_CIPHER_ALG_RC4:
368		if (plain != crypt)
369			os_memcpy(plain, crypt, len);
370		rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen,
371			 ctx->u.rc4.used_bytes, plain, len);
372		ctx->u.rc4.used_bytes += len;
373		break;
374	case CRYPTO_CIPHER_ALG_AES:
375		if (len % ctx->u.aes.block_size)
376			return -1;
377		blocks = len / ctx->u.aes.block_size;
378		for (i = 0; i < blocks; i++) {
379			os_memcpy(tmp, crypt, ctx->u.aes.block_size);
380			aes_decrypt(ctx->u.aes.ctx_dec, crypt, plain);
381			for (j = 0; j < ctx->u.aes.block_size; j++)
382				plain[j] ^= ctx->u.aes.cbc[j];
383			os_memcpy(ctx->u.aes.cbc, tmp, ctx->u.aes.block_size);
384			plain += ctx->u.aes.block_size;
385			crypt += ctx->u.aes.block_size;
386		}
387		break;
388	case CRYPTO_CIPHER_ALG_3DES:
389		if (len % 8)
390			return -1;
391		blocks = len / 8;
392		for (i = 0; i < blocks; i++) {
393			os_memcpy(tmp, crypt, 8);
394			des3_decrypt(crypt, &ctx->u.des3.key, plain);
395			for (j = 0; j < 8; j++)
396				plain[j] ^= ctx->u.des3.cbc[j];
397			os_memcpy(ctx->u.des3.cbc, tmp, 8);
398			plain += 8;
399			crypt += 8;
400		}
401		break;
402	default:
403		return -1;
404	}
405
406	return 0;
407}
408
409
410void crypto_cipher_deinit(struct crypto_cipher *ctx)
411{
412	switch (ctx->alg) {
413	case CRYPTO_CIPHER_ALG_AES:
414		aes_encrypt_deinit(ctx->u.aes.ctx_enc);
415		aes_decrypt_deinit(ctx->u.aes.ctx_dec);
416		break;
417	case CRYPTO_CIPHER_ALG_3DES:
418		break;
419	default:
420		break;
421	}
422	os_free(ctx);
423}
424
425
426/* Dummy structures; these are just typecast to struct crypto_rsa_key */
427struct crypto_public_key;
428struct crypto_private_key;
429
430
431struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
432{
433	return (struct crypto_public_key *)
434		crypto_rsa_import_public_key(key, len);
435}
436
437
438static struct crypto_private_key *
439crypto_pkcs8_key_import(const u8 *buf, size_t len)
440{
441	struct asn1_hdr hdr;
442	const u8 *pos, *end;
443	struct bignum *zero;
444	struct asn1_oid oid;
445	char obuf[80];
446
447	/* PKCS #8, Chapter 6 */
448
449	/* PrivateKeyInfo ::= SEQUENCE */
450	if (asn1_get_next(buf, len, &hdr) < 0 ||
451	    hdr.class != ASN1_CLASS_UNIVERSAL ||
452	    hdr.tag != ASN1_TAG_SEQUENCE) {
453		wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
454			   "header (SEQUENCE); assume PKCS #8 not used");
455		return NULL;
456	}
457	pos = hdr.payload;
458	end = pos + hdr.length;
459
460	/* version Version (Version ::= INTEGER) */
461	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
462	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
463		wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
464			   "class %d tag 0x%x; assume PKCS #8 not used",
465			   hdr.class, hdr.tag);
466		return NULL;
467	}
468
469	zero = bignum_init();
470	if (zero == NULL)
471		return NULL;
472
473	if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
474		wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
475		bignum_deinit(zero);
476		return NULL;
477	}
478	pos = hdr.payload + hdr.length;
479
480	if (bignum_cmp_d(zero, 0) != 0) {
481		wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
482			   "beginning of private key; not found; assume "
483			   "PKCS #8 not used");
484		bignum_deinit(zero);
485		return NULL;
486	}
487	bignum_deinit(zero);
488
489	/* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
490	 * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
491	if (asn1_get_next(pos, len, &hdr) < 0 ||
492	    hdr.class != ASN1_CLASS_UNIVERSAL ||
493	    hdr.tag != ASN1_TAG_SEQUENCE) {
494		wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
495			   "(AlgorithmIdentifier) - found class %d tag 0x%x; "
496			   "assume PKCS #8 not used",
497			   hdr.class, hdr.tag);
498		return NULL;
499	}
500
501	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
502		wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
503			   "(algorithm); assume PKCS #8 not used");
504		return NULL;
505	}
506
507	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
508	wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
509
510	if (oid.len != 7 ||
511	    oid.oid[0] != 1 /* iso */ ||
512	    oid.oid[1] != 2 /* member-body */ ||
513	    oid.oid[2] != 840 /* us */ ||
514	    oid.oid[3] != 113549 /* rsadsi */ ||
515	    oid.oid[4] != 1 /* pkcs */ ||
516	    oid.oid[5] != 1 /* pkcs-1 */ ||
517	    oid.oid[6] != 1 /* rsaEncryption */) {
518		wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
519			   "algorithm %s", obuf);
520		return NULL;
521	}
522
523	pos = hdr.payload + hdr.length;
524
525	/* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
526	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
527	    hdr.class != ASN1_CLASS_UNIVERSAL ||
528	    hdr.tag != ASN1_TAG_OCTETSTRING) {
529		wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
530			   "(privateKey) - found class %d tag 0x%x",
531			   hdr.class, hdr.tag);
532		return NULL;
533	}
534	wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
535
536	return (struct crypto_private_key *)
537		crypto_rsa_import_private_key(hdr.payload, hdr.length);
538}
539
540
541struct crypto_private_key * crypto_private_key_import(const u8 *key,
542						      size_t len)
543{
544	struct crypto_private_key *res;
545
546	/* First, check for possible PKCS #8 encoding */
547	res = crypto_pkcs8_key_import(key, len);
548	if (res)
549		return res;
550
551	/* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */
552	wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private "
553		   "key");
554	return (struct crypto_private_key *)
555		crypto_rsa_import_private_key(key, len);
556}
557
558
559struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
560						       size_t len)
561{
562	/* No X.509 support in crypto_internal.c */
563	return NULL;
564}
565
566
567static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
568					   const u8 *in, size_t inlen,
569					   u8 *out, size_t *outlen)
570{
571	size_t ps_len;
572	u8 *pos;
573
574	/*
575	 * PKCS #1 v1.5, 8.1:
576	 *
577	 * EB = 00 || BT || PS || 00 || D
578	 * BT = 00 or 01 for private-key operation; 02 for public-key operation
579	 * PS = k-3-||D||; at least eight octets
580	 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
581	 * k = length of modulus in octets (modlen)
582	 */
583
584	if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
585		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
586			   "lengths (modlen=%lu outlen=%lu inlen=%lu)",
587			   __func__, (unsigned long) modlen,
588			   (unsigned long) *outlen,
589			   (unsigned long) inlen);
590		return -1;
591	}
592
593	pos = out;
594	*pos++ = 0x00;
595	*pos++ = block_type; /* BT */
596	ps_len = modlen - inlen - 3;
597	switch (block_type) {
598	case 0:
599		os_memset(pos, 0x00, ps_len);
600		pos += ps_len;
601		break;
602	case 1:
603		os_memset(pos, 0xff, ps_len);
604		pos += ps_len;
605		break;
606	case 2:
607		if (os_get_random(pos, ps_len) < 0) {
608			wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
609				   "random data for PS", __func__);
610			return -1;
611		}
612		while (ps_len--) {
613			if (*pos == 0x00)
614				*pos = 0x01;
615			pos++;
616		}
617		break;
618	default:
619		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
620			   "%d", __func__, block_type);
621		return -1;
622	}
623	*pos++ = 0x00;
624	os_memcpy(pos, in, inlen); /* D */
625
626	return 0;
627}
628
629
630static int crypto_rsa_encrypt_pkcs1(int block_type, struct crypto_rsa_key *key,
631				    int use_private,
632				    const u8 *in, size_t inlen,
633				    u8 *out, size_t *outlen)
634{
635	size_t modlen;
636
637	modlen = crypto_rsa_get_modulus_len(key);
638
639	if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
640					    out, outlen) < 0)
641		return -1;
642
643	return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private);
644}
645
646
647int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
648					const u8 *in, size_t inlen,
649					u8 *out, size_t *outlen)
650{
651	return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key *) key,
652					0, in, inlen, out, outlen);
653}
654
655
656int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
657					 const u8 *in, size_t inlen,
658					 u8 *out, size_t *outlen)
659{
660	struct crypto_rsa_key *rkey = (struct crypto_rsa_key *) key;
661	int res;
662	u8 *pos, *end;
663
664	res = crypto_rsa_exptmod(in, inlen, out, outlen, rkey, 1);
665	if (res)
666		return res;
667
668	if (*outlen < 2 || out[0] != 0 || out[1] != 2)
669		return -1;
670
671	/* Skip PS (pseudorandom non-zero octets) */
672	pos = out + 2;
673	end = out + *outlen;
674	while (*pos && pos < end)
675		pos++;
676	if (pos == end)
677		return -1;
678	pos++;
679
680	*outlen -= pos - out;
681
682	/* Strip PKCS #1 header */
683	os_memmove(out, pos, *outlen);
684
685	return 0;
686}
687
688
689int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
690				  const u8 *in, size_t inlen,
691				  u8 *out, size_t *outlen)
692{
693	return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key *) key,
694					1, in, inlen, out, outlen);
695}
696
697
698void crypto_public_key_free(struct crypto_public_key *key)
699{
700	crypto_rsa_free((struct crypto_rsa_key *) key);
701}
702
703
704void crypto_private_key_free(struct crypto_private_key *key)
705{
706	crypto_rsa_free((struct crypto_rsa_key *) key);
707}
708
709
710int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
711				    const u8 *crypt, size_t crypt_len,
712				    u8 *plain, size_t *plain_len)
713{
714	size_t len;
715	u8 *pos;
716
717	len = *plain_len;
718	if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len,
719			       (struct crypto_rsa_key *) key, 0) < 0)
720		return -1;
721
722	/*
723	 * PKCS #1 v1.5, 8.1:
724	 *
725	 * EB = 00 || BT || PS || 00 || D
726	 * BT = 00 or 01
727	 * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
728	 * k = length of modulus in octets
729	 */
730
731	if (len < 3 + 8 + 16 /* min hash len */ ||
732	    plain[0] != 0x00 || (plain[1] != 0x00 && plain[1] != 0x01)) {
733		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
734			   "structure");
735		return -1;
736	}
737
738	pos = plain + 3;
739	if (plain[1] == 0x00) {
740		/* BT = 00 */
741		if (plain[2] != 0x00) {
742			wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
743				   "PS (BT=00)");
744			return -1;
745		}
746		while (pos + 1 < plain + len && *pos == 0x00 && pos[1] == 0x00)
747			pos++;
748	} else {
749		/* BT = 01 */
750		if (plain[2] != 0xff) {
751			wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
752				   "PS (BT=01)");
753			return -1;
754		}
755		while (pos < plain + len && *pos == 0xff)
756			pos++;
757	}
758
759	if (pos - plain - 2 < 8) {
760		/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
761		wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
762			   "padding");
763		return -1;
764	}
765
766	if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
767		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
768			   "structure (2)");
769		return -1;
770	}
771	pos++;
772	len -= pos - plain;
773
774	/* Strip PKCS #1 header */
775	os_memmove(plain, pos, len);
776	*plain_len = len;
777
778	return 0;
779}
780
781
782int crypto_global_init(void)
783{
784	return 0;
785}
786
787
788void crypto_global_deinit(void)
789{
790}
791
792
793#if defined(EAP_FAST) || defined(CONFIG_WPS)
794
795int crypto_mod_exp(const u8 *base, size_t base_len,
796		   const u8 *power, size_t power_len,
797		   const u8 *modulus, size_t modulus_len,
798		   u8 *result, size_t *result_len)
799{
800	struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result;
801	int ret = -1;
802
803	bn_base = bignum_init();
804	bn_exp = bignum_init();
805	bn_modulus = bignum_init();
806	bn_result = bignum_init();
807
808	if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
809	    bn_result == NULL)
810		goto error;
811
812	if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 ||
813	    bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 ||
814	    bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0)
815		goto error;
816
817	if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0)
818		goto error;
819
820	ret = bignum_get_unsigned_bin(bn_result, result, result_len);
821
822error:
823	bignum_deinit(bn_base);
824	bignum_deinit(bn_exp);
825	bignum_deinit(bn_modulus);
826	bignum_deinit(bn_result);
827	return ret;
828}
829
830#endif /* EAP_FAST || CONFIG_WPS */
831
832
833#endif /* CONFIG_TLS_INTERNAL */
834
835#endif /* EAP_TLS_FUNCS */
836