2 * WPA Supplicant / Crypto wrapper for LibTomCrypt (for internal TLSv1)
3 * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
16 #define mp_init_multi ltc_init_multi
17 #define mp_clear_multi ltc_deinit_multi
18 #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
19 #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
20 #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
21 #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
25 int md4_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
31 for (i
= 0; i
< num_elem
; i
++)
32 md4_process(&md
, addr
[i
], len
[i
]);
38 void des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
40 u8 pkey
[8], next
, tmp
;
44 /* Add parity bits to the key */
46 for (i
= 0; i
< 7; i
++) {
48 pkey
[i
] = (tmp
>> i
) | next
| 1;
49 next
= tmp
<< (7 - i
);
53 des_setup(pkey
, 8, 0, &skey
);
54 des_ecb_encrypt(clear
, cypher
, &skey
);
59 int md5_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
65 for (i
= 0; i
< num_elem
; i
++)
66 md5_process(&md
, addr
[i
], len
[i
]);
72 int sha1_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
78 for (i
= 0; i
< num_elem
; i
++)
79 sha1_process(&md
, addr
[i
], len
[i
]);
85 void * aes_encrypt_init(const u8
*key
, size_t len
)
88 skey
= os_malloc(sizeof(*skey
));
91 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
99 void aes_encrypt(void *ctx
, const u8
*plain
, u8
*crypt
)
101 symmetric_key
*skey
= ctx
;
102 aes_ecb_encrypt(plain
, crypt
, skey
);
106 void aes_encrypt_deinit(void *ctx
)
108 symmetric_key
*skey
= ctx
;
114 void * aes_decrypt_init(const u8
*key
, size_t len
)
117 skey
= os_malloc(sizeof(*skey
));
120 if (aes_setup(key
, len
, 0, skey
) != CRYPT_OK
) {
128 void aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
130 symmetric_key
*skey
= ctx
;
131 aes_ecb_encrypt(plain
, (u8
*) crypt
, skey
);
135 void aes_decrypt_deinit(void *ctx
)
137 symmetric_key
*skey
= ctx
;
144 enum crypto_hash_alg alg
;
153 struct crypto_hash
* crypto_hash_init(enum crypto_hash_alg alg
, const u8
*key
,
156 struct crypto_hash
*ctx
;
158 ctx
= os_zalloc(sizeof(*ctx
));
165 case CRYPTO_HASH_ALG_MD5
:
166 if (md5_init(&ctx
->u
.md
) != CRYPT_OK
)
169 case CRYPTO_HASH_ALG_SHA1
:
170 if (sha1_init(&ctx
->u
.md
) != CRYPT_OK
)
173 case CRYPTO_HASH_ALG_HMAC_MD5
:
174 if (hmac_init(&ctx
->u
.hmac
, find_hash("md5"), key
, key_len
) !=
178 case CRYPTO_HASH_ALG_HMAC_SHA1
:
179 if (hmac_init(&ctx
->u
.hmac
, find_hash("sha1"), key
, key_len
) !=
194 void crypto_hash_update(struct crypto_hash
*ctx
, const u8
*data
, size_t len
)
196 if (ctx
== NULL
|| ctx
->error
)
200 case CRYPTO_HASH_ALG_MD5
:
201 ctx
->error
= md5_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
203 case CRYPTO_HASH_ALG_SHA1
:
204 ctx
->error
= sha1_process(&ctx
->u
.md
, data
, len
) != CRYPT_OK
;
206 case CRYPTO_HASH_ALG_HMAC_MD5
:
207 case CRYPTO_HASH_ALG_HMAC_SHA1
:
208 ctx
->error
= hmac_process(&ctx
->u
.hmac
, data
, len
) != CRYPT_OK
;
214 int crypto_hash_finish(struct crypto_hash
*ctx
, u8
*mac
, size_t *len
)
222 if (mac
== NULL
|| len
== NULL
) {
233 case CRYPTO_HASH_ALG_MD5
:
240 if (md5_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
243 case CRYPTO_HASH_ALG_SHA1
:
250 if (sha1_done(&ctx
->u
.md
, mac
) != CRYPT_OK
)
253 case CRYPTO_HASH_ALG_HMAC_SHA1
:
260 case CRYPTO_HASH_ALG_HMAC_MD5
:
267 if (hmac_done(&ctx
->u
.hmac
, mac
, &clen
) != CRYPT_OK
) {
284 struct crypto_cipher
{
297 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
298 const u8
*iv
, const u8
*key
,
301 struct crypto_cipher
*ctx
;
302 int idx
, res
, rc4
= 0;
305 case CRYPTO_CIPHER_ALG_AES
:
306 idx
= find_cipher("aes");
308 case CRYPTO_CIPHER_ALG_3DES
:
309 idx
= find_cipher("3des");
311 case CRYPTO_CIPHER_ALG_DES
:
312 idx
= find_cipher("des");
314 case CRYPTO_CIPHER_ALG_RC2
:
315 idx
= find_cipher("rc2");
317 case CRYPTO_CIPHER_ALG_RC4
:
325 ctx
= os_zalloc(sizeof(*ctx
));
331 if (key_len
> sizeof(ctx
->u
.rc4
.key
)) {
335 ctx
->u
.rc4
.keylen
= key_len
;
336 os_memcpy(ctx
->u
.rc4
.key
, key
, key_len
);
338 res
= cbc_start(idx
, iv
, key
, key_len
, 0, &ctx
->u
.cbc
);
339 if (res
!= CRYPT_OK
) {
340 wpa_printf(MSG_DEBUG
, "LibTomCrypt: Cipher start "
341 "failed: %s", error_to_string(res
));
350 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
351 u8
*crypt
, size_t len
)
357 os_memcpy(crypt
, plain
, len
);
358 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
359 ctx
->u
.rc4
.used_bytes
, crypt
, len
);
360 ctx
->u
.rc4
.used_bytes
+= len
;
364 res
= cbc_encrypt(plain
, crypt
, len
, &ctx
->u
.cbc
);
365 if (res
!= CRYPT_OK
) {
366 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC encryption "
367 "failed: %s", error_to_string(res
));
374 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
375 u8
*plain
, size_t len
)
381 os_memcpy(plain
, crypt
, len
);
382 rc4_skip(ctx
->u
.rc4
.key
, ctx
->u
.rc4
.keylen
,
383 ctx
->u
.rc4
.used_bytes
, plain
, len
);
384 ctx
->u
.rc4
.used_bytes
+= len
;
388 res
= cbc_decrypt(crypt
, plain
, len
, &ctx
->u
.cbc
);
389 if (res
!= CRYPT_OK
) {
390 wpa_printf(MSG_DEBUG
, "LibTomCrypt: CBC decryption "
391 "failed: %s", error_to_string(res
));
399 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
402 cbc_done(&ctx
->u
.cbc
);
407 struct crypto_public_key
{
411 struct crypto_private_key
{
416 struct crypto_public_key
* crypto_public_key_import(const u8
*key
, size_t len
)
419 struct crypto_public_key
*pk
;
421 pk
= os_zalloc(sizeof(*pk
));
425 res
= rsa_import(key
, len
, &pk
->rsa
);
426 if (res
!= CRYPT_OK
) {
427 wpa_printf(MSG_ERROR
, "LibTomCrypt: Failed to import "
428 "public key (res=%d '%s')",
429 res
, error_to_string(res
));
434 if (pk
->rsa
.type
!= PK_PUBLIC
) {
435 wpa_printf(MSG_ERROR
, "LibTomCrypt: Public key was not of "
446 struct crypto_private_key
* crypto_private_key_import(const u8
*key
,
451 struct crypto_private_key
*pk
;
453 pk
= os_zalloc(sizeof(*pk
));
457 res
= rsa_import(key
, len
, &pk
->rsa
);
458 if (res
!= CRYPT_OK
) {
459 wpa_printf(MSG_ERROR
, "LibTomCrypt: Failed to import "
460 "private key (res=%d '%s')",
461 res
, error_to_string(res
));
466 if (pk
->rsa
.type
!= PK_PRIVATE
) {
467 wpa_printf(MSG_ERROR
, "LibTomCrypt: Private key was not of "
478 struct crypto_public_key
* crypto_public_key_from_cert(const u8
*buf
,
481 /* No X.509 support in LibTomCrypt */
486 static int pkcs1_generate_encryption_block(u8 block_type
, size_t modlen
,
487 const u8
*in
, size_t inlen
,
488 u8
*out
, size_t *outlen
)
496 * EB = 00 || BT || PS || 00 || D
497 * BT = 00 or 01 for private-key operation; 02 for public-key operation
498 * PS = k-3-||D||; at least eight octets
499 * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero)
500 * k = length of modulus in octets (modlen)
503 if (modlen
< 12 || modlen
> *outlen
|| inlen
> modlen
- 11) {
504 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Invalid buffer "
505 "lengths (modlen=%lu outlen=%lu inlen=%lu)",
506 __func__
, (unsigned long) modlen
,
507 (unsigned long) *outlen
,
508 (unsigned long) inlen
);
514 *pos
++ = block_type
; /* BT */
515 ps_len
= modlen
- inlen
- 3;
516 switch (block_type
) {
518 os_memset(pos
, 0x00, ps_len
);
522 os_memset(pos
, 0xff, ps_len
);
526 if (os_get_random(pos
, ps_len
) < 0) {
527 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Failed to get "
528 "random data for PS", __func__
);
538 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Unsupported block type "
539 "%d", __func__
, block_type
);
543 os_memcpy(pos
, in
, inlen
); /* D */
549 static int crypto_rsa_encrypt_pkcs1(int block_type
, rsa_key
*key
, int key_type
,
550 const u8
*in
, size_t inlen
,
551 u8
*out
, size_t *outlen
)
553 unsigned long len
, modlen
;
556 modlen
= mp_unsigned_bin_size(key
->N
);
558 if (pkcs1_generate_encryption_block(block_type
, modlen
, in
, inlen
,
563 res
= rsa_exptmod(out
, modlen
, out
, &len
, key_type
, key
);
564 if (res
!= CRYPT_OK
) {
565 wpa_printf(MSG_DEBUG
, "LibTomCrypt: rsa_exptmod failed: %s",
566 error_to_string(res
));
575 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key
*key
,
576 const u8
*in
, size_t inlen
,
577 u8
*out
, size_t *outlen
)
579 return crypto_rsa_encrypt_pkcs1(2, &key
->rsa
, PK_PUBLIC
, in
, inlen
,
584 int crypto_private_key_sign_pkcs1(struct crypto_private_key
*key
,
585 const u8
*in
, size_t inlen
,
586 u8
*out
, size_t *outlen
)
588 return crypto_rsa_encrypt_pkcs1(1, &key
->rsa
, PK_PRIVATE
, in
, inlen
,
593 void crypto_public_key_free(struct crypto_public_key
*key
)
602 void crypto_private_key_free(struct crypto_private_key
*key
)
611 int crypto_public_key_decrypt_pkcs1(struct crypto_public_key
*key
,
612 const u8
*crypt
, size_t crypt_len
,
613 u8
*plain
, size_t *plain_len
)
620 res
= rsa_exptmod(crypt
, crypt_len
, plain
, &len
, PK_PUBLIC
,
622 if (res
!= CRYPT_OK
) {
623 wpa_printf(MSG_DEBUG
, "LibTomCrypt: rsa_exptmod failed: %s",
624 error_to_string(res
));
631 * EB = 00 || BT || PS || 00 || D
633 * PS = k-3-||D|| times FF
634 * k = length of modulus in octets
637 if (len
< 3 + 8 + 16 /* min hash len */ ||
638 plain
[0] != 0x00 || plain
[1] != 0x01 || plain
[2] != 0xff) {
639 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature EB "
645 while (pos
< plain
+ len
&& *pos
== 0xff)
647 if (pos
- plain
- 2 < 8) {
648 /* PKCS #1 v1.5, 8.1: At least eight octets long PS */
649 wpa_printf(MSG_INFO
, "LibTomCrypt: Too short signature "
654 if (pos
+ 16 /* min hash len */ >= plain
+ len
|| *pos
!= 0x00) {
655 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature EB "
662 /* Strip PKCS #1 header */
663 os_memmove(plain
, pos
, len
);
670 int crypto_global_init(void)
673 /* TODO: only register algorithms that are really needed */
674 if (register_hash(&md4_desc
) < 0 ||
675 register_hash(&md5_desc
) < 0 ||
676 register_hash(&sha1_desc
) < 0 ||
677 register_cipher(&aes_desc
) < 0 ||
678 register_cipher(&des_desc
) < 0 ||
679 register_cipher(&des3_desc
) < 0) {
680 wpa_printf(MSG_ERROR
, "TLSv1: Failed to register "
681 "hash/cipher functions");
689 void crypto_global_deinit(void)
696 int crypto_mod_exp(const u8
*base
, size_t base_len
,
697 const u8
*power
, size_t power_len
,
698 const u8
*modulus
, size_t modulus_len
,
699 u8
*result
, size_t *result_len
)
703 if (mp_init_multi(&b
, &p
, &m
, &r
, NULL
) != CRYPT_OK
)
706 if (mp_read_unsigned_bin(b
, (u8
*) base
, base_len
) != CRYPT_OK
||
707 mp_read_unsigned_bin(p
, (u8
*) power
, power_len
) != CRYPT_OK
||
708 mp_read_unsigned_bin(m
, (u8
*) modulus
, modulus_len
) != CRYPT_OK
)
711 if (mp_exptmod(b
, p
, m
, r
) != CRYPT_OK
)
714 *result_len
= mp_unsigned_bin_size(r
);
715 if (mp_to_unsigned_bin(r
, result
) != CRYPT_OK
)
718 mp_clear_multi(b
, p
, m
, r
, NULL
);
722 mp_clear_multi(b
, p
, m
, r
, NULL
);
726 #endif /* CONFIG_MODEXP */