2 * WPA Supplicant / Crypto wrapper for internal crypto implementation
3 * Copyright (c) 2006-2007, 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.
24 #include "tls/bignum.h"
30 #ifdef CONFIG_TLS_INTERNAL
38 void des3_key_setup(const u8
*key
, struct des3_key_s
*dkey
);
39 void des3_encrypt(const u8
*plain
, const struct des3_key_s
*key
, u8
*crypt
);
40 void des3_decrypt(const u8
*crypt
, const struct des3_key_s
*key
, u8
*plain
);
52 unsigned char buffer
[64];
57 enum crypto_hash_alg alg
;
59 struct MD5Context md5
;
60 struct SHA1Context sha1
;
67 struct crypto_hash
* crypto_hash_init(enum crypto_hash_alg alg
, const u8
*key
,
70 struct crypto_hash
*ctx
;
75 ctx
= os_zalloc(sizeof(*ctx
));
82 case CRYPTO_HASH_ALG_MD5
:
85 case CRYPTO_HASH_ALG_SHA1
:
86 SHA1Init(&ctx
->u
.sha1
);
88 case CRYPTO_HASH_ALG_HMAC_MD5
:
89 if (key_len
> sizeof(k_pad
)) {
91 MD5Update(&ctx
->u
.md5
, key
, key_len
);
92 MD5Final(tk
, &ctx
->u
.md5
);
96 os_memcpy(ctx
->key
, key
, key_len
);
97 ctx
->key_len
= key_len
;
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
++)
103 MD5Init(&ctx
->u
.md5
);
104 MD5Update(&ctx
->u
.md5
, k_pad
, sizeof(k_pad
));
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
);
114 os_memcpy(ctx
->key
, key
, key_len
);
115 ctx
->key_len
= key_len
;
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
++)
121 SHA1Init(&ctx
->u
.sha1
);
122 SHA1Update(&ctx
->u
.sha1
, k_pad
, sizeof(k_pad
));
133 void crypto_hash_update(struct crypto_hash
*ctx
, const u8
*data
, size_t len
)
139 case CRYPTO_HASH_ALG_MD5
:
140 case CRYPTO_HASH_ALG_HMAC_MD5
:
141 MD5Update(&ctx
->u
.md5
, data
, len
);
143 case CRYPTO_HASH_ALG_SHA1
:
144 case CRYPTO_HASH_ALG_HMAC_SHA1
:
145 SHA1Update(&ctx
->u
.sha1
, data
, len
);
151 int crypto_hash_finish(struct crypto_hash
*ctx
, u8
*mac
, size_t *len
)
159 if (mac
== NULL
|| len
== NULL
) {
165 case CRYPTO_HASH_ALG_MD5
:
172 MD5Final(mac
, &ctx
->u
.md5
);
174 case CRYPTO_HASH_ALG_SHA1
:
181 SHA1Final(mac
, &ctx
->u
.sha1
);
183 case CRYPTO_HASH_ALG_HMAC_MD5
:
191 MD5Final(mac
, &ctx
->u
.md5
);
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
++)
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
);
203 case CRYPTO_HASH_ALG_HMAC_SHA1
:
211 SHA1Final(mac
, &ctx
->u
.sha1
);
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
++)
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
);
231 struct crypto_cipher
{
232 enum crypto_cipher_alg alg
;
246 struct des3_key_s key
;
253 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
254 const u8
*iv
, const u8
*key
,
257 struct crypto_cipher
*ctx
;
259 ctx
= os_zalloc(sizeof(*ctx
));
266 case CRYPTO_CIPHER_ALG_RC4
:
267 if (key_len
> sizeof(ctx
->u
.rc4
.key
)) {
271 ctx
->u
.rc4
.keylen
= key_len
;
272 os_memcpy(ctx
->u
.rc4
.key
, key
, key_len
);
274 case CRYPTO_CIPHER_ALG_AES
:
275 if (key_len
> sizeof(ctx
->u
.aes
.cbc
)) {
279 ctx
->u
.aes
.ctx_enc
= aes_encrypt_init(key
, key_len
);
280 if (ctx
->u
.aes
.ctx_enc
== NULL
) {
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
);
290 ctx
->u
.aes
.block_size
= key_len
;
291 os_memcpy(ctx
->u
.aes
.cbc
, iv
, ctx
->u
.aes
.block_size
);
293 case CRYPTO_CIPHER_ALG_3DES
:
298 des3_key_setup(key
, &ctx
->u
.des3
.key
);
299 os_memcpy(ctx
->u
.des3
.cbc
, iv
, 8);
310 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
311 u8
*crypt
, size_t len
)
316 case CRYPTO_CIPHER_ALG_RC4
:
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
;
323 case CRYPTO_CIPHER_ALG_AES
:
324 if (len
% ctx
->u
.aes
.block_size
)
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
,
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
;
338 case CRYPTO_CIPHER_ALG_3DES
:
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
,
347 os_memcpy(crypt
, ctx
->u
.des3
.cbc
, 8);
360 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
361 u8
*plain
, size_t len
)
367 case CRYPTO_CIPHER_ALG_RC4
:
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
;
374 case CRYPTO_CIPHER_ALG_AES
:
375 if (len
% ctx
->u
.aes
.block_size
)
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
;
388 case CRYPTO_CIPHER_ALG_3DES
:
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);
410 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
413 case CRYPTO_CIPHER_ALG_AES
:
414 aes_encrypt_deinit(ctx
->u
.aes
.ctx_enc
);
415 aes_decrypt_deinit(ctx
->u
.aes
.ctx_dec
);
417 case CRYPTO_CIPHER_ALG_3DES
:
426 /* Dummy structures; these are just typecast to struct crypto_rsa_key */
427 struct crypto_public_key
;
428 struct crypto_private_key
;
431 struct crypto_public_key
* crypto_public_key_import(const u8
*key
, size_t len
)
433 return (struct crypto_public_key
*)
434 crypto_rsa_import_public_key(key
, len
);
438 static struct crypto_private_key
*
439 crypto_pkcs8_key_import(const u8
*buf
, size_t len
)
447 /* PKCS #8, Chapter 6 */
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");
458 end
= pos
+ hdr
.length
;
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",
469 zero
= bignum_init();
473 if (bignum_set_unsigned_bin(zero
, hdr
.payload
, hdr
.length
) < 0) {
474 wpa_printf(MSG_DEBUG
, "PKCS #8: Failed to parse INTEGER");
478 pos
= hdr
.payload
+ hdr
.length
;
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 "
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",
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");
507 asn1_oid_to_str(&oid
, obuf
, sizeof(obuf
));
508 wpa_printf(MSG_DEBUG
, "PKCS #8: algorithm=%s", obuf
);
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
);
523 pos
= hdr
.payload
+ hdr
.length
;
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",
534 wpa_printf(MSG_DEBUG
, "PKCS #8: Try to parse RSAPrivateKey");
536 return (struct crypto_private_key
*)
537 crypto_rsa_import_private_key(hdr
.payload
, hdr
.length
);
541 struct crypto_private_key
* crypto_private_key_import(const u8
*key
,
544 struct crypto_private_key
*res
;
546 /* First, check for possible PKCS #8 encoding */
547 res
= crypto_pkcs8_key_import(key
, len
);
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 "
554 return (struct crypto_private_key
*)
555 crypto_rsa_import_private_key(key
, len
);
559 struct crypto_public_key
* crypto_public_key_from_cert(const u8
*buf
,
562 /* No X.509 support in crypto_internal.c */
567 static int pkcs1_generate_encryption_block(u8 block_type
, size_t modlen
,
568 const u8
*in
, size_t inlen
,
569 u8
*out
, size_t *outlen
)
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)
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
);
595 *pos
++ = block_type
; /* BT */
596 ps_len
= modlen
- inlen
- 3;
597 switch (block_type
) {
599 os_memset(pos
, 0x00, ps_len
);
603 os_memset(pos
, 0xff, ps_len
);
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__
);
619 wpa_printf(MSG_DEBUG
, "PKCS #1: %s - Unsupported block type "
620 "%d", __func__
, block_type
);
624 os_memcpy(pos
, in
, inlen
); /* D */
630 static int crypto_rsa_encrypt_pkcs1(int block_type
, struct crypto_rsa_key
*key
,
632 const u8
*in
, size_t inlen
,
633 u8
*out
, size_t *outlen
)
637 modlen
= crypto_rsa_get_modulus_len(key
);
639 if (pkcs1_generate_encryption_block(block_type
, modlen
, in
, inlen
,
643 return crypto_rsa_exptmod(out
, modlen
, out
, outlen
, key
, use_private
);
647 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key
*key
,
648 const u8
*in
, size_t inlen
,
649 u8
*out
, size_t *outlen
)
651 return crypto_rsa_encrypt_pkcs1(2, (struct crypto_rsa_key
*) key
,
652 0, in
, inlen
, out
, outlen
);
656 int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key
*key
,
657 const u8
*in
, size_t inlen
,
658 u8
*out
, size_t *outlen
)
660 struct crypto_rsa_key
*rkey
= (struct crypto_rsa_key
*) key
;
664 res
= crypto_rsa_exptmod(in
, inlen
, out
, outlen
, rkey
, 1);
668 if (*outlen
< 2 || out
[0] != 0 || out
[1] != 2)
671 /* Skip PS (pseudorandom non-zero octets) */
674 while (*pos
&& pos
< end
)
680 *outlen
-= pos
- out
;
682 /* Strip PKCS #1 header */
683 os_memmove(out
, pos
, *outlen
);
689 int crypto_private_key_sign_pkcs1(struct crypto_private_key
*key
,
690 const u8
*in
, size_t inlen
,
691 u8
*out
, size_t *outlen
)
693 return crypto_rsa_encrypt_pkcs1(1, (struct crypto_rsa_key
*) key
,
694 1, in
, inlen
, out
, outlen
);
698 void crypto_public_key_free(struct crypto_public_key
*key
)
700 crypto_rsa_free((struct crypto_rsa_key
*) key
);
704 void crypto_private_key_free(struct crypto_private_key
*key
)
706 crypto_rsa_free((struct crypto_rsa_key
*) key
);
710 int 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
)
718 if (crypto_rsa_exptmod(crypt
, crypt_len
, plain
, &len
,
719 (struct crypto_rsa_key
*) key
, 0) < 0)
725 * EB = 00 || BT || PS || 00 || D
727 * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
728 * k = length of modulus in octets
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 "
739 if (plain
[1] == 0x00) {
741 if (plain
[2] != 0x00) {
742 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature "
746 while (pos
+ 1 < plain
+ len
&& *pos
== 0x00 && pos
[1] == 0x00)
750 if (plain
[2] != 0xff) {
751 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature "
755 while (pos
< plain
+ len
&& *pos
== 0xff)
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 "
766 if (pos
+ 16 /* min hash len */ >= plain
+ len
|| *pos
!= 0x00) {
767 wpa_printf(MSG_INFO
, "LibTomCrypt: Invalid signature EB "
774 /* Strip PKCS #1 header */
775 os_memmove(plain
, pos
, len
);
782 int crypto_global_init(void)
788 void crypto_global_deinit(void)
795 int 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
)
800 struct bignum
*bn_base
, *bn_exp
, *bn_modulus
, *bn_result
;
803 bn_base
= bignum_init();
804 bn_exp
= bignum_init();
805 bn_modulus
= bignum_init();
806 bn_result
= bignum_init();
808 if (bn_base
== NULL
|| bn_exp
== NULL
|| bn_modulus
== NULL
||
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)
817 if (bignum_exptmod(bn_base
, bn_exp
, bn_modulus
, bn_result
) < 0)
820 ret
= bignum_get_unsigned_bin(bn_result
, result
, result_len
);
823 bignum_deinit(bn_base
);
824 bignum_deinit(bn_exp
);
825 bignum_deinit(bn_modulus
);
826 bignum_deinit(bn_result
);
830 #endif /* EAP_FAST */
833 #endif /* CONFIG_TLS_INTERNAL */
835 #endif /* EAP_TLS_FUNCS */