2 * Wrapper functions for libwolfssl
3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
15 #include <wolfssl/options.h>
16 #include <wolfssl/wolfcrypt/md4.h>
17 #include <wolfssl/wolfcrypt/md5.h>
18 #include <wolfssl/wolfcrypt/sha.h>
19 #include <wolfssl/wolfcrypt/sha256.h>
20 #include <wolfssl/wolfcrypt/sha512.h>
21 #include <wolfssl/wolfcrypt/hmac.h>
22 #include <wolfssl/wolfcrypt/pwdbased.h>
23 #include <wolfssl/wolfcrypt/arc4.h>
24 #include <wolfssl/wolfcrypt/des3.h>
25 #include <wolfssl/wolfcrypt/aes.h>
26 #include <wolfssl/wolfcrypt/dh.h>
27 #include <wolfssl/wolfcrypt/cmac.h>
28 #include <wolfssl/wolfcrypt/ecc.h>
29 #include <wolfssl/openssl/bn.h>
34 int md4_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
44 for (i
= 0; i
< num_elem
; i
++)
45 wc_Md4Update(&md4
, addr
[i
], len
[i
]);
47 wc_Md4Final(&md4
, mac
);
53 int md5_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
63 for (i
= 0; i
< num_elem
; i
++)
64 wc_Md5Update(&md5
, addr
[i
], len
[i
]);
66 wc_Md5Final(&md5
, mac
);
71 #endif /* CONFIG_FIPS */
74 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 wc_ShaUpdate(&sha
, addr
[i
], len
[i
]);
87 wc_ShaFinal(&sha
, mac
);
93 #ifndef NO_SHA256_WRAPPER
94 int sha256_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
,
103 wc_InitSha256(&sha256
);
105 for (i
= 0; i
< num_elem
; i
++)
106 wc_Sha256Update(&sha256
, addr
[i
], len
[i
]);
108 wc_Sha256Final(&sha256
, mac
);
112 #endif /* NO_SHA256_WRAPPER */
116 int sha384_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
,
125 wc_InitSha384(&sha384
);
127 for (i
= 0; i
< num_elem
; i
++)
128 wc_Sha384Update(&sha384
, addr
[i
], len
[i
]);
130 wc_Sha384Final(&sha384
, mac
);
134 #endif /* CONFIG_SHA384 */
138 int sha512_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
,
147 wc_InitSha512(&sha512
);
149 for (i
= 0; i
< num_elem
; i
++)
150 wc_Sha512Update(&sha512
, addr
[i
], len
[i
]);
152 wc_Sha512Final(&sha512
, mac
);
156 #endif /* CONFIG_SHA512 */
159 static int wolfssl_hmac_vector(int type
, const u8
*key
,
160 size_t key_len
, size_t num_elem
,
161 const u8
*addr
[], const size_t *len
, u8
*mac
,
172 if (wc_HmacSetKey(&hmac
, type
, key
, (word32
) key_len
) != 0)
174 for (i
= 0; i
< num_elem
; i
++)
175 if (wc_HmacUpdate(&hmac
, addr
[i
], len
[i
]) != 0)
177 if (wc_HmacFinal(&hmac
, mac
) != 0)
185 int hmac_md5_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
186 const u8
*addr
[], const size_t *len
, u8
*mac
)
188 return wolfssl_hmac_vector(WC_MD5
, key
, key_len
, num_elem
, addr
, len
,
193 int hmac_md5(const u8
*key
, size_t key_len
, const u8
*data
, size_t data_len
,
196 return hmac_md5_vector(key
, key_len
, 1, &data
, &data_len
, mac
);
199 #endif /* CONFIG_FIPS */
202 int hmac_sha1_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
203 const u8
*addr
[], const size_t *len
, u8
*mac
)
205 return wolfssl_hmac_vector(WC_SHA
, key
, key_len
, num_elem
, addr
, len
,
210 int hmac_sha1(const u8
*key
, size_t key_len
, const u8
*data
, size_t data_len
,
213 return hmac_sha1_vector(key
, key_len
, 1, &data
, &data_len
, mac
);
219 int hmac_sha256_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
220 const u8
*addr
[], const size_t *len
, u8
*mac
)
222 return wolfssl_hmac_vector(WC_SHA256
, key
, key_len
, num_elem
, addr
, len
,
227 int hmac_sha256(const u8
*key
, size_t key_len
, const u8
*data
,
228 size_t data_len
, u8
*mac
)
230 return hmac_sha256_vector(key
, key_len
, 1, &data
, &data_len
, mac
);
233 #endif /* CONFIG_SHA256 */
238 int hmac_sha384_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
239 const u8
*addr
[], const size_t *len
, u8
*mac
)
241 return wolfssl_hmac_vector(WC_SHA384
, key
, key_len
, num_elem
, addr
, len
,
246 int hmac_sha384(const u8
*key
, size_t key_len
, const u8
*data
,
247 size_t data_len
, u8
*mac
)
249 return hmac_sha384_vector(key
, key_len
, 1, &data
, &data_len
, mac
);
252 #endif /* CONFIG_SHA384 */
257 int hmac_sha512_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
258 const u8
*addr
[], const size_t *len
, u8
*mac
)
260 return wolfssl_hmac_vector(WC_SHA512
, key
, key_len
, num_elem
, addr
, len
,
265 int hmac_sha512(const u8
*key
, size_t key_len
, const u8
*data
,
266 size_t data_len
, u8
*mac
)
268 return hmac_sha512_vector(key
, key_len
, 1, &data
, &data_len
, mac
);
271 #endif /* CONFIG_SHA512 */
274 int pbkdf2_sha1(const char *passphrase
, const u8
*ssid
, size_t ssid_len
,
275 int iterations
, u8
*buf
, size_t buflen
)
277 if (wc_PBKDF2(buf
, (const byte
*)passphrase
, os_strlen(passphrase
), ssid
,
278 ssid_len
, iterations
, buflen
, WC_SHA
) != 0)
285 int des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
288 u8 pkey
[8], next
, tmp
;
291 /* Add parity bits to the key */
293 for (i
= 0; i
< 7; i
++) {
295 pkey
[i
] = (tmp
>> i
) | next
| 1;
296 next
= tmp
<< (7 - i
);
300 wc_Des_SetKey(&des
, pkey
, NULL
, DES_ENCRYPTION
);
301 wc_Des_EcbEncrypt(&des
, cypher
, clear
, DES_BLOCK_SIZE
);
305 #endif /* CONFIG_DES */
308 void * aes_encrypt_init(const u8
*key
, size_t len
)
315 aes
= os_malloc(sizeof(Aes
));
319 if (wc_AesSetKey(aes
, key
, len
, NULL
, AES_ENCRYPTION
) < 0) {
328 int aes_encrypt(void *ctx
, const u8
*plain
, u8
*crypt
)
330 wc_AesEncryptDirect(ctx
, crypt
, plain
);
335 void aes_encrypt_deinit(void *ctx
)
341 void * aes_decrypt_init(const u8
*key
, size_t len
)
348 aes
= os_malloc(sizeof(Aes
));
352 if (wc_AesSetKey(aes
, key
, len
, NULL
, AES_DECRYPTION
) < 0) {
361 int aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
363 wc_AesDecryptDirect(ctx
, plain
, crypt
);
368 void aes_decrypt_deinit(void *ctx
)
374 int aes_128_cbc_encrypt(const u8
*key
, const u8
*iv
, u8
*data
, size_t data_len
)
382 ret
= wc_AesSetKey(&aes
, key
, 16, iv
, AES_ENCRYPTION
);
386 ret
= wc_AesCbcEncrypt(&aes
, data
, data
, data_len
);
393 int aes_128_cbc_decrypt(const u8
*key
, const u8
*iv
, u8
*data
, size_t data_len
)
401 ret
= wc_AesSetKey(&aes
, key
, 16, iv
, AES_DECRYPTION
);
405 ret
= wc_AesCbcDecrypt(&aes
, data
, data
, data_len
);
412 int aes_wrap(const u8
*kek
, size_t kek_len
, int n
, const u8
*plain
, u8
*cipher
)
419 ret
= wc_AesKeyWrap(kek
, kek_len
, plain
, n
* 8, cipher
, (n
+ 1) * 8,
421 return ret
!= (n
+ 1) * 8 ? -1 : 0;
425 int aes_unwrap(const u8
*kek
, size_t kek_len
, int n
, const u8
*cipher
,
433 ret
= wc_AesKeyUnWrap(kek
, kek_len
, cipher
, (n
+ 1) * 8, plain
, n
* 8,
435 return ret
!= n
* 8 ? -1 : 0;
439 #ifndef CONFIG_NO_RC4
440 int rc4_skip(const u8
*key
, size_t keylen
, size_t skip
, u8
*data
,
445 unsigned char skip_buf
[16];
447 wc_Arc4SetKey(&arc4
, key
, keylen
);
449 while (skip
>= sizeof(skip_buf
)) {
452 if (len
> sizeof(skip_buf
))
453 len
= sizeof(skip_buf
);
454 wc_Arc4Process(&arc4
, skip_buf
, skip_buf
, len
);
458 wc_Arc4Process(&arc4
, data
, data
, data_len
);
465 #endif /* CONFIG_NO_RC4 */
468 #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \
469 || defined(EAP_SERVER_IKEV2)
470 union wolfssl_cipher
{
476 struct crypto_cipher
{
477 enum crypto_cipher_alg alg
;
478 union wolfssl_cipher enc
;
479 union wolfssl_cipher dec
;
482 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
483 const u8
*iv
, const u8
*key
,
486 struct crypto_cipher
*ctx
;
488 ctx
= os_zalloc(sizeof(*ctx
));
493 #ifndef CONFIG_NO_RC4
495 case CRYPTO_CIPHER_ALG_RC4
:
496 wc_Arc4SetKey(&ctx
->enc
.arc4
, key
, key_len
);
497 wc_Arc4SetKey(&ctx
->dec
.arc4
, key
, key_len
);
500 #endif /* CONFIG_NO_RC4 */
502 case CRYPTO_CIPHER_ALG_AES
:
512 if (wc_AesSetKey(&ctx
->enc
.aes
, key
, key_len
, iv
,
514 wc_AesSetKey(&ctx
->dec
.aes
, key
, key_len
, iv
,
522 case CRYPTO_CIPHER_ALG_3DES
:
523 if (key_len
!= DES3_KEYLEN
||
524 wc_Des3_SetKey(&ctx
->enc
.des3
, key
, iv
, DES_ENCRYPTION
) ||
525 wc_Des3_SetKey(&ctx
->dec
.des3
, key
, iv
, DES_DECRYPTION
)) {
531 case CRYPTO_CIPHER_ALG_RC2
:
532 case CRYPTO_CIPHER_ALG_DES
:
544 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
545 u8
*crypt
, size_t len
)
548 #ifndef CONFIG_NO_RC4
550 case CRYPTO_CIPHER_ALG_RC4
:
551 wc_Arc4Process(&ctx
->enc
.arc4
, crypt
, plain
, len
);
554 #endif /* CONFIG_NO_RC4 */
556 case CRYPTO_CIPHER_ALG_AES
:
557 if (wc_AesCbcEncrypt(&ctx
->enc
.aes
, crypt
, plain
, len
) != 0)
562 case CRYPTO_CIPHER_ALG_3DES
:
563 if (wc_Des3_CbcEncrypt(&ctx
->enc
.des3
, crypt
, plain
, len
) != 0)
574 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
575 u8
*plain
, size_t len
)
578 #ifndef CONFIG_NO_RC4
580 case CRYPTO_CIPHER_ALG_RC4
:
581 wc_Arc4Process(&ctx
->dec
.arc4
, plain
, crypt
, len
);
584 #endif /* CONFIG_NO_RC4 */
586 case CRYPTO_CIPHER_ALG_AES
:
587 if (wc_AesCbcDecrypt(&ctx
->dec
.aes
, plain
, crypt
, len
) != 0)
592 case CRYPTO_CIPHER_ALG_3DES
:
593 if (wc_Des3_CbcDecrypt(&ctx
->dec
.des3
, plain
, crypt
, len
) != 0)
604 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
612 #ifdef CONFIG_WPS_NFC
614 static const unsigned char RFC3526_PRIME_1536
[] = {
615 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
616 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
617 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
618 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
619 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
620 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
621 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
622 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
623 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
624 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
625 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
626 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
627 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
628 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
629 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
630 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
633 static const unsigned char RFC3526_GENERATOR_1536
[] = {
637 #define RFC3526_LEN sizeof(RFC3526_PRIME_1536)
640 void * dh5_init(struct wpabuf
**priv
, struct wpabuf
**publ
)
645 struct wpabuf
*privkey
= NULL
;
646 struct wpabuf
*pubkey
= NULL
;
647 word32 priv_sz
, pub_sz
;
653 dh
= XMALLOC(sizeof(DhKey
), NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
658 if (wc_InitRng(&rng
) != 0) {
659 XFREE(dh
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
663 privkey
= wpabuf_alloc(RFC3526_LEN
);
664 pubkey
= wpabuf_alloc(RFC3526_LEN
);
665 if (!privkey
|| !pubkey
)
668 if (wc_DhSetKey(dh
, RFC3526_PRIME_1536
, sizeof(RFC3526_PRIME_1536
),
669 RFC3526_GENERATOR_1536
, sizeof(RFC3526_GENERATOR_1536
))
673 if (wc_DhGenerateKeyPair(dh
, &rng
, wpabuf_mhead(privkey
), &priv_sz
,
674 wpabuf_mhead(pubkey
), &pub_sz
) != 0)
677 wpabuf_put(privkey
, priv_sz
);
678 wpabuf_put(pubkey
, pub_sz
);
687 wpabuf_clear_free(pubkey
);
688 wpabuf_clear_free(privkey
);
691 XFREE(dh
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
698 void * dh5_init_fixed(const struct wpabuf
*priv
, const struct wpabuf
*publ
)
705 dh
= XMALLOC(sizeof(DhKey
), NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
710 secret
= XMALLOC(RFC3526_LEN
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
714 if (wc_DhSetKey(dh
, RFC3526_PRIME_1536
, sizeof(RFC3526_PRIME_1536
),
715 RFC3526_GENERATOR_1536
, sizeof(RFC3526_GENERATOR_1536
))
719 if (wc_DhAgree(dh
, secret
, &secret_sz
, wpabuf_head(priv
),
720 wpabuf_len(priv
), RFC3526_GENERATOR_1536
,
721 sizeof(RFC3526_GENERATOR_1536
)) != 0)
724 if (secret_sz
!= wpabuf_len(publ
) ||
725 os_memcmp(secret
, wpabuf_head(publ
), secret_sz
) != 0)
733 XFREE(dh
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
735 XFREE(secret
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
740 struct wpabuf
* dh5_derive_shared(void *ctx
, const struct wpabuf
*peer_public
,
741 const struct wpabuf
*own_private
)
743 struct wpabuf
*ret
= NULL
;
744 struct wpabuf
*secret
;
747 secret
= wpabuf_alloc(RFC3526_LEN
);
751 if (wc_DhAgree(ctx
, wpabuf_mhead(secret
), &secret_sz
,
752 wpabuf_head(own_private
), wpabuf_len(own_private
),
753 wpabuf_head(peer_public
), wpabuf_len(peer_public
)) != 0)
756 wpabuf_put(secret
, secret_sz
);
761 wpabuf_clear_free(secret
);
766 void dh5_free(void *ctx
)
772 XFREE(ctx
, NULL
, DYNAMIC_TYPE_TMP_BUFFER
);
775 #endif /* CONFIG_WPS_NFC */
778 int crypto_dh_init(u8 generator
, const u8
*prime
, size_t prime_len
, u8
*privkey
,
784 word32 priv_sz
, pub_sz
;
789 dh
= os_malloc(sizeof(DhKey
));
794 if (wc_InitRng(&rng
) != 0) {
799 if (wc_DhSetKey(dh
, prime
, prime_len
, &generator
, 1) != 0)
802 if (wc_DhGenerateKeyPair(dh
, &rng
, privkey
, &priv_sz
, pubkey
, &pub_sz
)
806 if (priv_sz
< prime_len
) {
807 size_t pad_sz
= prime_len
- priv_sz
;
809 os_memmove(privkey
+ pad_sz
, privkey
, priv_sz
);
810 os_memset(privkey
, 0, pad_sz
);
813 if (pub_sz
< prime_len
) {
814 size_t pad_sz
= prime_len
- pub_sz
;
816 os_memmove(pubkey
+ pad_sz
, pubkey
, pub_sz
);
817 os_memset(pubkey
, 0, pad_sz
);
828 int crypto_dh_derive_secret(u8 generator
, const u8
*prime
, size_t prime_len
,
829 const u8
*order
, size_t order_len
,
830 const u8
*privkey
, size_t privkey_len
,
831 const u8
*pubkey
, size_t pubkey_len
,
832 u8
*secret
, size_t *len
)
838 dh
= os_malloc(sizeof(DhKey
));
843 if (wc_DhSetKey(dh
, prime
, prime_len
, &generator
, 1) != 0)
846 if (wc_DhAgree(dh
, secret
, &secret_sz
, privkey
, privkey_len
, pubkey
,
860 int crypto_get_random(void *buf
, size_t len
)
865 if (wc_InitRng(&rng
) != 0)
867 if (wc_RNG_GenerateBlock(&rng
, buf
, len
) != 0)
872 #endif /* CONFIG_FIPS */
875 #if defined(EAP_PWD) || defined(EAP_SERVER_PWD)
882 struct crypto_hash
* crypto_hash_init(enum crypto_hash_alg alg
, const u8
*key
,
885 struct crypto_hash
*ret
= NULL
;
886 struct crypto_hash
*hash
;
889 hash
= os_zalloc(sizeof(*hash
));
895 case CRYPTO_HASH_ALG_HMAC_MD5
:
901 case CRYPTO_HASH_ALG_HMAC_SHA1
:
908 case CRYPTO_HASH_ALG_HMAC_SHA256
:
912 #endif /* NO_SHA256 */
913 #endif /* CONFIG_SHA256 */
918 if (wc_HmacSetKey(&hash
->hmac
, type
, key
, key_len
) != 0)
929 void crypto_hash_update(struct crypto_hash
*ctx
, const u8
*data
, size_t len
)
933 wc_HmacUpdate(&ctx
->hmac
, data
, len
);
937 int crypto_hash_finish(struct crypto_hash
*ctx
, u8
*mac
, size_t *len
)
947 if (wc_HmacFinal(&ctx
->hmac
, mac
) != 0) {
955 bin_clear_free(ctx
, sizeof(*ctx
));
964 int omac1_aes_vector(const u8
*key
, size_t key_len
, size_t num_elem
,
965 const u8
*addr
[], const size_t *len
, u8
*mac
)
974 if (wc_InitCmac(&cmac
, key
, key_len
, WC_CMAC_AES
, NULL
) != 0)
977 for (i
= 0; i
< num_elem
; i
++)
978 if (wc_CmacUpdate(&cmac
, addr
[i
], len
[i
]) != 0)
982 if (wc_CmacFinal(&cmac
, mac
, &sz
) != 0 || sz
!= AES_BLOCK_SIZE
)
989 int omac1_aes_128_vector(const u8
*key
, size_t num_elem
,
990 const u8
*addr
[], const size_t *len
, u8
*mac
)
992 return omac1_aes_vector(key
, 16, num_elem
, addr
, len
, mac
);
996 int omac1_aes_128(const u8
*key
, const u8
*data
, size_t data_len
, u8
*mac
)
998 return omac1_aes_128_vector(key
, 1, &data
, &data_len
, mac
);
1002 int omac1_aes_256(const u8
*key
, const u8
*data
, size_t data_len
, u8
*mac
)
1004 return omac1_aes_vector(key
, 32, 1, &data
, &data_len
, mac
);
1008 struct crypto_bignum
* crypto_bignum_init(void)
1015 a
= os_malloc(sizeof(*a
));
1016 if (!a
|| mp_init(a
) != MP_OKAY
) {
1021 return (struct crypto_bignum
*) a
;
1025 struct crypto_bignum
* crypto_bignum_init_set(const u8
*buf
, size_t len
)
1032 a
= (mp_int
*) crypto_bignum_init();
1036 if (mp_read_unsigned_bin(a
, buf
, len
) != MP_OKAY
) {
1041 return (struct crypto_bignum
*) a
;
1045 struct crypto_bignum
* crypto_bignum_init_uint(unsigned int val
)
1052 a
= (mp_int
*) crypto_bignum_init();
1056 if (mp_set_int(a
, val
) != MP_OKAY
) {
1061 return (struct crypto_bignum
*) a
;
1065 void crypto_bignum_deinit(struct crypto_bignum
*n
, int clear
)
1071 mp_forcezero((mp_int
*) n
);
1072 mp_clear((mp_int
*) n
);
1073 os_free((mp_int
*) n
);
1077 int crypto_bignum_to_bin(const struct crypto_bignum
*a
,
1078 u8
*buf
, size_t buflen
, size_t padlen
)
1080 int num_bytes
, offset
;
1085 if (padlen
> buflen
)
1088 num_bytes
= (mp_count_bits((mp_int
*) a
) + 7) / 8;
1089 if ((size_t) num_bytes
> buflen
)
1091 if (padlen
> (size_t) num_bytes
)
1092 offset
= padlen
- num_bytes
;
1096 os_memset(buf
, 0, offset
);
1097 mp_to_unsigned_bin((mp_int
*) a
, buf
+ offset
);
1099 return num_bytes
+ offset
;
1103 int crypto_bignum_rand(struct crypto_bignum
*r
, const struct crypto_bignum
*m
)
1110 if (wc_InitRng(&rng
) != 0)
1112 if (mp_rand_prime((mp_int
*) r
,
1113 (mp_count_bits((mp_int
*) m
) + 7) / 8 * 2,
1117 mp_mod((mp_int
*) r
, (mp_int
*) m
, (mp_int
*) r
) != 0)
1124 int crypto_bignum_add(const struct crypto_bignum
*a
,
1125 const struct crypto_bignum
*b
,
1126 struct crypto_bignum
*r
)
1128 return mp_add((mp_int
*) a
, (mp_int
*) b
,
1129 (mp_int
*) r
) == MP_OKAY
? 0 : -1;
1133 int crypto_bignum_mod(const struct crypto_bignum
*a
,
1134 const struct crypto_bignum
*m
,
1135 struct crypto_bignum
*r
)
1137 return mp_mod((mp_int
*) a
, (mp_int
*) m
,
1138 (mp_int
*) r
) == MP_OKAY
? 0 : -1;
1142 int crypto_bignum_exptmod(const struct crypto_bignum
*b
,
1143 const struct crypto_bignum
*e
,
1144 const struct crypto_bignum
*m
,
1145 struct crypto_bignum
*r
)
1150 return mp_exptmod((mp_int
*) b
, (mp_int
*) e
, (mp_int
*) m
,
1151 (mp_int
*) r
) == MP_OKAY
? 0 : -1;
1155 int crypto_bignum_inverse(const struct crypto_bignum
*a
,
1156 const struct crypto_bignum
*m
,
1157 struct crypto_bignum
*r
)
1162 return mp_invmod((mp_int
*) a
, (mp_int
*) m
,
1163 (mp_int
*) r
) == MP_OKAY
? 0 : -1;
1167 int crypto_bignum_sub(const struct crypto_bignum
*a
,
1168 const struct crypto_bignum
*b
,
1169 struct crypto_bignum
*r
)
1174 return mp_sub((mp_int
*) a
, (mp_int
*) b
,
1175 (mp_int
*) r
) == MP_OKAY
? 0 : -1;
1179 int crypto_bignum_div(const struct crypto_bignum
*a
,
1180 const struct crypto_bignum
*b
,
1181 struct crypto_bignum
*d
)
1186 return mp_div((mp_int
*) a
, (mp_int
*) b
, (mp_int
*) d
,
1187 NULL
) == MP_OKAY
? 0 : -1;
1191 int crypto_bignum_addmod(const struct crypto_bignum
*a
,
1192 const struct crypto_bignum
*b
,
1193 const struct crypto_bignum
*c
,
1194 struct crypto_bignum
*d
)
1199 return mp_addmod((mp_int
*) a
, (mp_int
*) b
, (mp_int
*) c
,
1200 (mp_int
*) d
) == MP_OKAY
? 0 : -1;
1204 int crypto_bignum_mulmod(const struct crypto_bignum
*a
,
1205 const struct crypto_bignum
*b
,
1206 const struct crypto_bignum
*m
,
1207 struct crypto_bignum
*d
)
1212 return mp_mulmod((mp_int
*) a
, (mp_int
*) b
, (mp_int
*) m
,
1213 (mp_int
*) d
) == MP_OKAY
? 0 : -1;
1217 int crypto_bignum_sqrmod(const struct crypto_bignum
*a
,
1218 const struct crypto_bignum
*b
,
1219 struct crypto_bignum
*c
)
1224 return mp_sqrmod((mp_int
*) a
, (mp_int
*) b
,
1225 (mp_int
*) c
) == MP_OKAY
? 0 : -1;
1229 int crypto_bignum_rshift(const struct crypto_bignum
*a
, int n
,
1230 struct crypto_bignum
*r
)
1232 if (mp_copy((mp_int
*) a
, (mp_int
*) r
) != MP_OKAY
)
1234 mp_rshb((mp_int
*) r
, n
);
1239 int crypto_bignum_cmp(const struct crypto_bignum
*a
,
1240 const struct crypto_bignum
*b
)
1242 return mp_cmp((mp_int
*) a
, (mp_int
*) b
);
1246 int crypto_bignum_is_zero(const struct crypto_bignum
*a
)
1248 return mp_iszero((mp_int
*) a
);
1252 int crypto_bignum_is_one(const struct crypto_bignum
*a
)
1254 return mp_isone((const mp_int
*) a
);
1257 int crypto_bignum_is_odd(const struct crypto_bignum
*a
)
1259 return mp_isodd((mp_int
*) a
);
1263 int crypto_bignum_legendre(const struct crypto_bignum
*a
,
1264 const struct crypto_bignum
*p
)
1273 if (mp_init(&t
) != MP_OKAY
)
1277 ret
= mp_sub_d((mp_int
*) p
, 1, &t
);
1281 ret
= mp_exptmod((mp_int
*) a
, &t
, (mp_int
*) p
, &t
);
1282 if (ret
== MP_OKAY
) {
1285 else if (mp_iszero(&t
))
1298 int ecc_map(ecc_point
*, mp_int
*, mp_digit
);
1299 int ecc_projective_add_point(ecc_point
*P
, ecc_point
*Q
, ecc_point
*R
,
1300 mp_int
*a
, mp_int
*modulus
, mp_digit mp
);
1312 struct crypto_ec
* crypto_ec_init(int group
)
1315 struct crypto_ec
*e
;
1318 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1321 curve_id
= ECC_SECP256R1
;
1324 curve_id
= ECC_SECP384R1
;
1327 curve_id
= ECC_SECP521R1
;
1330 curve_id
= ECC_SECP192R1
;
1333 curve_id
= ECC_SECP224R1
;
1335 #ifdef HAVE_ECC_BRAINPOOL
1337 curve_id
= ECC_BRAINPOOLP224R1
;
1340 curve_id
= ECC_BRAINPOOLP256R1
;
1343 curve_id
= ECC_BRAINPOOLP384R1
;
1346 curve_id
= ECC_BRAINPOOLP512R1
;
1348 #endif /* HAVE_ECC_BRAINPOOL */
1353 e
= os_zalloc(sizeof(*e
));
1357 if (wc_ecc_init(&e
->key
) != 0 ||
1358 wc_ecc_set_curve(&e
->key
, 0, curve_id
) != 0 ||
1359 mp_init(&e
->a
) != MP_OKAY
||
1360 mp_init(&e
->prime
) != MP_OKAY
||
1361 mp_init(&e
->order
) != MP_OKAY
||
1362 mp_init(&e
->b
) != MP_OKAY
||
1363 mp_read_radix(&e
->a
, e
->key
.dp
->Af
, 16) != MP_OKAY
||
1364 mp_read_radix(&e
->b
, e
->key
.dp
->Bf
, 16) != MP_OKAY
||
1365 mp_read_radix(&e
->prime
, e
->key
.dp
->prime
, 16) != MP_OKAY
||
1366 mp_read_radix(&e
->order
, e
->key
.dp
->order
, 16) != MP_OKAY
||
1367 mp_montgomery_setup(&e
->prime
, &e
->mont_b
) != MP_OKAY
)
1373 crypto_ec_deinit(e
);
1380 void crypto_ec_deinit(struct crypto_ec
* e
)
1386 mp_clear(&e
->order
);
1387 mp_clear(&e
->prime
);
1389 wc_ecc_free(&e
->key
);
1394 struct crypto_ec_point
* crypto_ec_point_init(struct crypto_ec
*e
)
1400 return (struct crypto_ec_point
*) wc_ecc_new_point();
1404 size_t crypto_ec_prime_len(struct crypto_ec
*e
)
1406 return (mp_count_bits(&e
->prime
) + 7) / 8;
1410 size_t crypto_ec_prime_len_bits(struct crypto_ec
*e
)
1412 return mp_count_bits(&e
->prime
);
1416 size_t crypto_ec_order_len(struct crypto_ec
*e
)
1418 return (mp_count_bits(&e
->order
) + 7) / 8;
1422 const struct crypto_bignum
* crypto_ec_get_prime(struct crypto_ec
*e
)
1424 return (const struct crypto_bignum
*) &e
->prime
;
1428 const struct crypto_bignum
* crypto_ec_get_order(struct crypto_ec
*e
)
1430 return (const struct crypto_bignum
*) &e
->order
;
1434 const struct crypto_bignum
* crypto_ec_get_a(struct crypto_ec
*e
)
1436 return (const struct crypto_bignum
*) &e
->a
;
1440 const struct crypto_bignum
* crypto_ec_get_b(struct crypto_ec
*e
)
1442 return (const struct crypto_bignum
*) &e
->b
;
1446 void crypto_ec_point_deinit(struct crypto_ec_point
*p
, int clear
)
1448 ecc_point
*point
= (ecc_point
*) p
;
1454 mp_forcezero(point
->x
);
1455 mp_forcezero(point
->y
);
1456 mp_forcezero(point
->z
);
1458 wc_ecc_del_point(point
);
1462 int crypto_ec_point_x(struct crypto_ec
*e
, const struct crypto_ec_point
*p
,
1463 struct crypto_bignum
*x
)
1465 return mp_copy(((ecc_point
*) p
)->x
, (mp_int
*) x
) == MP_OKAY
? 0 : -1;
1469 int crypto_ec_point_to_bin(struct crypto_ec
*e
,
1470 const struct crypto_ec_point
*point
, u8
*x
, u8
*y
)
1472 ecc_point
*p
= (ecc_point
*) point
;
1477 if (!mp_isone(p
->z
)) {
1478 if (ecc_map(p
, &e
->prime
, e
->mont_b
) != MP_OKAY
)
1483 if (crypto_bignum_to_bin((struct crypto_bignum
*)p
->x
, x
,
1485 e
->key
.dp
->size
) <= 0)
1490 if (crypto_bignum_to_bin((struct crypto_bignum
*) p
->y
, y
,
1492 e
->key
.dp
->size
) <= 0)
1500 struct crypto_ec_point
* crypto_ec_point_from_bin(struct crypto_ec
*e
,
1503 ecc_point
*point
= NULL
;
1509 point
= wc_ecc_new_point();
1513 if (mp_read_unsigned_bin(point
->x
, val
, e
->key
.dp
->size
) != MP_OKAY
)
1515 val
+= e
->key
.dp
->size
;
1516 if (mp_read_unsigned_bin(point
->y
, val
, e
->key
.dp
->size
) != MP_OKAY
)
1518 mp_set(point
->z
, 1);
1523 wc_ecc_del_point(point
);
1526 return (struct crypto_ec_point
*) point
;
1530 int crypto_ec_point_add(struct crypto_ec
*e
, const struct crypto_ec_point
*a
,
1531 const struct crypto_ec_point
*b
,
1532 struct crypto_ec_point
*c
)
1535 ecc_point
*ta
= NULL
, *tb
= NULL
;
1536 ecc_point
*pa
= (ecc_point
*) a
, *pb
= (ecc_point
*) b
;
1537 mp_int
*modulus
= &e
->prime
;
1547 ret
= mp_montgomery_calc_normalization(&mu
, modulus
);
1548 if (ret
!= MP_OKAY
) {
1553 if (!mp_isone(&mu
)) {
1554 ta
= wc_ecc_new_point();
1559 tb
= wc_ecc_new_point();
1561 wc_ecc_del_point(ta
);
1566 if (mp_mulmod(pa
->x
, &mu
, modulus
, ta
->x
) != MP_OKAY
||
1567 mp_mulmod(pa
->y
, &mu
, modulus
, ta
->y
) != MP_OKAY
||
1568 mp_mulmod(pa
->z
, &mu
, modulus
, ta
->z
) != MP_OKAY
||
1569 mp_mulmod(pb
->x
, &mu
, modulus
, tb
->x
) != MP_OKAY
||
1570 mp_mulmod(pb
->y
, &mu
, modulus
, tb
->y
) != MP_OKAY
||
1571 mp_mulmod(pb
->z
, &mu
, modulus
, tb
->z
) != MP_OKAY
) {
1579 ret
= ecc_projective_add_point(pa
, pb
, (ecc_point
*) c
, &e
->a
,
1580 &e
->prime
, e
->mont_b
);
1586 if (ecc_map((ecc_point
*) c
, &e
->prime
, e
->mont_b
) != MP_OKAY
)
1591 wc_ecc_del_point(tb
);
1592 wc_ecc_del_point(ta
);
1598 int crypto_ec_point_mul(struct crypto_ec
*e
, const struct crypto_ec_point
*p
,
1599 const struct crypto_bignum
*b
,
1600 struct crypto_ec_point
*res
)
1607 ret
= wc_ecc_mulmod((mp_int
*) b
, (ecc_point
*) p
, (ecc_point
*) res
,
1608 &e
->a
, &e
->prime
, 1);
1609 return ret
== 0 ? 0 : -1;
1613 int crypto_ec_point_invert(struct crypto_ec
*e
, struct crypto_ec_point
*p
)
1615 ecc_point
*point
= (ecc_point
*) p
;
1620 if (mp_sub(&e
->prime
, point
->y
, point
->y
) != MP_OKAY
)
1627 int crypto_ec_point_solve_y_coord(struct crypto_ec
*e
,
1628 struct crypto_ec_point
*p
,
1629 const struct crypto_bignum
*x
, int y_bit
)
1631 byte buf
[1 + 2 * MAX_ECC_BYTES
];
1633 int prime_len
= crypto_ec_prime_len(e
);
1638 buf
[0] = y_bit
? ECC_POINT_COMP_ODD
: ECC_POINT_COMP_EVEN
;
1639 ret
= crypto_bignum_to_bin(x
, buf
+ 1, prime_len
, prime_len
);
1642 ret
= wc_ecc_import_point_der(buf
, 1 + 2 * ret
, e
->key
.idx
,
1651 struct crypto_bignum
*
1652 crypto_ec_point_compute_y_sqr(struct crypto_ec
*e
,
1653 const struct crypto_bignum
*x
)
1662 if (mp_init(&t
) != MP_OKAY
)
1665 y2
= (mp_int
*) crypto_bignum_init();
1669 if (mp_sqrmod((mp_int
*) x
, &e
->prime
, y2
) != 0 ||
1670 mp_mulmod((mp_int
*) x
, y2
, &e
->prime
, y2
) != 0 ||
1671 mp_mulmod((mp_int
*) x
, &e
->a
, &e
->prime
, &t
) != 0 ||
1672 mp_addmod(y2
, &t
, &e
->prime
, y2
) != 0 ||
1673 mp_addmod(y2
, &e
->b
, &e
->prime
, y2
) != 0)
1686 return (struct crypto_bignum
*) y2
;
1690 int crypto_ec_point_is_at_infinity(struct crypto_ec
*e
,
1691 const struct crypto_ec_point
*p
)
1693 return wc_ecc_point_is_at_infinity((ecc_point
*) p
);
1697 int crypto_ec_point_is_on_curve(struct crypto_ec
*e
,
1698 const struct crypto_ec_point
*p
)
1700 return wc_ecc_is_point((ecc_point
*) p
, &e
->a
, &e
->b
, &e
->prime
) ==
1705 int crypto_ec_point_cmp(const struct crypto_ec
*e
,
1706 const struct crypto_ec_point
*a
,
1707 const struct crypto_ec_point
*b
)
1709 return wc_ecc_cmp_point((ecc_point
*) a
, (ecc_point
*) b
);
1713 struct crypto_ecdh
{
1714 struct crypto_ec
*ec
;
1717 struct crypto_ecdh
* crypto_ecdh_init(int group
)
1719 struct crypto_ecdh
*ecdh
= NULL
;
1723 if (wc_InitRng(&rng
) != 0)
1726 ecdh
= os_zalloc(sizeof(*ecdh
));
1730 ecdh
->ec
= crypto_ec_init(group
);
1734 ret
= wc_ecc_make_key_ex(&rng
, ecdh
->ec
->key
.dp
->size
, &ecdh
->ec
->key
,
1735 ecdh
->ec
->key
.dp
->id
);
1744 crypto_ecdh_deinit(ecdh
);
1750 void crypto_ecdh_deinit(struct crypto_ecdh
*ecdh
)
1753 crypto_ec_deinit(ecdh
->ec
);
1759 struct wpabuf
* crypto_ecdh_get_pubkey(struct crypto_ecdh
*ecdh
, int inc_y
)
1761 struct wpabuf
*buf
= NULL
;
1763 int len
= ecdh
->ec
->key
.dp
->size
;
1765 buf
= wpabuf_alloc(inc_y
? 2 * len
: len
);
1769 ret
= crypto_bignum_to_bin((struct crypto_bignum
*)
1770 ecdh
->ec
->key
.pubkey
.x
, wpabuf_put(buf
, len
),
1775 ret
= crypto_bignum_to_bin((struct crypto_bignum
*)
1776 ecdh
->ec
->key
.pubkey
.y
,
1777 wpabuf_put(buf
, len
), len
, len
);
1791 struct wpabuf
* crypto_ecdh_set_peerkey(struct crypto_ecdh
*ecdh
, int inc_y
,
1792 const u8
*key
, size_t len
)
1795 struct wpabuf
*pubkey
= NULL
;
1796 struct wpabuf
*secret
= NULL
;
1797 word32 key_len
= ecdh
->ec
->key
.dp
->size
;
1798 ecc_point
*point
= NULL
;
1799 size_t need_key_len
= inc_y
? 2 * key_len
: key_len
;
1801 if (len
< need_key_len
)
1803 pubkey
= wpabuf_alloc(1 + 2 * key_len
);
1806 wpabuf_put_u8(pubkey
, inc_y
? ECC_POINT_UNCOMP
: ECC_POINT_COMP_EVEN
);
1807 wpabuf_put_data(pubkey
, key
, need_key_len
);
1809 point
= wc_ecc_new_point();
1813 ret
= wc_ecc_import_point_der(wpabuf_mhead(pubkey
), 1 + 2 * key_len
,
1814 ecdh
->ec
->key
.idx
, point
);
1818 secret
= wpabuf_alloc(key_len
);
1822 ret
= wc_ecc_shared_secret_ex(&ecdh
->ec
->key
, point
,
1823 wpabuf_put(secret
, key_len
), &key_len
);
1828 wc_ecc_del_point(point
);
1829 wpabuf_free(pubkey
);
1832 wpabuf_free(secret
);
1837 #endif /* CONFIG_ECC */