2 * WPA Supplicant / Crypto wrapper for LibTomCrypt (for internal TLSv1)
3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
23 #define mp_init_multi ltc_init_multi
24 #define mp_clear_multi ltc_deinit_multi
25 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
26 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
27 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
28 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
32 void md4_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
38 for (i
= 0; i
< num_elem
; i
++)
39 md4_process(&md
, addr
[i
], len
[i
]);
44 void des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
46 u8 pkey
[8], next
, tmp
;
50 /* Add parity bits to the key */
52 for (i
= 0; i
< 7; i
++) {
54 pkey
[i
] = (tmp
>> i
) | next
| 1;
55 next
= tmp
<< (7 - i
);
59 des_setup(pkey
, 8, 0, &skey
);
60 des_ecb_encrypt(clear
, cypher
, &skey
);
66 void md5_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
72 for (i
= 0; i
< num_elem
; i
++)
73 md5_process(&md
, addr
[i
], len
[i
]);
78 void sha1_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
84 for (i
= 0; i
< num_elem
; i
++)
85 sha1_process(&md
, addr
[i
], len
[i
]);
90 void * aes_encrypt_init(const u8
*key
, size_t len
)
93 skey
= os_malloc(sizeof(*skey
));
96 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
104 void aes_encrypt(void *ctx
, const u8
*plain
, u8
*crypt
)
106 symmetric_key
*skey
= ctx
;
107 aes_ecb_encrypt(plain
, crypt
, skey
);
111 void aes_encrypt_deinit(void *ctx
)
113 symmetric_key
*skey
= ctx
;
119 void * aes_decrypt_init(const u8
*key
, size_t len
)
122 skey
= os_malloc(sizeof(*skey
));
125 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
133 void aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
135 symmetric_key
*skey
= ctx
;
136 aes_ecb_encrypt(plain
, (u8
*) crypt
, skey
);
140 void aes_decrypt_deinit(void *ctx
)
142 symmetric_key
*skey
= ctx
;
148 #ifdef CONFIG_TLS_INTERNAL
151 enum crypto_hash_alg alg
;
160 struct crypto_hash
* crypto_hash_init(enum crypto_hash_alg alg
, const u8
*key
,
163 struct crypto_hash
*ctx
;
165 ctx
= os_zalloc(sizeof(*ctx
));
172 case CRYPTO_HASH_ALG_MD5
:
173 if (md5_init(&ctx
->u
.md
) != CRYPT_OK
)
176 case CRYPTO_HASH_ALG_SHA1
:
177 if (sha1_init(&ctx
->u
.md
) != CRYPT_OK
)
180 case CRYPTO_HASH_ALG_HMAC_MD5
:
181 if (hmac_init(&ctx
->u
.hmac
, find_hash("md5"), key
, key_len
) !=
185 case CRYPTO_HASH_ALG_HMAC_SHA1
:
186 if (hmac_init(&ctx
->u
.hmac
, find_hash("sha1"), key
, key_len
) !=
201 void crypto_hash_update(struct crypto_hash
*ctx
, const u8
*data
, size_t len
)
203 if (ctx
== NULL
|| ctx
->error
)
207 case CRYPTO_HASH_ALG_MD5
:
208 ctx
->error
= md5_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
210 case CRYPTO_HASH_ALG_SHA1
:
211 ctx
->error
= sha1_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
213 case CRYPTO_HASH_ALG_HMAC_MD5
:
214 case CRYPTO_HASH_ALG_HMAC_SHA1
:
215 ctx
->error
= hmac_process(&ctx
->u
.hmac
, data
, len
) != CRYPT_OK
;
221 int crypto_hash_finish(struct crypto_hash
*ctx
, u8
*mac
, size_t *len
)
229 if (mac
== NULL
|| len
== NULL
) {
240 case CRYPTO_HASH_ALG_MD5
:
247 if (md5_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
250 case CRYPTO_HASH_ALG_SHA1
:
257 if (sha1_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
260 case CRYPTO_HASH_ALG_HMAC_SHA1
:
267 case CRYPTO_HASH_ALG_HMAC_MD5
:
274 if (hmac_done(&ctx
->u
.hmac
, mac
, &clen
) != CRYPT_OK
) {
291 struct crypto_cipher
{
304 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
305 const u8
*iv
, const u8
*key
,
308 struct crypto_cipher
*ctx
;
309 int idx
, res
, rc4
= 0;
312 case CRYPTO_CIPHER_ALG_AES
:
313 idx
= find_cipher("aes");
315 case CRYPTO_CIPHER_ALG_3DES
:
316 idx
= find_cipher("3des");
318 case CRYPTO_CIPHER_ALG_DES
:
319 idx
= find_cipher("des");
321 case CRYPTO_CIPHER_ALG_RC2
:
322 idx
= find_cipher("rc2");
324 case CRYPTO_CIPHER_ALG_RC4
:
332 ctx
= os_zalloc(sizeof(*ctx
));
338 if (key_len
> sizeof(ctx
->u
.rc4
.key
)) {
342 ctx
->u
.rc4
.keylen
= key_len
;
343 os_memcpy(ctx
->u
.rc4
.key
, key
, key_len
);
345 res
= cbc_start(idx
, iv
, key
, key_len
, 0, &ctx
->u
.cbc
);
346 if (res
!= CRYPT_OK
) {
347 wpa_printf(MSG_DEBUG
, "LibTomCrypt: Cipher start "
348 "failed: %s", error_to_string(res
));
357 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
358 u8
*crypt
, size_t len
)
364 os_memcpy(crypt
, plain
, len
);
365 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
366 ctx
->u
.rc4
.used_bytes
, crypt
, len
);
367 ctx
->u
.rc4
.used_bytes
+= len
;
371 res
= cbc_encrypt(plain
, crypt
, len
, &ctx
->u
.cbc
);
372 if (res
!= CRYPT_OK
) {
373 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC encryption "
374 "failed: %s", error_to_string(res
));
381 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
382 u8
*plain
, size_t len
)
388 os_memcpy(plain
, crypt
, len
);
389 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
390 ctx
->u
.rc4
.used_bytes
, plain
, len
);
391 ctx
->u
.rc4
.used_bytes
+= len
;
395 res
= cbc_decrypt(crypt
, plain
, len
, &ctx
->u
.cbc
);
396 if (res
!= CRYPT_OK
) {
397 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC decryption "
398 "failed: %s", error_to_string(res
));
406 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
409 cbc_done(&ctx
->u
.cbc
);
414 struct crypto_public_key
{
418 struct crypto_private_key
{
423 struct crypto_public_key
* crypto_public_key_import(const u8
*key
, size_t len
)
426 struct crypto_public_key
*pk
;
428 pk
= os_zalloc(sizeof(*pk
));
432 res
= rsa_import(key
, len
, &pk
->rsa
);
433 if (res
!= CRYPT_OK
) {
434 wpa_printf(MSG_ERROR
, "LibTomCrypt: Failed to import "
435 "public key (res=%d '%s')",
436 res
, error_to_string(res
));
441 if (pk
->rsa
.type
!= PK_PUBLIC
) {
442 wpa_printf(MSG_ERROR
, "LibTomCrypt: Public key was not of "
453 struct crypto_private_key
* crypto_private_key_import(const u8
*key
,
457 struct crypto_private_key
*pk
;
459 pk
= os_zalloc(sizeof(*pk
));
463 res
= rsa_import(key
, len
, &pk
->rsa
);
464 if (res
!= CRYPT_OK
) {
465 wpa_printf(MSG_ERROR
, "LibTomCrypt: Failed to import "
466 "private key (res=%d '%s')",
467 res
, error_to_string(res
));
472 if (pk
->rsa
.type
!= PK_PRIVATE
) {
473 wpa_printf(MSG_ERROR
, "LibTomCrypt: Private key was not of "
484 struct crypto_public_key
* crypto_public_key_from_cert(const u8
*buf
,
487 /* No X.509 support in LibTomCrypt */
492 static int pkcs1_generate_encryption_block(u8 block_type
, size_t modlen
,
493 const u8
*in
, size_t inlen
,
494 u8
*out
, size_t *outlen
)
502 * EB = 00 || BT || PS || 00 || D
503 * BT = 00 or 01 for private-key operation; 02 for public-key operation
504 * PS = k-3-||D||; at least eight octets
505 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
506 * k = length of modulus in octets (modlen)
509 if (modlen
< 12 || modlen
> *outlen
|| inlen
> modlen
- 11) {
510 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Invalid buffer "
511 "lengths (modlen=%lu outlen=%lu inlen=%lu)",
512 __func__
, (unsigned long) modlen
,
513 (unsigned long) *outlen
,
514 (unsigned long) inlen
);
520 *pos
++ = block_type
; /* BT */
521 ps_len
= modlen
- inlen
- 3;
522 switch (block_type
) {
524 os_memset(pos
, 0x00, ps_len
);
528 os_memset(pos
, 0xff, ps_len
);
532 if (os_get_random(pos
, ps_len
) < 0) {
533 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Failed to get "
534 "random data for PS", __func__
);
544 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Unsupported block type "
545 "%d", __func__
, block_type
);
549 os_memcpy(pos
, in
, inlen
); /* D */
555 static int crypto_rsa_encrypt_pkcs1(int block_type
, rsa_key
*key
, int key_type
,
556 const u8
*in
, size_t inlen
,
557 u8
*out
, size_t *outlen
)
559 unsigned long len
, modlen
;
562 modlen
= mp_unsigned_bin_size(key
->N
);
564 if (pkcs1_generate_encryption_block(block_type
, modlen
, in
, inlen
,
569 res
= rsa_exptmod(out
, modlen
, out
, &len
, key_type
, key
);
570 if (res
!= CRYPT_OK
) {
571 wpa_printf(MSG_DEBUG
, "LibTomCrypt: rsa_exptmod failed: %s",
572 error_to_string(res
));
581 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key
*key
,
582 const u8
*in
, size_t inlen
,
583 u8
*out
, size_t *outlen
)
585 return crypto_rsa_encrypt_pkcs1(2, &key
->rsa
, PK_PUBLIC
, in
, inlen
,
590 int crypto_private_key_sign_pkcs1(struct crypto_private_key
*key
,
591 const u8
*in
, size_t inlen
,
592 u8
*out
, size_t *outlen
)
594 return crypto_rsa_encrypt_pkcs1(1, &key
->rsa
, PK_PRIVATE
, in
, inlen
,
599 void crypto_public_key_free(struct crypto_public_key
*key
)
608 void crypto_private_key_free(struct crypto_private_key
*key
)
617 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key
*key
,
618 const u8
*crypt
, size_t crypt_len
,
619 u8
*plain
, size_t *plain_len
)
626 res
= rsa_exptmod(crypt
, crypt_len
, plain
, &len
, PK_PUBLIC
,
628 if (res
!= CRYPT_OK
) {
629 wpa_printf(MSG_DEBUG
, "LibTomCrypt: rsa_exptmod failed: %s",
630 error_to_string(res
));
637 * EB = 00 || BT || PS || 00 || D
639 * PS = k-3-||D|| times FF
640 * k = length of modulus in octets
643 if (len
< 3 + 8 + 16 /* min hash len */ ||
644 plain
[0] != 0x00 || plain
[1] != 0x01 || plain
[2] != 0xff) {
645 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature EB "
651 while (pos
< plain
+ len
&& *pos
== 0xff)
653 if (pos
- plain
- 2 < 8) {
654 /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
655 wpa_printf(MSG_INFO
, "LibTomCrypt: Too short signature "
660 if (pos
+ 16 /* min hash len */ >= plain
+ len
|| *pos
!= 0x00) {
661 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature EB "
668 /* Strip PKCS #1 header */
669 os_memmove(plain
, pos
, len
);
676 int crypto_global_init(void)
679 /* TODO: only register algorithms that are really needed */
680 if (register_hash(&md4_desc
) < 0 ||
681 register_hash(&md5_desc
) < 0 ||
682 register_hash(&sha1_desc
) < 0 ||
683 register_cipher(&aes_desc
) < 0 ||
684 register_cipher(&des_desc
) < 0 ||
685 register_cipher(&des3_desc
) < 0) {
686 wpa_printf(MSG_ERROR
, "TLSv1: Failed to register "
687 "hash/cipher functions");
695 void crypto_global_deinit(void)
702 int crypto_mod_exp(const u8
*base
, size_t base_len
,
703 const u8
*power
, size_t power_len
,
704 const u8
*modulus
, size_t modulus_len
,
705 u8
*result
, size_t *result_len
)
709 if (mp_init_multi(&b
, &p
, &m
, &r
, NULL
) != CRYPT_OK
)
712 if (mp_read_unsigned_bin(b
, (u8
*) base
, base_len
) != CRYPT_OK
||
713 mp_read_unsigned_bin(p
, (u8
*) power
, power_len
) != CRYPT_OK
||
714 mp_read_unsigned_bin(m
, (u8
*) modulus
, modulus_len
) != CRYPT_OK
)
717 if (mp_exptmod(b
, p
, m
, r
) != CRYPT_OK
)
720 *result_len
= mp_unsigned_bin_size(r
);
721 if (mp_to_unsigned_bin(r
, result
) != CRYPT_OK
)
724 mp_clear_multi(b
, p
, m
, r
, NULL
);
728 mp_clear_multi(b
, p
, m
, r
, NULL
);
732 #endif /* EAP_FAST */
734 #endif /* CONFIG_TLS_INTERNAL */
736 #endif /* EAP_TLS_FUNCS */