crypto_internal.c revision 209158
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 CONFIG_CRYPTO_INTERNAL
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
438#ifdef EAP_TLS_FUNCS
439static struct crypto_private_key *
440crypto_pkcs8_key_import(const u8 *buf, size_t len)
441{
442	struct asn1_hdr hdr;
443	const u8 *pos, *end;
444	struct bignum *zero;
445	struct asn1_oid oid;
446	char obuf[80];
447
448	/* PKCS #8, Chapter 6 */
449
450	/* PrivateKeyInfo ::= SEQUENCE */
451	if (asn1_get_next(buf, len, &hdr) < 0 ||
452	    hdr.class != ASN1_CLASS_UNIVERSAL ||
453	    hdr.tag != ASN1_TAG_SEQUENCE) {
454		wpa_printf(MSG_DEBUG, "PKCS #8: Does not start with PKCS #8 "
455			   "header (SEQUENCE); assume PKCS #8 not used");
456		return NULL;
457	}
458	pos = hdr.payload;
459	end = pos + hdr.length;
460
461	/* version Version (Version ::= INTEGER) */
462	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
463	    hdr.class != ASN1_CLASS_UNIVERSAL || hdr.tag != ASN1_TAG_INTEGER) {
464		wpa_printf(MSG_DEBUG, "PKCS #8: Expected INTEGER - found "
465			   "class %d tag 0x%x; assume PKCS #8 not used",
466			   hdr.class, hdr.tag);
467		return NULL;
468	}
469
470	zero = bignum_init();
471	if (zero == NULL)
472		return NULL;
473
474	if (bignum_set_unsigned_bin(zero, hdr.payload, hdr.length) < 0) {
475		wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse INTEGER");
476		bignum_deinit(zero);
477		return NULL;
478	}
479	pos = hdr.payload + hdr.length;
480
481	if (bignum_cmp_d(zero, 0) != 0) {
482		wpa_printf(MSG_DEBUG, "PKCS #8: Expected zero INTEGER in the "
483			   "beginning of private key; not found; assume "
484			   "PKCS #8 not used");
485		bignum_deinit(zero);
486		return NULL;
487	}
488	bignum_deinit(zero);
489
490	/* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier
491	 * (PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier) */
492	if (asn1_get_next(pos, len, &hdr) < 0 ||
493	    hdr.class != ASN1_CLASS_UNIVERSAL ||
494	    hdr.tag != ASN1_TAG_SEQUENCE) {
495		wpa_printf(MSG_DEBUG, "PKCS #8: Expected SEQUENCE "
496			   "(AlgorithmIdentifier) - found class %d tag 0x%x; "
497			   "assume PKCS #8 not used",
498			   hdr.class, hdr.tag);
499		return NULL;
500	}
501
502	if (asn1_get_oid(hdr.payload, hdr.length, &oid, &pos)) {
503		wpa_printf(MSG_DEBUG, "PKCS #8: Failed to parse OID "
504			   "(algorithm); assume PKCS #8 not used");
505		return NULL;
506	}
507
508	asn1_oid_to_str(&oid, obuf, sizeof(obuf));
509	wpa_printf(MSG_DEBUG, "PKCS #8: algorithm=%s", obuf);
510
511	if (oid.len != 7 ||
512	    oid.oid[0] != 1 /* iso */ ||
513	    oid.oid[1] != 2 /* member-body */ ||
514	    oid.oid[2] != 840 /* us */ ||
515	    oid.oid[3] != 113549 /* rsadsi */ ||
516	    oid.oid[4] != 1 /* pkcs */ ||
517	    oid.oid[5] != 1 /* pkcs-1 */ ||
518	    oid.oid[6] != 1 /* rsaEncryption */) {
519		wpa_printf(MSG_DEBUG, "PKCS #8: Unsupported private key "
520			   "algorithm %s", obuf);
521		return NULL;
522	}
523
524	pos = hdr.payload + hdr.length;
525
526	/* privateKey PrivateKey (PrivateKey ::= OCTET STRING) */
527	if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
528	    hdr.class != ASN1_CLASS_UNIVERSAL ||
529	    hdr.tag != ASN1_TAG_OCTETSTRING) {
530		wpa_printf(MSG_DEBUG, "PKCS #8: Expected OCTETSTRING "
531			   "(privateKey) - found class %d tag 0x%x",
532			   hdr.class, hdr.tag);
533		return NULL;
534	}
535	wpa_printf(MSG_DEBUG, "PKCS #8: Try to parse RSAPrivateKey");
536
537	return (struct crypto_private_key *)
538		crypto_rsa_import_private_key(hdr.payload, hdr.length);
539}
540#endif /* EAP_TLS_FUNCS */
541
542
543struct crypto_private_key * crypto_private_key_import(const u8 *key,
544						      size_t len)
545{
546	struct crypto_private_key *res;
547
548	/* First, check for possible PKCS #8 encoding */
549	res = crypto_pkcs8_key_import(key, len);
550	if (res)
551		return res;
552
553	/* Not PKCS#8, so try to import PKCS #1 encoded RSA private key */
554	wpa_printf(MSG_DEBUG, "Trying to parse PKCS #1 encoded RSA private "
555		   "key");
556	return (struct crypto_private_key *)
557		crypto_rsa_import_private_key(key, len);
558}
559
560
561struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
562						       size_t len)
563{
564	/* No X.509 support in crypto_internal.c */
565	return NULL;
566}
567
568
569static int pkcs1_generate_encryption_block(u8 block_type, size_t modlen,
570					   const u8 *in, size_t inlen,
571					   u8 *out, size_t *outlen)
572{
573	size_t ps_len;
574	u8 *pos;
575
576	/*
577	 * PKCS #1 v1.5, 8.1:
578	 *
579	 * EB = 00 || BT || PS || 00 || D
580	 * BT = 00 or 01 for private-key operation; 02 for public-key operation
581	 * PS = k-3-||D||; at least eight octets
582	 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
583	 * k = length of modulus in octets (modlen)
584	 */
585
586	if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) {
587		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer "
588			   "lengths (modlen=%lu outlen=%lu inlen=%lu)",
589			   __func__, (unsigned long) modlen,
590			   (unsigned long) *outlen,
591			   (unsigned long) inlen);
592		return -1;
593	}
594
595	pos = out;
596	*pos++ = 0x00;
597	*pos++ = block_type; /* BT */
598	ps_len = modlen - inlen - 3;
599	switch (block_type) {
600	case 0:
601		os_memset(pos, 0x00, ps_len);
602		pos += ps_len;
603		break;
604	case 1:
605		os_memset(pos, 0xff, ps_len);
606		pos += ps_len;
607		break;
608	case 2:
609		if (os_get_random(pos, ps_len) < 0) {
610			wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get "
611				   "random data for PS", __func__);
612			return -1;
613		}
614		while (ps_len--) {
615			if (*pos == 0x00)
616				*pos = 0x01;
617			pos++;
618		}
619		break;
620	default:
621		wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type "
622			   "%d", __func__, block_type);
623		return -1;
624	}
625	*pos++ = 0x00;
626	os_memcpy(pos, in, inlen); /* D */
627
628	return 0;
629}
630
631
632static int crypto_rsa_encrypt_pkcs1(int block_type, struct crypto_rsa_key *key,
633				    int use_private,
634				    const u8 *in, size_t inlen,
635				    u8 *out, size_t *outlen)
636{
637	size_t modlen;
638
639	modlen = crypto_rsa_get_modulus_len(key);
640
641	if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen,
642					    out, outlen) < 0)
643		return -1;
644
645	return crypto_rsa_exptmod(out, modlen, out, outlen, key, use_private);
646}
647
648
649int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
650					const u8 *in, size_t inlen,
651					u8 *out, size_t *outlen)
652{
653	return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key *) key,
654					0, in, inlen, out, outlen);
655}
656
657
658int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
659					 const u8 *in, size_t inlen,
660					 u8 *out, size_t *outlen)
661{
662	struct crypto_rsa_key *rkey = (struct crypto_rsa_key *) key;
663	int res;
664	u8 *pos, *end;
665
666	res = crypto_rsa_exptmod(in, inlen, out, outlen, rkey, 1);
667	if (res)
668		return res;
669
670	if (*outlen < 2 || out[0] != 0 || out[1] != 2)
671		return -1;
672
673	/* Skip PS (pseudorandom non-zero octets) */
674	pos = out + 2;
675	end = out + *outlen;
676	while (*pos && pos < end)
677		pos++;
678	if (pos == end)
679		return -1;
680	pos++;
681
682	*outlen -= pos - out;
683
684	/* Strip PKCS #1 header */
685	os_memmove(out, pos, *outlen);
686
687	return 0;
688}
689
690
691int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
692				  const u8 *in, size_t inlen,
693				  u8 *out, size_t *outlen)
694{
695	return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key *) key,
696					1, in, inlen, out, outlen);
697}
698
699
700void crypto_public_key_free(struct crypto_public_key *key)
701{
702	crypto_rsa_free((struct crypto_rsa_key *) key);
703}
704
705
706void crypto_private_key_free(struct crypto_private_key *key)
707{
708	crypto_rsa_free((struct crypto_rsa_key *) key);
709}
710
711
712int crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key,
713				    const u8 *crypt, size_t crypt_len,
714				    u8 *plain, size_t *plain_len)
715{
716	size_t len;
717	u8 *pos;
718
719	len = *plain_len;
720	if (crypto_rsa_exptmod(crypt, crypt_len, plain, &len,
721			       (struct crypto_rsa_key *) key, 0) < 0)
722		return -1;
723
724	/*
725	 * PKCS #1 v1.5, 8.1:
726	 *
727	 * EB = 00 || BT || PS || 00 || D
728	 * BT = 00 or 01
729	 * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
730	 * k = length of modulus in octets
731	 */
732
733	if (len < 3 + 8 + 16 /* min hash len */ ||
734	    plain[0] != 0x00 || (plain[1] != 0x00 && plain[1] != 0x01)) {
735		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
736			   "structure");
737		return -1;
738	}
739
740	pos = plain + 3;
741	if (plain[1] == 0x00) {
742		/* BT = 00 */
743		if (plain[2] != 0x00) {
744			wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
745				   "PS (BT=00)");
746			return -1;
747		}
748		while (pos + 1 < plain + len && *pos == 0x00 && pos[1] == 0x00)
749			pos++;
750	} else {
751		/* BT = 01 */
752		if (plain[2] != 0xff) {
753			wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
754				   "PS (BT=01)");
755			return -1;
756		}
757		while (pos < plain + len && *pos == 0xff)
758			pos++;
759	}
760
761	if (pos - plain - 2 < 8) {
762		/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
763		wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
764			   "padding");
765		return -1;
766	}
767
768	if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) {
769		wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
770			   "structure (2)");
771		return -1;
772	}
773	pos++;
774	len -= pos - plain;
775
776	/* Strip PKCS #1 header */
777	os_memmove(plain, pos, len);
778	*plain_len = len;
779
780	return 0;
781}
782
783
784int crypto_global_init(void)
785{
786	return 0;
787}
788
789
790void crypto_global_deinit(void)
791{
792}
793#endif /* CONFIG_TLS_INTERNAL */
794
795
796#if defined(EAP_FAST) || defined(CONFIG_WPS)
797
798int crypto_mod_exp(const u8 *base, size_t base_len,
799		   const u8 *power, size_t power_len,
800		   const u8 *modulus, size_t modulus_len,
801		   u8 *result, size_t *result_len)
802{
803	struct bignum *bn_base, *bn_exp, *bn_modulus, *bn_result;
804	int ret = -1;
805
806	bn_base = bignum_init();
807	bn_exp = bignum_init();
808	bn_modulus = bignum_init();
809	bn_result = bignum_init();
810
811	if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
812	    bn_result == NULL)
813		goto error;
814
815	if (bignum_set_unsigned_bin(bn_base, base, base_len) < 0 ||
816	    bignum_set_unsigned_bin(bn_exp, power, power_len) < 0 ||
817	    bignum_set_unsigned_bin(bn_modulus, modulus, modulus_len) < 0)
818		goto error;
819
820	if (bignum_exptmod(bn_base, bn_exp, bn_modulus, bn_result) < 0)
821		goto error;
822
823	ret = bignum_get_unsigned_bin(bn_result, result, result_len);
824
825error:
826	bignum_deinit(bn_base);
827	bignum_deinit(bn_exp);
828	bignum_deinit(bn_modulus);
829	bignum_deinit(bn_result);
830	return ret;
831}
832
833#endif /* EAP_FAST || CONFIG_WPS */
834
835
836#endif /* CONFIG_CRYPTO_INTERNAL */
837