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.
22 #define mp_init_multi ltc_init_multi
23 #define mp_clear_multi ltc_deinit_multi
24 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
25 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
26 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
27 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
31 int md4_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
37 for (i
= 0; i
< num_elem
; i
++)
38 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
);
65 int md5_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
71 for (i
= 0; i
< num_elem
; i
++)
72 md5_process(&md
, addr
[i
], len
[i
]);
78 int 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
]);
91 void * aes_encrypt_init(const u8
*key
, size_t len
)
94 skey
= os_malloc(sizeof(*skey
));
97 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
105 void aes_encrypt(void *ctx
, const u8
*plain
, u8
*crypt
)
107 symmetric_key
*skey
= ctx
;
108 aes_ecb_encrypt(plain
, crypt
, skey
);
112 void aes_encrypt_deinit(void *ctx
)
114 symmetric_key
*skey
= ctx
;
120 void * aes_decrypt_init(const u8
*key
, size_t len
)
123 skey
= os_malloc(sizeof(*skey
));
126 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
134 void aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
136 symmetric_key
*skey
= ctx
;
137 aes_ecb_encrypt(plain
, (u8
*) crypt
, skey
);
141 void aes_decrypt_deinit(void *ctx
)
143 symmetric_key
*skey
= ctx
;
150 enum crypto_hash_alg alg
;
159 struct crypto_hash
* crypto_hash_init(enum crypto_hash_alg alg
, const u8
*key
,
162 struct crypto_hash
*ctx
;
164 ctx
= os_zalloc(sizeof(*ctx
));
171 case CRYPTO_HASH_ALG_MD5
:
172 if (md5_init(&ctx
->u
.md
) != CRYPT_OK
)
175 case CRYPTO_HASH_ALG_SHA1
:
176 if (sha1_init(&ctx
->u
.md
) != CRYPT_OK
)
179 case CRYPTO_HASH_ALG_HMAC_MD5
:
180 if (hmac_init(&ctx
->u
.hmac
, find_hash("md5"), key
, key_len
) !=
184 case CRYPTO_HASH_ALG_HMAC_SHA1
:
185 if (hmac_init(&ctx
->u
.hmac
, find_hash("sha1"), key
, key_len
) !=
200 void crypto_hash_update(struct crypto_hash
*ctx
, const u8
*data
, size_t len
)
202 if (ctx
== NULL
|| ctx
->error
)
206 case CRYPTO_HASH_ALG_MD5
:
207 ctx
->error
= md5_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
209 case CRYPTO_HASH_ALG_SHA1
:
210 ctx
->error
= sha1_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
212 case CRYPTO_HASH_ALG_HMAC_MD5
:
213 case CRYPTO_HASH_ALG_HMAC_SHA1
:
214 ctx
->error
= hmac_process(&ctx
->u
.hmac
, data
, len
) != CRYPT_OK
;
220 int crypto_hash_finish(struct crypto_hash
*ctx
, u8
*mac
, size_t *len
)
228 if (mac
== NULL
|| len
== NULL
) {
239 case CRYPTO_HASH_ALG_MD5
:
246 if (md5_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
249 case CRYPTO_HASH_ALG_SHA1
:
256 if (sha1_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
259 case CRYPTO_HASH_ALG_HMAC_SHA1
:
266 case CRYPTO_HASH_ALG_HMAC_MD5
:
273 if (hmac_done(&ctx
->u
.hmac
, mac
, &clen
) != CRYPT_OK
) {
290 struct crypto_cipher
{
303 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
304 const u8
*iv
, const u8
*key
,
307 struct crypto_cipher
*ctx
;
308 int idx
, res
, rc4
= 0;
311 case CRYPTO_CIPHER_ALG_AES
:
312 idx
= find_cipher("aes");
314 case CRYPTO_CIPHER_ALG_3DES
:
315 idx
= find_cipher("3des");
317 case CRYPTO_CIPHER_ALG_DES
:
318 idx
= find_cipher("des");
320 case CRYPTO_CIPHER_ALG_RC2
:
321 idx
= find_cipher("rc2");
323 case CRYPTO_CIPHER_ALG_RC4
:
331 ctx
= os_zalloc(sizeof(*ctx
));
337 if (key_len
> sizeof(ctx
->u
.rc4
.key
)) {
341 ctx
->u
.rc4
.keylen
= key_len
;
342 os_memcpy(ctx
->u
.rc4
.key
, key
, key_len
);
344 res
= cbc_start(idx
, iv
, key
, key_len
, 0, &ctx
->u
.cbc
);
345 if (res
!= CRYPT_OK
) {
346 wpa_printf(MSG_DEBUG
, "LibTomCrypt: Cipher start "
347 "failed: %s", error_to_string(res
));
356 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
357 u8
*crypt
, size_t len
)
363 os_memcpy(crypt
, plain
, len
);
364 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
365 ctx
->u
.rc4
.used_bytes
, crypt
, len
);
366 ctx
->u
.rc4
.used_bytes
+= len
;
370 res
= cbc_encrypt(plain
, crypt
, len
, &ctx
->u
.cbc
);
371 if (res
!= CRYPT_OK
) {
372 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC encryption "
373 "failed: %s", error_to_string(res
));
380 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
381 u8
*plain
, size_t len
)
387 os_memcpy(plain
, crypt
, len
);
388 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
389 ctx
->u
.rc4
.used_bytes
, plain
, len
);
390 ctx
->u
.rc4
.used_bytes
+= len
;
394 res
= cbc_decrypt(crypt
, plain
, len
, &ctx
->u
.cbc
);
395 if (res
!= CRYPT_OK
) {
396 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC decryption "
397 "failed: %s", error_to_string(res
));
405 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
408 cbc_done(&ctx
->u
.cbc
);
413 struct crypto_public_key
{
417 struct crypto_private_key
{
422 struct crypto_public_key
* crypto_public_key_import(const u8
*key
, size_t len
)
425 struct crypto_public_key
*pk
;
427 pk
= os_zalloc(sizeof(*pk
));
431 res
= rsa_import(key
, len
, &pk
->rsa
);
432 if (res
!= CRYPT_OK
) {
433 wpa_printf(MSG_ERROR
, "LibTomCrypt: Failed to import "
434 "public key (res=%d '%s')",
435 res
, error_to_string(res
));
440 if (pk
->rsa
.type
!= PK_PUBLIC
) {
441 wpa_printf(MSG_ERROR
, "LibTomCrypt: Public key was not of "
452 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 /* CONFIG_MODEXP */