1*85732ac8SCy Schubert /* 2*85732ac8SCy Schubert * Wrapper functions for libwolfssl 3*85732ac8SCy Schubert * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi> 4*85732ac8SCy Schubert * 5*85732ac8SCy Schubert * This software may be distributed under the terms of the BSD license. 6*85732ac8SCy Schubert * See README for more details. 7*85732ac8SCy Schubert */ 8*85732ac8SCy Schubert 9*85732ac8SCy Schubert #include "includes.h" 10*85732ac8SCy Schubert 11*85732ac8SCy Schubert #include "common.h" 12*85732ac8SCy Schubert #include "crypto.h" 13*85732ac8SCy Schubert 14*85732ac8SCy Schubert /* wolfSSL headers */ 15*85732ac8SCy Schubert #include <wolfssl/options.h> 16*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/md4.h> 17*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/md5.h> 18*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/sha.h> 19*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/sha256.h> 20*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/sha512.h> 21*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/hmac.h> 22*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/pwdbased.h> 23*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/arc4.h> 24*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/des3.h> 25*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/aes.h> 26*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/dh.h> 27*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/cmac.h> 28*85732ac8SCy Schubert #include <wolfssl/wolfcrypt/ecc.h> 29*85732ac8SCy Schubert #include <wolfssl/openssl/bn.h> 30*85732ac8SCy Schubert 31*85732ac8SCy Schubert 32*85732ac8SCy Schubert #ifndef CONFIG_FIPS 33*85732ac8SCy Schubert 34*85732ac8SCy Schubert int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 35*85732ac8SCy Schubert { 36*85732ac8SCy Schubert Md4 md4; 37*85732ac8SCy Schubert size_t i; 38*85732ac8SCy Schubert 39*85732ac8SCy Schubert if (TEST_FAIL()) 40*85732ac8SCy Schubert return -1; 41*85732ac8SCy Schubert 42*85732ac8SCy Schubert wc_InitMd4(&md4); 43*85732ac8SCy Schubert 44*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 45*85732ac8SCy Schubert wc_Md4Update(&md4, addr[i], len[i]); 46*85732ac8SCy Schubert 47*85732ac8SCy Schubert wc_Md4Final(&md4, mac); 48*85732ac8SCy Schubert 49*85732ac8SCy Schubert return 0; 50*85732ac8SCy Schubert } 51*85732ac8SCy Schubert 52*85732ac8SCy Schubert 53*85732ac8SCy Schubert int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 54*85732ac8SCy Schubert { 55*85732ac8SCy Schubert wc_Md5 md5; 56*85732ac8SCy Schubert size_t i; 57*85732ac8SCy Schubert 58*85732ac8SCy Schubert if (TEST_FAIL()) 59*85732ac8SCy Schubert return -1; 60*85732ac8SCy Schubert 61*85732ac8SCy Schubert wc_InitMd5(&md5); 62*85732ac8SCy Schubert 63*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 64*85732ac8SCy Schubert wc_Md5Update(&md5, addr[i], len[i]); 65*85732ac8SCy Schubert 66*85732ac8SCy Schubert wc_Md5Final(&md5, mac); 67*85732ac8SCy Schubert 68*85732ac8SCy Schubert return 0; 69*85732ac8SCy Schubert } 70*85732ac8SCy Schubert 71*85732ac8SCy Schubert #endif /* CONFIG_FIPS */ 72*85732ac8SCy Schubert 73*85732ac8SCy Schubert 74*85732ac8SCy Schubert int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 75*85732ac8SCy Schubert { 76*85732ac8SCy Schubert wc_Sha sha; 77*85732ac8SCy Schubert size_t i; 78*85732ac8SCy Schubert 79*85732ac8SCy Schubert if (TEST_FAIL()) 80*85732ac8SCy Schubert return -1; 81*85732ac8SCy Schubert 82*85732ac8SCy Schubert wc_InitSha(&sha); 83*85732ac8SCy Schubert 84*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 85*85732ac8SCy Schubert wc_ShaUpdate(&sha, addr[i], len[i]); 86*85732ac8SCy Schubert 87*85732ac8SCy Schubert wc_ShaFinal(&sha, mac); 88*85732ac8SCy Schubert 89*85732ac8SCy Schubert return 0; 90*85732ac8SCy Schubert } 91*85732ac8SCy Schubert 92*85732ac8SCy Schubert 93*85732ac8SCy Schubert #ifndef NO_SHA256_WRAPPER 94*85732ac8SCy Schubert int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, 95*85732ac8SCy Schubert u8 *mac) 96*85732ac8SCy Schubert { 97*85732ac8SCy Schubert wc_Sha256 sha256; 98*85732ac8SCy Schubert size_t i; 99*85732ac8SCy Schubert 100*85732ac8SCy Schubert if (TEST_FAIL()) 101*85732ac8SCy Schubert return -1; 102*85732ac8SCy Schubert 103*85732ac8SCy Schubert wc_InitSha256(&sha256); 104*85732ac8SCy Schubert 105*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 106*85732ac8SCy Schubert wc_Sha256Update(&sha256, addr[i], len[i]); 107*85732ac8SCy Schubert 108*85732ac8SCy Schubert wc_Sha256Final(&sha256, mac); 109*85732ac8SCy Schubert 110*85732ac8SCy Schubert return 0; 111*85732ac8SCy Schubert } 112*85732ac8SCy Schubert #endif /* NO_SHA256_WRAPPER */ 113*85732ac8SCy Schubert 114*85732ac8SCy Schubert 115*85732ac8SCy Schubert #ifdef CONFIG_SHA384 116*85732ac8SCy Schubert int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, 117*85732ac8SCy Schubert u8 *mac) 118*85732ac8SCy Schubert { 119*85732ac8SCy Schubert wc_Sha384 sha384; 120*85732ac8SCy Schubert size_t i; 121*85732ac8SCy Schubert 122*85732ac8SCy Schubert if (TEST_FAIL()) 123*85732ac8SCy Schubert return -1; 124*85732ac8SCy Schubert 125*85732ac8SCy Schubert wc_InitSha384(&sha384); 126*85732ac8SCy Schubert 127*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 128*85732ac8SCy Schubert wc_Sha384Update(&sha384, addr[i], len[i]); 129*85732ac8SCy Schubert 130*85732ac8SCy Schubert wc_Sha384Final(&sha384, mac); 131*85732ac8SCy Schubert 132*85732ac8SCy Schubert return 0; 133*85732ac8SCy Schubert } 134*85732ac8SCy Schubert #endif /* CONFIG_SHA384 */ 135*85732ac8SCy Schubert 136*85732ac8SCy Schubert 137*85732ac8SCy Schubert #ifdef CONFIG_SHA512 138*85732ac8SCy Schubert int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, 139*85732ac8SCy Schubert u8 *mac) 140*85732ac8SCy Schubert { 141*85732ac8SCy Schubert wc_Sha512 sha512; 142*85732ac8SCy Schubert size_t i; 143*85732ac8SCy Schubert 144*85732ac8SCy Schubert if (TEST_FAIL()) 145*85732ac8SCy Schubert return -1; 146*85732ac8SCy Schubert 147*85732ac8SCy Schubert wc_InitSha512(&sha512); 148*85732ac8SCy Schubert 149*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 150*85732ac8SCy Schubert wc_Sha512Update(&sha512, addr[i], len[i]); 151*85732ac8SCy Schubert 152*85732ac8SCy Schubert wc_Sha512Final(&sha512, mac); 153*85732ac8SCy Schubert 154*85732ac8SCy Schubert return 0; 155*85732ac8SCy Schubert } 156*85732ac8SCy Schubert #endif /* CONFIG_SHA512 */ 157*85732ac8SCy Schubert 158*85732ac8SCy Schubert 159*85732ac8SCy Schubert static int wolfssl_hmac_vector(int type, const u8 *key, 160*85732ac8SCy Schubert size_t key_len, size_t num_elem, 161*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac, 162*85732ac8SCy Schubert unsigned int mdlen) 163*85732ac8SCy Schubert { 164*85732ac8SCy Schubert Hmac hmac; 165*85732ac8SCy Schubert size_t i; 166*85732ac8SCy Schubert 167*85732ac8SCy Schubert (void) mdlen; 168*85732ac8SCy Schubert 169*85732ac8SCy Schubert if (TEST_FAIL()) 170*85732ac8SCy Schubert return -1; 171*85732ac8SCy Schubert 172*85732ac8SCy Schubert if (wc_HmacSetKey(&hmac, type, key, (word32) key_len) != 0) 173*85732ac8SCy Schubert return -1; 174*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 175*85732ac8SCy Schubert if (wc_HmacUpdate(&hmac, addr[i], len[i]) != 0) 176*85732ac8SCy Schubert return -1; 177*85732ac8SCy Schubert if (wc_HmacFinal(&hmac, mac) != 0) 178*85732ac8SCy Schubert return -1; 179*85732ac8SCy Schubert return 0; 180*85732ac8SCy Schubert } 181*85732ac8SCy Schubert 182*85732ac8SCy Schubert 183*85732ac8SCy Schubert #ifndef CONFIG_FIPS 184*85732ac8SCy Schubert 185*85732ac8SCy Schubert int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem, 186*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 187*85732ac8SCy Schubert { 188*85732ac8SCy Schubert return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len, 189*85732ac8SCy Schubert mac, 16); 190*85732ac8SCy Schubert } 191*85732ac8SCy Schubert 192*85732ac8SCy Schubert 193*85732ac8SCy Schubert int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 194*85732ac8SCy Schubert u8 *mac) 195*85732ac8SCy Schubert { 196*85732ac8SCy Schubert return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac); 197*85732ac8SCy Schubert } 198*85732ac8SCy Schubert 199*85732ac8SCy Schubert #endif /* CONFIG_FIPS */ 200*85732ac8SCy Schubert 201*85732ac8SCy Schubert 202*85732ac8SCy Schubert int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem, 203*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 204*85732ac8SCy Schubert { 205*85732ac8SCy Schubert return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len, 206*85732ac8SCy Schubert mac, 20); 207*85732ac8SCy Schubert } 208*85732ac8SCy Schubert 209*85732ac8SCy Schubert 210*85732ac8SCy Schubert int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len, 211*85732ac8SCy Schubert u8 *mac) 212*85732ac8SCy Schubert { 213*85732ac8SCy Schubert return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac); 214*85732ac8SCy Schubert } 215*85732ac8SCy Schubert 216*85732ac8SCy Schubert 217*85732ac8SCy Schubert #ifdef CONFIG_SHA256 218*85732ac8SCy Schubert 219*85732ac8SCy Schubert int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem, 220*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 221*85732ac8SCy Schubert { 222*85732ac8SCy Schubert return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len, 223*85732ac8SCy Schubert mac, 32); 224*85732ac8SCy Schubert } 225*85732ac8SCy Schubert 226*85732ac8SCy Schubert 227*85732ac8SCy Schubert int hmac_sha256(const u8 *key, size_t key_len, const u8 *data, 228*85732ac8SCy Schubert size_t data_len, u8 *mac) 229*85732ac8SCy Schubert { 230*85732ac8SCy Schubert return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac); 231*85732ac8SCy Schubert } 232*85732ac8SCy Schubert 233*85732ac8SCy Schubert #endif /* CONFIG_SHA256 */ 234*85732ac8SCy Schubert 235*85732ac8SCy Schubert 236*85732ac8SCy Schubert #ifdef CONFIG_SHA384 237*85732ac8SCy Schubert 238*85732ac8SCy Schubert int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem, 239*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 240*85732ac8SCy Schubert { 241*85732ac8SCy Schubert return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len, 242*85732ac8SCy Schubert mac, 48); 243*85732ac8SCy Schubert } 244*85732ac8SCy Schubert 245*85732ac8SCy Schubert 246*85732ac8SCy Schubert int hmac_sha384(const u8 *key, size_t key_len, const u8 *data, 247*85732ac8SCy Schubert size_t data_len, u8 *mac) 248*85732ac8SCy Schubert { 249*85732ac8SCy Schubert return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac); 250*85732ac8SCy Schubert } 251*85732ac8SCy Schubert 252*85732ac8SCy Schubert #endif /* CONFIG_SHA384 */ 253*85732ac8SCy Schubert 254*85732ac8SCy Schubert 255*85732ac8SCy Schubert #ifdef CONFIG_SHA512 256*85732ac8SCy Schubert 257*85732ac8SCy Schubert int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem, 258*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 259*85732ac8SCy Schubert { 260*85732ac8SCy Schubert return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len, 261*85732ac8SCy Schubert mac, 64); 262*85732ac8SCy Schubert } 263*85732ac8SCy Schubert 264*85732ac8SCy Schubert 265*85732ac8SCy Schubert int hmac_sha512(const u8 *key, size_t key_len, const u8 *data, 266*85732ac8SCy Schubert size_t data_len, u8 *mac) 267*85732ac8SCy Schubert { 268*85732ac8SCy Schubert return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac); 269*85732ac8SCy Schubert } 270*85732ac8SCy Schubert 271*85732ac8SCy Schubert #endif /* CONFIG_SHA512 */ 272*85732ac8SCy Schubert 273*85732ac8SCy Schubert 274*85732ac8SCy Schubert int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len, 275*85732ac8SCy Schubert int iterations, u8 *buf, size_t buflen) 276*85732ac8SCy Schubert { 277*85732ac8SCy Schubert if (wc_PBKDF2(buf, (const byte*)passphrase, os_strlen(passphrase), ssid, 278*85732ac8SCy Schubert ssid_len, iterations, buflen, WC_SHA) != 0) 279*85732ac8SCy Schubert return -1; 280*85732ac8SCy Schubert return 0; 281*85732ac8SCy Schubert } 282*85732ac8SCy Schubert 283*85732ac8SCy Schubert 284*85732ac8SCy Schubert #ifdef CONFIG_DES 285*85732ac8SCy Schubert int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 286*85732ac8SCy Schubert { 287*85732ac8SCy Schubert Des des; 288*85732ac8SCy Schubert u8 pkey[8], next, tmp; 289*85732ac8SCy Schubert int i; 290*85732ac8SCy Schubert 291*85732ac8SCy Schubert /* Add parity bits to the key */ 292*85732ac8SCy Schubert next = 0; 293*85732ac8SCy Schubert for (i = 0; i < 7; i++) { 294*85732ac8SCy Schubert tmp = key[i]; 295*85732ac8SCy Schubert pkey[i] = (tmp >> i) | next | 1; 296*85732ac8SCy Schubert next = tmp << (7 - i); 297*85732ac8SCy Schubert } 298*85732ac8SCy Schubert pkey[i] = next | 1; 299*85732ac8SCy Schubert 300*85732ac8SCy Schubert wc_Des_SetKey(&des, pkey, NULL, DES_ENCRYPTION); 301*85732ac8SCy Schubert wc_Des_EcbEncrypt(&des, cypher, clear, DES_BLOCK_SIZE); 302*85732ac8SCy Schubert 303*85732ac8SCy Schubert return 0; 304*85732ac8SCy Schubert } 305*85732ac8SCy Schubert #endif /* CONFIG_DES */ 306*85732ac8SCy Schubert 307*85732ac8SCy Schubert 308*85732ac8SCy Schubert void * aes_encrypt_init(const u8 *key, size_t len) 309*85732ac8SCy Schubert { 310*85732ac8SCy Schubert Aes *aes; 311*85732ac8SCy Schubert 312*85732ac8SCy Schubert if (TEST_FAIL()) 313*85732ac8SCy Schubert return NULL; 314*85732ac8SCy Schubert 315*85732ac8SCy Schubert aes = os_malloc(sizeof(Aes)); 316*85732ac8SCy Schubert if (!aes) 317*85732ac8SCy Schubert return NULL; 318*85732ac8SCy Schubert 319*85732ac8SCy Schubert if (wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION) < 0) { 320*85732ac8SCy Schubert os_free(aes); 321*85732ac8SCy Schubert return NULL; 322*85732ac8SCy Schubert } 323*85732ac8SCy Schubert 324*85732ac8SCy Schubert return aes; 325*85732ac8SCy Schubert } 326*85732ac8SCy Schubert 327*85732ac8SCy Schubert 328*85732ac8SCy Schubert int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 329*85732ac8SCy Schubert { 330*85732ac8SCy Schubert wc_AesEncryptDirect(ctx, crypt, plain); 331*85732ac8SCy Schubert return 0; 332*85732ac8SCy Schubert } 333*85732ac8SCy Schubert 334*85732ac8SCy Schubert 335*85732ac8SCy Schubert void aes_encrypt_deinit(void *ctx) 336*85732ac8SCy Schubert { 337*85732ac8SCy Schubert os_free(ctx); 338*85732ac8SCy Schubert } 339*85732ac8SCy Schubert 340*85732ac8SCy Schubert 341*85732ac8SCy Schubert void * aes_decrypt_init(const u8 *key, size_t len) 342*85732ac8SCy Schubert { 343*85732ac8SCy Schubert Aes *aes; 344*85732ac8SCy Schubert 345*85732ac8SCy Schubert if (TEST_FAIL()) 346*85732ac8SCy Schubert return NULL; 347*85732ac8SCy Schubert 348*85732ac8SCy Schubert aes = os_malloc(sizeof(Aes)); 349*85732ac8SCy Schubert if (!aes) 350*85732ac8SCy Schubert return NULL; 351*85732ac8SCy Schubert 352*85732ac8SCy Schubert if (wc_AesSetKey(aes, key, len, NULL, AES_DECRYPTION) < 0) { 353*85732ac8SCy Schubert os_free(aes); 354*85732ac8SCy Schubert return NULL; 355*85732ac8SCy Schubert } 356*85732ac8SCy Schubert 357*85732ac8SCy Schubert return aes; 358*85732ac8SCy Schubert } 359*85732ac8SCy Schubert 360*85732ac8SCy Schubert 361*85732ac8SCy Schubert int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 362*85732ac8SCy Schubert { 363*85732ac8SCy Schubert wc_AesDecryptDirect(ctx, plain, crypt); 364*85732ac8SCy Schubert return 0; 365*85732ac8SCy Schubert } 366*85732ac8SCy Schubert 367*85732ac8SCy Schubert 368*85732ac8SCy Schubert void aes_decrypt_deinit(void *ctx) 369*85732ac8SCy Schubert { 370*85732ac8SCy Schubert os_free(ctx); 371*85732ac8SCy Schubert } 372*85732ac8SCy Schubert 373*85732ac8SCy Schubert 374*85732ac8SCy Schubert int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 375*85732ac8SCy Schubert { 376*85732ac8SCy Schubert Aes aes; 377*85732ac8SCy Schubert int ret; 378*85732ac8SCy Schubert 379*85732ac8SCy Schubert if (TEST_FAIL()) 380*85732ac8SCy Schubert return -1; 381*85732ac8SCy Schubert 382*85732ac8SCy Schubert ret = wc_AesSetKey(&aes, key, 16, iv, AES_ENCRYPTION); 383*85732ac8SCy Schubert if (ret != 0) 384*85732ac8SCy Schubert return -1; 385*85732ac8SCy Schubert 386*85732ac8SCy Schubert ret = wc_AesCbcEncrypt(&aes, data, data, data_len); 387*85732ac8SCy Schubert if (ret != 0) 388*85732ac8SCy Schubert return -1; 389*85732ac8SCy Schubert return 0; 390*85732ac8SCy Schubert } 391*85732ac8SCy Schubert 392*85732ac8SCy Schubert 393*85732ac8SCy Schubert int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len) 394*85732ac8SCy Schubert { 395*85732ac8SCy Schubert Aes aes; 396*85732ac8SCy Schubert int ret; 397*85732ac8SCy Schubert 398*85732ac8SCy Schubert if (TEST_FAIL()) 399*85732ac8SCy Schubert return -1; 400*85732ac8SCy Schubert 401*85732ac8SCy Schubert ret = wc_AesSetKey(&aes, key, 16, iv, AES_DECRYPTION); 402*85732ac8SCy Schubert if (ret != 0) 403*85732ac8SCy Schubert return -1; 404*85732ac8SCy Schubert 405*85732ac8SCy Schubert ret = wc_AesCbcDecrypt(&aes, data, data, data_len); 406*85732ac8SCy Schubert if (ret != 0) 407*85732ac8SCy Schubert return -1; 408*85732ac8SCy Schubert return 0; 409*85732ac8SCy Schubert } 410*85732ac8SCy Schubert 411*85732ac8SCy Schubert 412*85732ac8SCy Schubert int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher) 413*85732ac8SCy Schubert { 414*85732ac8SCy Schubert int ret; 415*85732ac8SCy Schubert 416*85732ac8SCy Schubert if (TEST_FAIL()) 417*85732ac8SCy Schubert return -1; 418*85732ac8SCy Schubert 419*85732ac8SCy Schubert ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8, 420*85732ac8SCy Schubert NULL); 421*85732ac8SCy Schubert return ret != (n + 1) * 8 ? -1 : 0; 422*85732ac8SCy Schubert } 423*85732ac8SCy Schubert 424*85732ac8SCy Schubert 425*85732ac8SCy Schubert int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher, 426*85732ac8SCy Schubert u8 *plain) 427*85732ac8SCy Schubert { 428*85732ac8SCy Schubert int ret; 429*85732ac8SCy Schubert 430*85732ac8SCy Schubert if (TEST_FAIL()) 431*85732ac8SCy Schubert return -1; 432*85732ac8SCy Schubert 433*85732ac8SCy Schubert ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8, 434*85732ac8SCy Schubert NULL); 435*85732ac8SCy Schubert return ret != n * 8 ? -1 : 0; 436*85732ac8SCy Schubert } 437*85732ac8SCy Schubert 438*85732ac8SCy Schubert 439*85732ac8SCy Schubert #ifndef CONFIG_NO_RC4 440*85732ac8SCy Schubert int rc4_skip(const u8 *key, size_t keylen, size_t skip, u8 *data, 441*85732ac8SCy Schubert size_t data_len) 442*85732ac8SCy Schubert { 443*85732ac8SCy Schubert #ifndef NO_RC4 444*85732ac8SCy Schubert Arc4 arc4; 445*85732ac8SCy Schubert unsigned char skip_buf[16]; 446*85732ac8SCy Schubert 447*85732ac8SCy Schubert wc_Arc4SetKey(&arc4, key, keylen); 448*85732ac8SCy Schubert 449*85732ac8SCy Schubert while (skip >= sizeof(skip_buf)) { 450*85732ac8SCy Schubert size_t len = skip; 451*85732ac8SCy Schubert 452*85732ac8SCy Schubert if (len > sizeof(skip_buf)) 453*85732ac8SCy Schubert len = sizeof(skip_buf); 454*85732ac8SCy Schubert wc_Arc4Process(&arc4, skip_buf, skip_buf, len); 455*85732ac8SCy Schubert skip -= len; 456*85732ac8SCy Schubert } 457*85732ac8SCy Schubert 458*85732ac8SCy Schubert wc_Arc4Process(&arc4, data, data, data_len); 459*85732ac8SCy Schubert 460*85732ac8SCy Schubert return 0; 461*85732ac8SCy Schubert #else /* NO_RC4 */ 462*85732ac8SCy Schubert return -1; 463*85732ac8SCy Schubert #endif /* NO_RC4 */ 464*85732ac8SCy Schubert } 465*85732ac8SCy Schubert #endif /* CONFIG_NO_RC4 */ 466*85732ac8SCy Schubert 467*85732ac8SCy Schubert 468*85732ac8SCy Schubert #if defined(EAP_IKEV2) || defined(EAP_IKEV2_DYNAMIC) \ 469*85732ac8SCy Schubert || defined(EAP_SERVER_IKEV2) 470*85732ac8SCy Schubert union wolfssl_cipher { 471*85732ac8SCy Schubert Aes aes; 472*85732ac8SCy Schubert Des3 des3; 473*85732ac8SCy Schubert Arc4 arc4; 474*85732ac8SCy Schubert }; 475*85732ac8SCy Schubert 476*85732ac8SCy Schubert struct crypto_cipher { 477*85732ac8SCy Schubert enum crypto_cipher_alg alg; 478*85732ac8SCy Schubert union wolfssl_cipher enc; 479*85732ac8SCy Schubert union wolfssl_cipher dec; 480*85732ac8SCy Schubert }; 481*85732ac8SCy Schubert 482*85732ac8SCy Schubert struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 483*85732ac8SCy Schubert const u8 *iv, const u8 *key, 484*85732ac8SCy Schubert size_t key_len) 485*85732ac8SCy Schubert { 486*85732ac8SCy Schubert struct crypto_cipher *ctx; 487*85732ac8SCy Schubert 488*85732ac8SCy Schubert ctx = os_zalloc(sizeof(*ctx)); 489*85732ac8SCy Schubert if (!ctx) 490*85732ac8SCy Schubert return NULL; 491*85732ac8SCy Schubert 492*85732ac8SCy Schubert switch (alg) { 493*85732ac8SCy Schubert #ifndef CONFIG_NO_RC4 494*85732ac8SCy Schubert #ifndef NO_RC4 495*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_RC4: 496*85732ac8SCy Schubert wc_Arc4SetKey(&ctx->enc.arc4, key, key_len); 497*85732ac8SCy Schubert wc_Arc4SetKey(&ctx->dec.arc4, key, key_len); 498*85732ac8SCy Schubert break; 499*85732ac8SCy Schubert #endif /* NO_RC4 */ 500*85732ac8SCy Schubert #endif /* CONFIG_NO_RC4 */ 501*85732ac8SCy Schubert #ifndef NO_AES 502*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_AES: 503*85732ac8SCy Schubert switch (key_len) { 504*85732ac8SCy Schubert case 16: 505*85732ac8SCy Schubert case 24: 506*85732ac8SCy Schubert case 32: 507*85732ac8SCy Schubert break; 508*85732ac8SCy Schubert default: 509*85732ac8SCy Schubert os_free(ctx); 510*85732ac8SCy Schubert return NULL; 511*85732ac8SCy Schubert } 512*85732ac8SCy Schubert if (wc_AesSetKey(&ctx->enc.aes, key, key_len, iv, 513*85732ac8SCy Schubert AES_ENCRYPTION) || 514*85732ac8SCy Schubert wc_AesSetKey(&ctx->dec.aes, key, key_len, iv, 515*85732ac8SCy Schubert AES_DECRYPTION)) { 516*85732ac8SCy Schubert os_free(ctx); 517*85732ac8SCy Schubert return NULL; 518*85732ac8SCy Schubert } 519*85732ac8SCy Schubert break; 520*85732ac8SCy Schubert #endif /* NO_AES */ 521*85732ac8SCy Schubert #ifndef NO_DES3 522*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_3DES: 523*85732ac8SCy Schubert if (key_len != DES3_KEYLEN || 524*85732ac8SCy Schubert wc_Des3_SetKey(&ctx->enc.des3, key, iv, DES_ENCRYPTION) || 525*85732ac8SCy Schubert wc_Des3_SetKey(&ctx->dec.des3, key, iv, DES_DECRYPTION)) { 526*85732ac8SCy Schubert os_free(ctx); 527*85732ac8SCy Schubert return NULL; 528*85732ac8SCy Schubert } 529*85732ac8SCy Schubert break; 530*85732ac8SCy Schubert #endif /* NO_DES3 */ 531*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_RC2: 532*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_DES: 533*85732ac8SCy Schubert default: 534*85732ac8SCy Schubert os_free(ctx); 535*85732ac8SCy Schubert return NULL; 536*85732ac8SCy Schubert } 537*85732ac8SCy Schubert 538*85732ac8SCy Schubert ctx->alg = alg; 539*85732ac8SCy Schubert 540*85732ac8SCy Schubert return ctx; 541*85732ac8SCy Schubert } 542*85732ac8SCy Schubert 543*85732ac8SCy Schubert 544*85732ac8SCy Schubert int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 545*85732ac8SCy Schubert u8 *crypt, size_t len) 546*85732ac8SCy Schubert { 547*85732ac8SCy Schubert switch (ctx->alg) { 548*85732ac8SCy Schubert #ifndef CONFIG_NO_RC4 549*85732ac8SCy Schubert #ifndef NO_RC4 550*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_RC4: 551*85732ac8SCy Schubert wc_Arc4Process(&ctx->enc.arc4, crypt, plain, len); 552*85732ac8SCy Schubert return 0; 553*85732ac8SCy Schubert #endif /* NO_RC4 */ 554*85732ac8SCy Schubert #endif /* CONFIG_NO_RC4 */ 555*85732ac8SCy Schubert #ifndef NO_AES 556*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_AES: 557*85732ac8SCy Schubert if (wc_AesCbcEncrypt(&ctx->enc.aes, crypt, plain, len) != 0) 558*85732ac8SCy Schubert return -1; 559*85732ac8SCy Schubert return 0; 560*85732ac8SCy Schubert #endif /* NO_AES */ 561*85732ac8SCy Schubert #ifndef NO_DES3 562*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_3DES: 563*85732ac8SCy Schubert if (wc_Des3_CbcEncrypt(&ctx->enc.des3, crypt, plain, len) != 0) 564*85732ac8SCy Schubert return -1; 565*85732ac8SCy Schubert return 0; 566*85732ac8SCy Schubert #endif /* NO_DES3 */ 567*85732ac8SCy Schubert default: 568*85732ac8SCy Schubert return -1; 569*85732ac8SCy Schubert } 570*85732ac8SCy Schubert return -1; 571*85732ac8SCy Schubert } 572*85732ac8SCy Schubert 573*85732ac8SCy Schubert 574*85732ac8SCy Schubert int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 575*85732ac8SCy Schubert u8 *plain, size_t len) 576*85732ac8SCy Schubert { 577*85732ac8SCy Schubert switch (ctx->alg) { 578*85732ac8SCy Schubert #ifndef CONFIG_NO_RC4 579*85732ac8SCy Schubert #ifndef NO_RC4 580*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_RC4: 581*85732ac8SCy Schubert wc_Arc4Process(&ctx->dec.arc4, plain, crypt, len); 582*85732ac8SCy Schubert return 0; 583*85732ac8SCy Schubert #endif /* NO_RC4 */ 584*85732ac8SCy Schubert #endif /* CONFIG_NO_RC4 */ 585*85732ac8SCy Schubert #ifndef NO_AES 586*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_AES: 587*85732ac8SCy Schubert if (wc_AesCbcDecrypt(&ctx->dec.aes, plain, crypt, len) != 0) 588*85732ac8SCy Schubert return -1; 589*85732ac8SCy Schubert return 0; 590*85732ac8SCy Schubert #endif /* NO_AES */ 591*85732ac8SCy Schubert #ifndef NO_DES3 592*85732ac8SCy Schubert case CRYPTO_CIPHER_ALG_3DES: 593*85732ac8SCy Schubert if (wc_Des3_CbcDecrypt(&ctx->dec.des3, plain, crypt, len) != 0) 594*85732ac8SCy Schubert return -1; 595*85732ac8SCy Schubert return 0; 596*85732ac8SCy Schubert #endif /* NO_DES3 */ 597*85732ac8SCy Schubert default: 598*85732ac8SCy Schubert return -1; 599*85732ac8SCy Schubert } 600*85732ac8SCy Schubert return -1; 601*85732ac8SCy Schubert } 602*85732ac8SCy Schubert 603*85732ac8SCy Schubert 604*85732ac8SCy Schubert void crypto_cipher_deinit(struct crypto_cipher *ctx) 605*85732ac8SCy Schubert { 606*85732ac8SCy Schubert os_free(ctx); 607*85732ac8SCy Schubert } 608*85732ac8SCy Schubert 609*85732ac8SCy Schubert #endif 610*85732ac8SCy Schubert 611*85732ac8SCy Schubert 612*85732ac8SCy Schubert #ifdef CONFIG_WPS_NFC 613*85732ac8SCy Schubert 614*85732ac8SCy Schubert static const unsigned char RFC3526_PRIME_1536[] = { 615*85732ac8SCy Schubert 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 616*85732ac8SCy Schubert 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 617*85732ac8SCy Schubert 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 618*85732ac8SCy Schubert 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 619*85732ac8SCy Schubert 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 620*85732ac8SCy Schubert 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 621*85732ac8SCy Schubert 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 622*85732ac8SCy Schubert 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 623*85732ac8SCy Schubert 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 624*85732ac8SCy Schubert 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 625*85732ac8SCy Schubert 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 626*85732ac8SCy Schubert 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 627*85732ac8SCy Schubert 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 628*85732ac8SCy Schubert 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 629*85732ac8SCy Schubert 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 630*85732ac8SCy Schubert 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 631*85732ac8SCy Schubert }; 632*85732ac8SCy Schubert 633*85732ac8SCy Schubert static const unsigned char RFC3526_GENERATOR_1536[] = { 634*85732ac8SCy Schubert 0x02 635*85732ac8SCy Schubert }; 636*85732ac8SCy Schubert 637*85732ac8SCy Schubert #define RFC3526_LEN sizeof(RFC3526_PRIME_1536) 638*85732ac8SCy Schubert 639*85732ac8SCy Schubert 640*85732ac8SCy Schubert void * dh5_init(struct wpabuf **priv, struct wpabuf **publ) 641*85732ac8SCy Schubert { 642*85732ac8SCy Schubert WC_RNG rng; 643*85732ac8SCy Schubert DhKey *ret = NULL; 644*85732ac8SCy Schubert DhKey *dh = NULL; 645*85732ac8SCy Schubert struct wpabuf *privkey = NULL; 646*85732ac8SCy Schubert struct wpabuf *pubkey = NULL; 647*85732ac8SCy Schubert word32 priv_sz, pub_sz; 648*85732ac8SCy Schubert 649*85732ac8SCy Schubert *priv = NULL; 650*85732ac8SCy Schubert wpabuf_free(*publ); 651*85732ac8SCy Schubert *publ = NULL; 652*85732ac8SCy Schubert 653*85732ac8SCy Schubert dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); 654*85732ac8SCy Schubert if (!dh) 655*85732ac8SCy Schubert return NULL; 656*85732ac8SCy Schubert wc_InitDhKey(dh); 657*85732ac8SCy Schubert 658*85732ac8SCy Schubert if (wc_InitRng(&rng) != 0) { 659*85732ac8SCy Schubert XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER); 660*85732ac8SCy Schubert return NULL; 661*85732ac8SCy Schubert } 662*85732ac8SCy Schubert 663*85732ac8SCy Schubert privkey = wpabuf_alloc(RFC3526_LEN); 664*85732ac8SCy Schubert pubkey = wpabuf_alloc(RFC3526_LEN); 665*85732ac8SCy Schubert if (!privkey || !pubkey) 666*85732ac8SCy Schubert goto done; 667*85732ac8SCy Schubert 668*85732ac8SCy Schubert if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), 669*85732ac8SCy Schubert RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536)) 670*85732ac8SCy Schubert != 0) 671*85732ac8SCy Schubert goto done; 672*85732ac8SCy Schubert 673*85732ac8SCy Schubert if (wc_DhGenerateKeyPair(dh, &rng, wpabuf_mhead(privkey), &priv_sz, 674*85732ac8SCy Schubert wpabuf_mhead(pubkey), &pub_sz) != 0) 675*85732ac8SCy Schubert goto done; 676*85732ac8SCy Schubert 677*85732ac8SCy Schubert wpabuf_put(privkey, priv_sz); 678*85732ac8SCy Schubert wpabuf_put(pubkey, pub_sz); 679*85732ac8SCy Schubert 680*85732ac8SCy Schubert ret = dh; 681*85732ac8SCy Schubert *priv = privkey; 682*85732ac8SCy Schubert *publ = pubkey; 683*85732ac8SCy Schubert dh = NULL; 684*85732ac8SCy Schubert privkey = NULL; 685*85732ac8SCy Schubert pubkey = NULL; 686*85732ac8SCy Schubert done: 687*85732ac8SCy Schubert wpabuf_clear_free(pubkey); 688*85732ac8SCy Schubert wpabuf_clear_free(privkey); 689*85732ac8SCy Schubert if (dh) { 690*85732ac8SCy Schubert wc_FreeDhKey(dh); 691*85732ac8SCy Schubert XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER); 692*85732ac8SCy Schubert } 693*85732ac8SCy Schubert wc_FreeRng(&rng); 694*85732ac8SCy Schubert return ret; 695*85732ac8SCy Schubert } 696*85732ac8SCy Schubert 697*85732ac8SCy Schubert 698*85732ac8SCy Schubert void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ) 699*85732ac8SCy Schubert { 700*85732ac8SCy Schubert DhKey *ret = NULL; 701*85732ac8SCy Schubert DhKey *dh; 702*85732ac8SCy Schubert byte *secret; 703*85732ac8SCy Schubert word32 secret_sz; 704*85732ac8SCy Schubert 705*85732ac8SCy Schubert dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER); 706*85732ac8SCy Schubert if (!dh) 707*85732ac8SCy Schubert return NULL; 708*85732ac8SCy Schubert wc_InitDhKey(dh); 709*85732ac8SCy Schubert 710*85732ac8SCy Schubert secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER); 711*85732ac8SCy Schubert if (!secret) 712*85732ac8SCy Schubert goto done; 713*85732ac8SCy Schubert 714*85732ac8SCy Schubert if (wc_DhSetKey(dh, RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), 715*85732ac8SCy Schubert RFC3526_GENERATOR_1536, sizeof(RFC3526_GENERATOR_1536)) 716*85732ac8SCy Schubert != 0) 717*85732ac8SCy Schubert goto done; 718*85732ac8SCy Schubert 719*85732ac8SCy Schubert if (wc_DhAgree(dh, secret, &secret_sz, wpabuf_head(priv), 720*85732ac8SCy Schubert wpabuf_len(priv), RFC3526_GENERATOR_1536, 721*85732ac8SCy Schubert sizeof(RFC3526_GENERATOR_1536)) != 0) 722*85732ac8SCy Schubert goto done; 723*85732ac8SCy Schubert 724*85732ac8SCy Schubert if (secret_sz != wpabuf_len(publ) || 725*85732ac8SCy Schubert os_memcmp(secret, wpabuf_head(publ), secret_sz) != 0) 726*85732ac8SCy Schubert goto done; 727*85732ac8SCy Schubert 728*85732ac8SCy Schubert ret = dh; 729*85732ac8SCy Schubert dh = NULL; 730*85732ac8SCy Schubert done: 731*85732ac8SCy Schubert if (dh) { 732*85732ac8SCy Schubert wc_FreeDhKey(dh); 733*85732ac8SCy Schubert XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER); 734*85732ac8SCy Schubert } 735*85732ac8SCy Schubert XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER); 736*85732ac8SCy Schubert return ret; 737*85732ac8SCy Schubert } 738*85732ac8SCy Schubert 739*85732ac8SCy Schubert 740*85732ac8SCy Schubert struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public, 741*85732ac8SCy Schubert const struct wpabuf *own_private) 742*85732ac8SCy Schubert { 743*85732ac8SCy Schubert struct wpabuf *ret = NULL; 744*85732ac8SCy Schubert struct wpabuf *secret; 745*85732ac8SCy Schubert word32 secret_sz; 746*85732ac8SCy Schubert 747*85732ac8SCy Schubert secret = wpabuf_alloc(RFC3526_LEN); 748*85732ac8SCy Schubert if (!secret) 749*85732ac8SCy Schubert goto done; 750*85732ac8SCy Schubert 751*85732ac8SCy Schubert if (wc_DhAgree(ctx, wpabuf_mhead(secret), &secret_sz, 752*85732ac8SCy Schubert wpabuf_head(own_private), wpabuf_len(own_private), 753*85732ac8SCy Schubert wpabuf_head(peer_public), wpabuf_len(peer_public)) != 0) 754*85732ac8SCy Schubert goto done; 755*85732ac8SCy Schubert 756*85732ac8SCy Schubert wpabuf_put(secret, secret_sz); 757*85732ac8SCy Schubert 758*85732ac8SCy Schubert ret = secret; 759*85732ac8SCy Schubert secret = NULL; 760*85732ac8SCy Schubert done: 761*85732ac8SCy Schubert wpabuf_clear_free(secret); 762*85732ac8SCy Schubert return ret; 763*85732ac8SCy Schubert } 764*85732ac8SCy Schubert 765*85732ac8SCy Schubert 766*85732ac8SCy Schubert void dh5_free(void *ctx) 767*85732ac8SCy Schubert { 768*85732ac8SCy Schubert if (!ctx) 769*85732ac8SCy Schubert return; 770*85732ac8SCy Schubert 771*85732ac8SCy Schubert wc_FreeDhKey(ctx); 772*85732ac8SCy Schubert XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); 773*85732ac8SCy Schubert } 774*85732ac8SCy Schubert 775*85732ac8SCy Schubert #endif /* CONFIG_WPS_NFC */ 776*85732ac8SCy Schubert 777*85732ac8SCy Schubert 778*85732ac8SCy Schubert int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey, 779*85732ac8SCy Schubert u8 *pubkey) 780*85732ac8SCy Schubert { 781*85732ac8SCy Schubert int ret = -1; 782*85732ac8SCy Schubert WC_RNG rng; 783*85732ac8SCy Schubert DhKey *dh = NULL; 784*85732ac8SCy Schubert word32 priv_sz, pub_sz; 785*85732ac8SCy Schubert 786*85732ac8SCy Schubert if (TEST_FAIL()) 787*85732ac8SCy Schubert return -1; 788*85732ac8SCy Schubert 789*85732ac8SCy Schubert dh = os_malloc(sizeof(DhKey)); 790*85732ac8SCy Schubert if (!dh) 791*85732ac8SCy Schubert return -1; 792*85732ac8SCy Schubert wc_InitDhKey(dh); 793*85732ac8SCy Schubert 794*85732ac8SCy Schubert if (wc_InitRng(&rng) != 0) { 795*85732ac8SCy Schubert os_free(dh); 796*85732ac8SCy Schubert return -1; 797*85732ac8SCy Schubert } 798*85732ac8SCy Schubert 799*85732ac8SCy Schubert if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0) 800*85732ac8SCy Schubert goto done; 801*85732ac8SCy Schubert 802*85732ac8SCy Schubert if (wc_DhGenerateKeyPair(dh, &rng, privkey, &priv_sz, pubkey, &pub_sz) 803*85732ac8SCy Schubert != 0) 804*85732ac8SCy Schubert goto done; 805*85732ac8SCy Schubert 806*85732ac8SCy Schubert if (priv_sz < prime_len) { 807*85732ac8SCy Schubert size_t pad_sz = prime_len - priv_sz; 808*85732ac8SCy Schubert 809*85732ac8SCy Schubert os_memmove(privkey + pad_sz, privkey, priv_sz); 810*85732ac8SCy Schubert os_memset(privkey, 0, pad_sz); 811*85732ac8SCy Schubert } 812*85732ac8SCy Schubert 813*85732ac8SCy Schubert if (pub_sz < prime_len) { 814*85732ac8SCy Schubert size_t pad_sz = prime_len - pub_sz; 815*85732ac8SCy Schubert 816*85732ac8SCy Schubert os_memmove(pubkey + pad_sz, pubkey, pub_sz); 817*85732ac8SCy Schubert os_memset(pubkey, 0, pad_sz); 818*85732ac8SCy Schubert } 819*85732ac8SCy Schubert ret = 0; 820*85732ac8SCy Schubert done: 821*85732ac8SCy Schubert wc_FreeDhKey(dh); 822*85732ac8SCy Schubert os_free(dh); 823*85732ac8SCy Schubert wc_FreeRng(&rng); 824*85732ac8SCy Schubert return ret; 825*85732ac8SCy Schubert } 826*85732ac8SCy Schubert 827*85732ac8SCy Schubert 828*85732ac8SCy Schubert int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len, 829*85732ac8SCy Schubert const u8 *privkey, size_t privkey_len, 830*85732ac8SCy Schubert const u8 *pubkey, size_t pubkey_len, 831*85732ac8SCy Schubert u8 *secret, size_t *len) 832*85732ac8SCy Schubert { 833*85732ac8SCy Schubert int ret = -1; 834*85732ac8SCy Schubert DhKey *dh; 835*85732ac8SCy Schubert word32 secret_sz; 836*85732ac8SCy Schubert 837*85732ac8SCy Schubert dh = os_malloc(sizeof(DhKey)); 838*85732ac8SCy Schubert if (!dh) 839*85732ac8SCy Schubert return -1; 840*85732ac8SCy Schubert wc_InitDhKey(dh); 841*85732ac8SCy Schubert 842*85732ac8SCy Schubert if (wc_DhSetKey(dh, prime, prime_len, &generator, 1) != 0) 843*85732ac8SCy Schubert goto done; 844*85732ac8SCy Schubert 845*85732ac8SCy Schubert if (wc_DhAgree(dh, secret, &secret_sz, privkey, privkey_len, pubkey, 846*85732ac8SCy Schubert pubkey_len) != 0) 847*85732ac8SCy Schubert goto done; 848*85732ac8SCy Schubert 849*85732ac8SCy Schubert *len = secret_sz; 850*85732ac8SCy Schubert ret = 0; 851*85732ac8SCy Schubert done: 852*85732ac8SCy Schubert wc_FreeDhKey(dh); 853*85732ac8SCy Schubert os_free(dh); 854*85732ac8SCy Schubert return ret; 855*85732ac8SCy Schubert } 856*85732ac8SCy Schubert 857*85732ac8SCy Schubert 858*85732ac8SCy Schubert #ifdef CONFIG_FIPS 859*85732ac8SCy Schubert int crypto_get_random(void *buf, size_t len) 860*85732ac8SCy Schubert { 861*85732ac8SCy Schubert int ret = 0; 862*85732ac8SCy Schubert WC_RNG rng; 863*85732ac8SCy Schubert 864*85732ac8SCy Schubert if (wc_InitRng(&rng) != 0) 865*85732ac8SCy Schubert return -1; 866*85732ac8SCy Schubert if (wc_RNG_GenerateBlock(&rng, buf, len) != 0) 867*85732ac8SCy Schubert ret = -1; 868*85732ac8SCy Schubert wc_FreeRng(&rng); 869*85732ac8SCy Schubert return ret; 870*85732ac8SCy Schubert } 871*85732ac8SCy Schubert #endif /* CONFIG_FIPS */ 872*85732ac8SCy Schubert 873*85732ac8SCy Schubert 874*85732ac8SCy Schubert #if defined(EAP_PWD) || defined(EAP_SERVER_PWD) 875*85732ac8SCy Schubert struct crypto_hash { 876*85732ac8SCy Schubert Hmac hmac; 877*85732ac8SCy Schubert int size; 878*85732ac8SCy Schubert }; 879*85732ac8SCy Schubert 880*85732ac8SCy Schubert 881*85732ac8SCy Schubert struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 882*85732ac8SCy Schubert size_t key_len) 883*85732ac8SCy Schubert { 884*85732ac8SCy Schubert struct crypto_hash *ret = NULL; 885*85732ac8SCy Schubert struct crypto_hash *hash; 886*85732ac8SCy Schubert int type; 887*85732ac8SCy Schubert 888*85732ac8SCy Schubert hash = os_zalloc(sizeof(*hash)); 889*85732ac8SCy Schubert if (!hash) 890*85732ac8SCy Schubert goto done; 891*85732ac8SCy Schubert 892*85732ac8SCy Schubert switch (alg) { 893*85732ac8SCy Schubert #ifndef NO_MD5 894*85732ac8SCy Schubert case CRYPTO_HASH_ALG_HMAC_MD5: 895*85732ac8SCy Schubert hash->size = 16; 896*85732ac8SCy Schubert type = WC_MD5; 897*85732ac8SCy Schubert break; 898*85732ac8SCy Schubert #endif /* NO_MD5 */ 899*85732ac8SCy Schubert #ifndef NO_SHA 900*85732ac8SCy Schubert case CRYPTO_HASH_ALG_HMAC_SHA1: 901*85732ac8SCy Schubert type = WC_SHA; 902*85732ac8SCy Schubert hash->size = 20; 903*85732ac8SCy Schubert break; 904*85732ac8SCy Schubert #endif /* NO_SHA */ 905*85732ac8SCy Schubert #ifdef CONFIG_SHA256 906*85732ac8SCy Schubert #ifndef NO_SHA256 907*85732ac8SCy Schubert case CRYPTO_HASH_ALG_HMAC_SHA256: 908*85732ac8SCy Schubert type = WC_SHA256; 909*85732ac8SCy Schubert hash->size = 32; 910*85732ac8SCy Schubert break; 911*85732ac8SCy Schubert #endif /* NO_SHA256 */ 912*85732ac8SCy Schubert #endif /* CONFIG_SHA256 */ 913*85732ac8SCy Schubert default: 914*85732ac8SCy Schubert goto done; 915*85732ac8SCy Schubert } 916*85732ac8SCy Schubert 917*85732ac8SCy Schubert if (wc_HmacSetKey(&hash->hmac, type, key, key_len) != 0) 918*85732ac8SCy Schubert goto done; 919*85732ac8SCy Schubert 920*85732ac8SCy Schubert ret = hash; 921*85732ac8SCy Schubert hash = NULL; 922*85732ac8SCy Schubert done: 923*85732ac8SCy Schubert os_free(hash); 924*85732ac8SCy Schubert return ret; 925*85732ac8SCy Schubert } 926*85732ac8SCy Schubert 927*85732ac8SCy Schubert 928*85732ac8SCy Schubert void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 929*85732ac8SCy Schubert { 930*85732ac8SCy Schubert if (!ctx) 931*85732ac8SCy Schubert return; 932*85732ac8SCy Schubert wc_HmacUpdate(&ctx->hmac, data, len); 933*85732ac8SCy Schubert } 934*85732ac8SCy Schubert 935*85732ac8SCy Schubert 936*85732ac8SCy Schubert int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 937*85732ac8SCy Schubert { 938*85732ac8SCy Schubert int ret = 0; 939*85732ac8SCy Schubert 940*85732ac8SCy Schubert if (!ctx) 941*85732ac8SCy Schubert return -2; 942*85732ac8SCy Schubert 943*85732ac8SCy Schubert if (!mac || !len) 944*85732ac8SCy Schubert goto done; 945*85732ac8SCy Schubert 946*85732ac8SCy Schubert if (wc_HmacFinal(&ctx->hmac, mac) != 0) { 947*85732ac8SCy Schubert ret = -1; 948*85732ac8SCy Schubert goto done; 949*85732ac8SCy Schubert } 950*85732ac8SCy Schubert 951*85732ac8SCy Schubert *len = ctx->size; 952*85732ac8SCy Schubert ret = 0; 953*85732ac8SCy Schubert done: 954*85732ac8SCy Schubert bin_clear_free(ctx, sizeof(*ctx)); 955*85732ac8SCy Schubert return ret; 956*85732ac8SCy Schubert } 957*85732ac8SCy Schubert 958*85732ac8SCy Schubert #endif 959*85732ac8SCy Schubert 960*85732ac8SCy Schubert 961*85732ac8SCy Schubert int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem, 962*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 963*85732ac8SCy Schubert { 964*85732ac8SCy Schubert Cmac cmac; 965*85732ac8SCy Schubert size_t i; 966*85732ac8SCy Schubert word32 sz; 967*85732ac8SCy Schubert 968*85732ac8SCy Schubert if (TEST_FAIL()) 969*85732ac8SCy Schubert return -1; 970*85732ac8SCy Schubert 971*85732ac8SCy Schubert if (wc_InitCmac(&cmac, key, key_len, WC_CMAC_AES, NULL) != 0) 972*85732ac8SCy Schubert return -1; 973*85732ac8SCy Schubert 974*85732ac8SCy Schubert for (i = 0; i < num_elem; i++) 975*85732ac8SCy Schubert if (wc_CmacUpdate(&cmac, addr[i], len[i]) != 0) 976*85732ac8SCy Schubert return -1; 977*85732ac8SCy Schubert 978*85732ac8SCy Schubert sz = AES_BLOCK_SIZE; 979*85732ac8SCy Schubert if (wc_CmacFinal(&cmac, mac, &sz) != 0 || sz != AES_BLOCK_SIZE) 980*85732ac8SCy Schubert return -1; 981*85732ac8SCy Schubert 982*85732ac8SCy Schubert return 0; 983*85732ac8SCy Schubert } 984*85732ac8SCy Schubert 985*85732ac8SCy Schubert 986*85732ac8SCy Schubert int omac1_aes_128_vector(const u8 *key, size_t num_elem, 987*85732ac8SCy Schubert const u8 *addr[], const size_t *len, u8 *mac) 988*85732ac8SCy Schubert { 989*85732ac8SCy Schubert return omac1_aes_vector(key, 16, num_elem, addr, len, mac); 990*85732ac8SCy Schubert } 991*85732ac8SCy Schubert 992*85732ac8SCy Schubert 993*85732ac8SCy Schubert int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 994*85732ac8SCy Schubert { 995*85732ac8SCy Schubert return omac1_aes_128_vector(key, 1, &data, &data_len, mac); 996*85732ac8SCy Schubert } 997*85732ac8SCy Schubert 998*85732ac8SCy Schubert 999*85732ac8SCy Schubert int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac) 1000*85732ac8SCy Schubert { 1001*85732ac8SCy Schubert return omac1_aes_vector(key, 32, 1, &data, &data_len, mac); 1002*85732ac8SCy Schubert } 1003*85732ac8SCy Schubert 1004*85732ac8SCy Schubert 1005*85732ac8SCy Schubert struct crypto_bignum * crypto_bignum_init(void) 1006*85732ac8SCy Schubert { 1007*85732ac8SCy Schubert mp_int *a; 1008*85732ac8SCy Schubert 1009*85732ac8SCy Schubert if (TEST_FAIL()) 1010*85732ac8SCy Schubert return NULL; 1011*85732ac8SCy Schubert 1012*85732ac8SCy Schubert a = os_malloc(sizeof(*a)); 1013*85732ac8SCy Schubert if (!a || mp_init(a) != MP_OKAY) { 1014*85732ac8SCy Schubert os_free(a); 1015*85732ac8SCy Schubert a = NULL; 1016*85732ac8SCy Schubert } 1017*85732ac8SCy Schubert 1018*85732ac8SCy Schubert return (struct crypto_bignum *) a; 1019*85732ac8SCy Schubert } 1020*85732ac8SCy Schubert 1021*85732ac8SCy Schubert 1022*85732ac8SCy Schubert struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len) 1023*85732ac8SCy Schubert { 1024*85732ac8SCy Schubert mp_int *a; 1025*85732ac8SCy Schubert 1026*85732ac8SCy Schubert if (TEST_FAIL()) 1027*85732ac8SCy Schubert return NULL; 1028*85732ac8SCy Schubert 1029*85732ac8SCy Schubert a = (mp_int *) crypto_bignum_init(); 1030*85732ac8SCy Schubert if (!a) 1031*85732ac8SCy Schubert return NULL; 1032*85732ac8SCy Schubert 1033*85732ac8SCy Schubert if (mp_read_unsigned_bin(a, buf, len) != MP_OKAY) { 1034*85732ac8SCy Schubert os_free(a); 1035*85732ac8SCy Schubert a = NULL; 1036*85732ac8SCy Schubert } 1037*85732ac8SCy Schubert 1038*85732ac8SCy Schubert return (struct crypto_bignum *) a; 1039*85732ac8SCy Schubert } 1040*85732ac8SCy Schubert 1041*85732ac8SCy Schubert 1042*85732ac8SCy Schubert void crypto_bignum_deinit(struct crypto_bignum *n, int clear) 1043*85732ac8SCy Schubert { 1044*85732ac8SCy Schubert if (!n) 1045*85732ac8SCy Schubert return; 1046*85732ac8SCy Schubert 1047*85732ac8SCy Schubert if (clear) 1048*85732ac8SCy Schubert mp_forcezero((mp_int *) n); 1049*85732ac8SCy Schubert mp_clear((mp_int *) n); 1050*85732ac8SCy Schubert os_free((mp_int *) n); 1051*85732ac8SCy Schubert } 1052*85732ac8SCy Schubert 1053*85732ac8SCy Schubert 1054*85732ac8SCy Schubert int crypto_bignum_to_bin(const struct crypto_bignum *a, 1055*85732ac8SCy Schubert u8 *buf, size_t buflen, size_t padlen) 1056*85732ac8SCy Schubert { 1057*85732ac8SCy Schubert int num_bytes, offset; 1058*85732ac8SCy Schubert 1059*85732ac8SCy Schubert if (TEST_FAIL()) 1060*85732ac8SCy Schubert return -1; 1061*85732ac8SCy Schubert 1062*85732ac8SCy Schubert if (padlen > buflen) 1063*85732ac8SCy Schubert return -1; 1064*85732ac8SCy Schubert 1065*85732ac8SCy Schubert num_bytes = (mp_count_bits((mp_int *) a) + 7) / 8; 1066*85732ac8SCy Schubert if ((size_t) num_bytes > buflen) 1067*85732ac8SCy Schubert return -1; 1068*85732ac8SCy Schubert if (padlen > (size_t) num_bytes) 1069*85732ac8SCy Schubert offset = padlen - num_bytes; 1070*85732ac8SCy Schubert else 1071*85732ac8SCy Schubert offset = 0; 1072*85732ac8SCy Schubert 1073*85732ac8SCy Schubert os_memset(buf, 0, offset); 1074*85732ac8SCy Schubert mp_to_unsigned_bin((mp_int *) a, buf + offset); 1075*85732ac8SCy Schubert 1076*85732ac8SCy Schubert return num_bytes + offset; 1077*85732ac8SCy Schubert } 1078*85732ac8SCy Schubert 1079*85732ac8SCy Schubert 1080*85732ac8SCy Schubert int crypto_bignum_rand(struct crypto_bignum *r, const struct crypto_bignum *m) 1081*85732ac8SCy Schubert { 1082*85732ac8SCy Schubert int ret = 0; 1083*85732ac8SCy Schubert WC_RNG rng; 1084*85732ac8SCy Schubert 1085*85732ac8SCy Schubert if (wc_InitRng(&rng) != 0) 1086*85732ac8SCy Schubert return -1; 1087*85732ac8SCy Schubert if (mp_rand_prime((mp_int *) r, 1088*85732ac8SCy Schubert (mp_count_bits((mp_int *) m) + 7) / 8 * 2, 1089*85732ac8SCy Schubert &rng, NULL) != 0) 1090*85732ac8SCy Schubert ret = -1; 1091*85732ac8SCy Schubert if (ret == 0 && 1092*85732ac8SCy Schubert mp_mod((mp_int *) r, (mp_int *) m, (mp_int *) r) != 0) 1093*85732ac8SCy Schubert ret = -1; 1094*85732ac8SCy Schubert wc_FreeRng(&rng); 1095*85732ac8SCy Schubert return ret; 1096*85732ac8SCy Schubert } 1097*85732ac8SCy Schubert 1098*85732ac8SCy Schubert 1099*85732ac8SCy Schubert int crypto_bignum_add(const struct crypto_bignum *a, 1100*85732ac8SCy Schubert const struct crypto_bignum *b, 1101*85732ac8SCy Schubert struct crypto_bignum *r) 1102*85732ac8SCy Schubert { 1103*85732ac8SCy Schubert return mp_add((mp_int *) a, (mp_int *) b, 1104*85732ac8SCy Schubert (mp_int *) r) == MP_OKAY ? 0 : -1; 1105*85732ac8SCy Schubert } 1106*85732ac8SCy Schubert 1107*85732ac8SCy Schubert 1108*85732ac8SCy Schubert int crypto_bignum_mod(const struct crypto_bignum *a, 1109*85732ac8SCy Schubert const struct crypto_bignum *m, 1110*85732ac8SCy Schubert struct crypto_bignum *r) 1111*85732ac8SCy Schubert { 1112*85732ac8SCy Schubert return mp_mod((mp_int *) a, (mp_int *) m, 1113*85732ac8SCy Schubert (mp_int *) r) == MP_OKAY ? 0 : -1; 1114*85732ac8SCy Schubert } 1115*85732ac8SCy Schubert 1116*85732ac8SCy Schubert 1117*85732ac8SCy Schubert int crypto_bignum_exptmod(const struct crypto_bignum *b, 1118*85732ac8SCy Schubert const struct crypto_bignum *e, 1119*85732ac8SCy Schubert const struct crypto_bignum *m, 1120*85732ac8SCy Schubert struct crypto_bignum *r) 1121*85732ac8SCy Schubert { 1122*85732ac8SCy Schubert if (TEST_FAIL()) 1123*85732ac8SCy Schubert return -1; 1124*85732ac8SCy Schubert 1125*85732ac8SCy Schubert return mp_exptmod((mp_int *) b, (mp_int *) e, (mp_int *) m, 1126*85732ac8SCy Schubert (mp_int *) r) == MP_OKAY ? 0 : -1; 1127*85732ac8SCy Schubert } 1128*85732ac8SCy Schubert 1129*85732ac8SCy Schubert 1130*85732ac8SCy Schubert int crypto_bignum_inverse(const struct crypto_bignum *a, 1131*85732ac8SCy Schubert const struct crypto_bignum *m, 1132*85732ac8SCy Schubert struct crypto_bignum *r) 1133*85732ac8SCy Schubert { 1134*85732ac8SCy Schubert if (TEST_FAIL()) 1135*85732ac8SCy Schubert return -1; 1136*85732ac8SCy Schubert 1137*85732ac8SCy Schubert return mp_invmod((mp_int *) a, (mp_int *) m, 1138*85732ac8SCy Schubert (mp_int *) r) == MP_OKAY ? 0 : -1; 1139*85732ac8SCy Schubert } 1140*85732ac8SCy Schubert 1141*85732ac8SCy Schubert 1142*85732ac8SCy Schubert int crypto_bignum_sub(const struct crypto_bignum *a, 1143*85732ac8SCy Schubert const struct crypto_bignum *b, 1144*85732ac8SCy Schubert struct crypto_bignum *r) 1145*85732ac8SCy Schubert { 1146*85732ac8SCy Schubert if (TEST_FAIL()) 1147*85732ac8SCy Schubert return -1; 1148*85732ac8SCy Schubert 1149*85732ac8SCy Schubert return mp_add((mp_int *) a, (mp_int *) b, 1150*85732ac8SCy Schubert (mp_int *) r) == MP_OKAY ? 0 : -1; 1151*85732ac8SCy Schubert } 1152*85732ac8SCy Schubert 1153*85732ac8SCy Schubert 1154*85732ac8SCy Schubert int crypto_bignum_div(const struct crypto_bignum *a, 1155*85732ac8SCy Schubert const struct crypto_bignum *b, 1156*85732ac8SCy Schubert struct crypto_bignum *d) 1157*85732ac8SCy Schubert { 1158*85732ac8SCy Schubert if (TEST_FAIL()) 1159*85732ac8SCy Schubert return -1; 1160*85732ac8SCy Schubert 1161*85732ac8SCy Schubert return mp_div((mp_int *) a, (mp_int *) b, (mp_int *) d, 1162*85732ac8SCy Schubert NULL) == MP_OKAY ? 0 : -1; 1163*85732ac8SCy Schubert } 1164*85732ac8SCy Schubert 1165*85732ac8SCy Schubert 1166*85732ac8SCy Schubert int crypto_bignum_mulmod(const struct crypto_bignum *a, 1167*85732ac8SCy Schubert const struct crypto_bignum *b, 1168*85732ac8SCy Schubert const struct crypto_bignum *m, 1169*85732ac8SCy Schubert struct crypto_bignum *d) 1170*85732ac8SCy Schubert { 1171*85732ac8SCy Schubert if (TEST_FAIL()) 1172*85732ac8SCy Schubert return -1; 1173*85732ac8SCy Schubert 1174*85732ac8SCy Schubert return mp_mulmod((mp_int *) a, (mp_int *) b, (mp_int *) m, 1175*85732ac8SCy Schubert (mp_int *) d) == MP_OKAY ? 0 : -1; 1176*85732ac8SCy Schubert } 1177*85732ac8SCy Schubert 1178*85732ac8SCy Schubert 1179*85732ac8SCy Schubert int crypto_bignum_rshift(const struct crypto_bignum *a, int n, 1180*85732ac8SCy Schubert struct crypto_bignum *r) 1181*85732ac8SCy Schubert { 1182*85732ac8SCy Schubert if (mp_copy((mp_int *) a, (mp_int *) r) != MP_OKAY) 1183*85732ac8SCy Schubert return -1; 1184*85732ac8SCy Schubert mp_rshb((mp_int *) r, n); 1185*85732ac8SCy Schubert return 0; 1186*85732ac8SCy Schubert } 1187*85732ac8SCy Schubert 1188*85732ac8SCy Schubert 1189*85732ac8SCy Schubert int crypto_bignum_cmp(const struct crypto_bignum *a, 1190*85732ac8SCy Schubert const struct crypto_bignum *b) 1191*85732ac8SCy Schubert { 1192*85732ac8SCy Schubert return mp_cmp((mp_int *) a, (mp_int *) b); 1193*85732ac8SCy Schubert } 1194*85732ac8SCy Schubert 1195*85732ac8SCy Schubert 1196*85732ac8SCy Schubert int crypto_bignum_bits(const struct crypto_bignum *a) 1197*85732ac8SCy Schubert { 1198*85732ac8SCy Schubert return mp_count_bits((mp_int *) a); 1199*85732ac8SCy Schubert } 1200*85732ac8SCy Schubert 1201*85732ac8SCy Schubert 1202*85732ac8SCy Schubert int crypto_bignum_is_zero(const struct crypto_bignum *a) 1203*85732ac8SCy Schubert { 1204*85732ac8SCy Schubert return mp_iszero((mp_int *) a); 1205*85732ac8SCy Schubert } 1206*85732ac8SCy Schubert 1207*85732ac8SCy Schubert 1208*85732ac8SCy Schubert int crypto_bignum_is_one(const struct crypto_bignum *a) 1209*85732ac8SCy Schubert { 1210*85732ac8SCy Schubert return mp_isone((const mp_int *) a); 1211*85732ac8SCy Schubert } 1212*85732ac8SCy Schubert 1213*85732ac8SCy Schubert int crypto_bignum_is_odd(const struct crypto_bignum *a) 1214*85732ac8SCy Schubert { 1215*85732ac8SCy Schubert return mp_isodd((mp_int *) a); 1216*85732ac8SCy Schubert } 1217*85732ac8SCy Schubert 1218*85732ac8SCy Schubert 1219*85732ac8SCy Schubert int crypto_bignum_legendre(const struct crypto_bignum *a, 1220*85732ac8SCy Schubert const struct crypto_bignum *p) 1221*85732ac8SCy Schubert { 1222*85732ac8SCy Schubert mp_int t; 1223*85732ac8SCy Schubert int ret; 1224*85732ac8SCy Schubert int res = -2; 1225*85732ac8SCy Schubert 1226*85732ac8SCy Schubert if (TEST_FAIL()) 1227*85732ac8SCy Schubert return -2; 1228*85732ac8SCy Schubert 1229*85732ac8SCy Schubert if (mp_init(&t) != MP_OKAY) 1230*85732ac8SCy Schubert return -2; 1231*85732ac8SCy Schubert 1232*85732ac8SCy Schubert /* t = (p-1) / 2 */ 1233*85732ac8SCy Schubert ret = mp_sub_d((mp_int *) p, 1, &t); 1234*85732ac8SCy Schubert if (ret == MP_OKAY) 1235*85732ac8SCy Schubert mp_rshb(&t, 1); 1236*85732ac8SCy Schubert if (ret == MP_OKAY) 1237*85732ac8SCy Schubert ret = mp_exptmod((mp_int *) a, &t, (mp_int *) p, &t); 1238*85732ac8SCy Schubert if (ret == MP_OKAY) { 1239*85732ac8SCy Schubert if (mp_isone(&t)) 1240*85732ac8SCy Schubert res = 1; 1241*85732ac8SCy Schubert else if (mp_iszero(&t)) 1242*85732ac8SCy Schubert res = 0; 1243*85732ac8SCy Schubert else 1244*85732ac8SCy Schubert res = -1; 1245*85732ac8SCy Schubert } 1246*85732ac8SCy Schubert 1247*85732ac8SCy Schubert mp_clear(&t); 1248*85732ac8SCy Schubert return res; 1249*85732ac8SCy Schubert } 1250*85732ac8SCy Schubert 1251*85732ac8SCy Schubert 1252*85732ac8SCy Schubert #ifdef CONFIG_ECC 1253*85732ac8SCy Schubert 1254*85732ac8SCy Schubert int ecc_map(ecc_point *, mp_int *, mp_digit); 1255*85732ac8SCy Schubert int ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, 1256*85732ac8SCy Schubert mp_int *a, mp_int *modulus, mp_digit mp); 1257*85732ac8SCy Schubert 1258*85732ac8SCy Schubert struct crypto_ec { 1259*85732ac8SCy Schubert ecc_key key; 1260*85732ac8SCy Schubert mp_int a; 1261*85732ac8SCy Schubert mp_int prime; 1262*85732ac8SCy Schubert mp_int order; 1263*85732ac8SCy Schubert mp_digit mont_b; 1264*85732ac8SCy Schubert mp_int b; 1265*85732ac8SCy Schubert }; 1266*85732ac8SCy Schubert 1267*85732ac8SCy Schubert 1268*85732ac8SCy Schubert struct crypto_ec * crypto_ec_init(int group) 1269*85732ac8SCy Schubert { 1270*85732ac8SCy Schubert int built = 0; 1271*85732ac8SCy Schubert struct crypto_ec *e; 1272*85732ac8SCy Schubert int curve_id; 1273*85732ac8SCy Schubert 1274*85732ac8SCy Schubert /* Map from IANA registry for IKE D-H groups to OpenSSL NID */ 1275*85732ac8SCy Schubert switch (group) { 1276*85732ac8SCy Schubert case 19: 1277*85732ac8SCy Schubert curve_id = ECC_SECP256R1; 1278*85732ac8SCy Schubert break; 1279*85732ac8SCy Schubert case 20: 1280*85732ac8SCy Schubert curve_id = ECC_SECP384R1; 1281*85732ac8SCy Schubert break; 1282*85732ac8SCy Schubert case 21: 1283*85732ac8SCy Schubert curve_id = ECC_SECP521R1; 1284*85732ac8SCy Schubert break; 1285*85732ac8SCy Schubert case 25: 1286*85732ac8SCy Schubert curve_id = ECC_SECP192R1; 1287*85732ac8SCy Schubert break; 1288*85732ac8SCy Schubert case 26: 1289*85732ac8SCy Schubert curve_id = ECC_SECP224R1; 1290*85732ac8SCy Schubert break; 1291*85732ac8SCy Schubert #ifdef HAVE_ECC_BRAINPOOL 1292*85732ac8SCy Schubert case 27: 1293*85732ac8SCy Schubert curve_id = ECC_BRAINPOOLP224R1; 1294*85732ac8SCy Schubert break; 1295*85732ac8SCy Schubert case 28: 1296*85732ac8SCy Schubert curve_id = ECC_BRAINPOOLP256R1; 1297*85732ac8SCy Schubert break; 1298*85732ac8SCy Schubert case 29: 1299*85732ac8SCy Schubert curve_id = ECC_BRAINPOOLP384R1; 1300*85732ac8SCy Schubert break; 1301*85732ac8SCy Schubert case 30: 1302*85732ac8SCy Schubert curve_id = ECC_BRAINPOOLP512R1; 1303*85732ac8SCy Schubert break; 1304*85732ac8SCy Schubert #endif /* HAVE_ECC_BRAINPOOL */ 1305*85732ac8SCy Schubert default: 1306*85732ac8SCy Schubert return NULL; 1307*85732ac8SCy Schubert } 1308*85732ac8SCy Schubert 1309*85732ac8SCy Schubert e = os_zalloc(sizeof(*e)); 1310*85732ac8SCy Schubert if (!e) 1311*85732ac8SCy Schubert return NULL; 1312*85732ac8SCy Schubert 1313*85732ac8SCy Schubert if (wc_ecc_init(&e->key) != 0 || 1314*85732ac8SCy Schubert wc_ecc_set_curve(&e->key, 0, curve_id) != 0 || 1315*85732ac8SCy Schubert mp_init(&e->a) != MP_OKAY || 1316*85732ac8SCy Schubert mp_init(&e->prime) != MP_OKAY || 1317*85732ac8SCy Schubert mp_init(&e->order) != MP_OKAY || 1318*85732ac8SCy Schubert mp_init(&e->b) != MP_OKAY || 1319*85732ac8SCy Schubert mp_read_radix(&e->a, e->key.dp->Af, 16) != MP_OKAY || 1320*85732ac8SCy Schubert mp_read_radix(&e->b, e->key.dp->Bf, 16) != MP_OKAY || 1321*85732ac8SCy Schubert mp_read_radix(&e->prime, e->key.dp->prime, 16) != MP_OKAY || 1322*85732ac8SCy Schubert mp_read_radix(&e->order, e->key.dp->order, 16) != MP_OKAY || 1323*85732ac8SCy Schubert mp_montgomery_setup(&e->prime, &e->mont_b) != MP_OKAY) 1324*85732ac8SCy Schubert goto done; 1325*85732ac8SCy Schubert 1326*85732ac8SCy Schubert built = 1; 1327*85732ac8SCy Schubert done: 1328*85732ac8SCy Schubert if (!built) { 1329*85732ac8SCy Schubert crypto_ec_deinit(e); 1330*85732ac8SCy Schubert e = NULL; 1331*85732ac8SCy Schubert } 1332*85732ac8SCy Schubert return e; 1333*85732ac8SCy Schubert } 1334*85732ac8SCy Schubert 1335*85732ac8SCy Schubert 1336*85732ac8SCy Schubert void crypto_ec_deinit(struct crypto_ec* e) 1337*85732ac8SCy Schubert { 1338*85732ac8SCy Schubert if (!e) 1339*85732ac8SCy Schubert return; 1340*85732ac8SCy Schubert 1341*85732ac8SCy Schubert mp_clear(&e->b); 1342*85732ac8SCy Schubert mp_clear(&e->order); 1343*85732ac8SCy Schubert mp_clear(&e->prime); 1344*85732ac8SCy Schubert mp_clear(&e->a); 1345*85732ac8SCy Schubert wc_ecc_free(&e->key); 1346*85732ac8SCy Schubert os_free(e); 1347*85732ac8SCy Schubert } 1348*85732ac8SCy Schubert 1349*85732ac8SCy Schubert 1350*85732ac8SCy Schubert int crypto_ec_cofactor(struct crypto_ec *e, struct crypto_bignum *cofactor) 1351*85732ac8SCy Schubert { 1352*85732ac8SCy Schubert if (!e || !cofactor) 1353*85732ac8SCy Schubert return -1; 1354*85732ac8SCy Schubert 1355*85732ac8SCy Schubert mp_set((mp_int *) cofactor, e->key.dp->cofactor); 1356*85732ac8SCy Schubert return 0; 1357*85732ac8SCy Schubert } 1358*85732ac8SCy Schubert 1359*85732ac8SCy Schubert 1360*85732ac8SCy Schubert struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e) 1361*85732ac8SCy Schubert { 1362*85732ac8SCy Schubert if (TEST_FAIL()) 1363*85732ac8SCy Schubert return NULL; 1364*85732ac8SCy Schubert if (!e) 1365*85732ac8SCy Schubert return NULL; 1366*85732ac8SCy Schubert return (struct crypto_ec_point *) wc_ecc_new_point(); 1367*85732ac8SCy Schubert } 1368*85732ac8SCy Schubert 1369*85732ac8SCy Schubert 1370*85732ac8SCy Schubert size_t crypto_ec_prime_len(struct crypto_ec *e) 1371*85732ac8SCy Schubert { 1372*85732ac8SCy Schubert return (mp_count_bits(&e->prime) + 7) / 8; 1373*85732ac8SCy Schubert } 1374*85732ac8SCy Schubert 1375*85732ac8SCy Schubert 1376*85732ac8SCy Schubert size_t crypto_ec_prime_len_bits(struct crypto_ec *e) 1377*85732ac8SCy Schubert { 1378*85732ac8SCy Schubert return mp_count_bits(&e->prime); 1379*85732ac8SCy Schubert } 1380*85732ac8SCy Schubert 1381*85732ac8SCy Schubert 1382*85732ac8SCy Schubert size_t crypto_ec_order_len(struct crypto_ec *e) 1383*85732ac8SCy Schubert { 1384*85732ac8SCy Schubert return (mp_count_bits(&e->order) + 7) / 8; 1385*85732ac8SCy Schubert } 1386*85732ac8SCy Schubert 1387*85732ac8SCy Schubert 1388*85732ac8SCy Schubert const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e) 1389*85732ac8SCy Schubert { 1390*85732ac8SCy Schubert return (const struct crypto_bignum *) &e->prime; 1391*85732ac8SCy Schubert } 1392*85732ac8SCy Schubert 1393*85732ac8SCy Schubert 1394*85732ac8SCy Schubert const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e) 1395*85732ac8SCy Schubert { 1396*85732ac8SCy Schubert return (const struct crypto_bignum *) &e->order; 1397*85732ac8SCy Schubert } 1398*85732ac8SCy Schubert 1399*85732ac8SCy Schubert 1400*85732ac8SCy Schubert void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear) 1401*85732ac8SCy Schubert { 1402*85732ac8SCy Schubert ecc_point *point = (ecc_point *) p; 1403*85732ac8SCy Schubert 1404*85732ac8SCy Schubert if (!p) 1405*85732ac8SCy Schubert return; 1406*85732ac8SCy Schubert 1407*85732ac8SCy Schubert if (clear) { 1408*85732ac8SCy Schubert mp_forcezero(point->x); 1409*85732ac8SCy Schubert mp_forcezero(point->y); 1410*85732ac8SCy Schubert mp_forcezero(point->z); 1411*85732ac8SCy Schubert } 1412*85732ac8SCy Schubert wc_ecc_del_point(point); 1413*85732ac8SCy Schubert } 1414*85732ac8SCy Schubert 1415*85732ac8SCy Schubert 1416*85732ac8SCy Schubert int crypto_ec_point_x(struct crypto_ec *e, const struct crypto_ec_point *p, 1417*85732ac8SCy Schubert struct crypto_bignum *x) 1418*85732ac8SCy Schubert { 1419*85732ac8SCy Schubert return mp_copy(((ecc_point *) p)->x, (mp_int *) x) == MP_OKAY ? 0 : -1; 1420*85732ac8SCy Schubert } 1421*85732ac8SCy Schubert 1422*85732ac8SCy Schubert 1423*85732ac8SCy Schubert int crypto_ec_point_to_bin(struct crypto_ec *e, 1424*85732ac8SCy Schubert const struct crypto_ec_point *point, u8 *x, u8 *y) 1425*85732ac8SCy Schubert { 1426*85732ac8SCy Schubert ecc_point *p = (ecc_point *) point; 1427*85732ac8SCy Schubert 1428*85732ac8SCy Schubert if (TEST_FAIL()) 1429*85732ac8SCy Schubert return -1; 1430*85732ac8SCy Schubert 1431*85732ac8SCy Schubert if (!mp_isone(p->z)) { 1432*85732ac8SCy Schubert if (ecc_map(p, &e->prime, e->mont_b) != MP_OKAY) 1433*85732ac8SCy Schubert return -1; 1434*85732ac8SCy Schubert } 1435*85732ac8SCy Schubert 1436*85732ac8SCy Schubert if (x) { 1437*85732ac8SCy Schubert if (crypto_bignum_to_bin((struct crypto_bignum *)p->x, x, 1438*85732ac8SCy Schubert e->key.dp->size, 1439*85732ac8SCy Schubert e->key.dp->size) <= 0) 1440*85732ac8SCy Schubert return -1; 1441*85732ac8SCy Schubert } 1442*85732ac8SCy Schubert 1443*85732ac8SCy Schubert if (y) { 1444*85732ac8SCy Schubert if (crypto_bignum_to_bin((struct crypto_bignum *) p->y, y, 1445*85732ac8SCy Schubert e->key.dp->size, 1446*85732ac8SCy Schubert e->key.dp->size) <= 0) 1447*85732ac8SCy Schubert return -1; 1448*85732ac8SCy Schubert } 1449*85732ac8SCy Schubert 1450*85732ac8SCy Schubert return 0; 1451*85732ac8SCy Schubert } 1452*85732ac8SCy Schubert 1453*85732ac8SCy Schubert 1454*85732ac8SCy Schubert struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e, 1455*85732ac8SCy Schubert const u8 *val) 1456*85732ac8SCy Schubert { 1457*85732ac8SCy Schubert ecc_point *point = NULL; 1458*85732ac8SCy Schubert int loaded = 0; 1459*85732ac8SCy Schubert 1460*85732ac8SCy Schubert if (TEST_FAIL()) 1461*85732ac8SCy Schubert return NULL; 1462*85732ac8SCy Schubert 1463*85732ac8SCy Schubert point = wc_ecc_new_point(); 1464*85732ac8SCy Schubert if (!point) 1465*85732ac8SCy Schubert goto done; 1466*85732ac8SCy Schubert 1467*85732ac8SCy Schubert if (mp_read_unsigned_bin(point->x, val, e->key.dp->size) != MP_OKAY) 1468*85732ac8SCy Schubert goto done; 1469*85732ac8SCy Schubert val += e->key.dp->size; 1470*85732ac8SCy Schubert if (mp_read_unsigned_bin(point->y, val, e->key.dp->size) != MP_OKAY) 1471*85732ac8SCy Schubert goto done; 1472*85732ac8SCy Schubert mp_set(point->z, 1); 1473*85732ac8SCy Schubert 1474*85732ac8SCy Schubert loaded = 1; 1475*85732ac8SCy Schubert done: 1476*85732ac8SCy Schubert if (!loaded) { 1477*85732ac8SCy Schubert wc_ecc_del_point(point); 1478*85732ac8SCy Schubert point = NULL; 1479*85732ac8SCy Schubert } 1480*85732ac8SCy Schubert return (struct crypto_ec_point *) point; 1481*85732ac8SCy Schubert } 1482*85732ac8SCy Schubert 1483*85732ac8SCy Schubert 1484*85732ac8SCy Schubert int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a, 1485*85732ac8SCy Schubert const struct crypto_ec_point *b, 1486*85732ac8SCy Schubert struct crypto_ec_point *c) 1487*85732ac8SCy Schubert { 1488*85732ac8SCy Schubert mp_int mu; 1489*85732ac8SCy Schubert ecc_point *ta = NULL, *tb = NULL; 1490*85732ac8SCy Schubert ecc_point *pa = (ecc_point *) a, *pb = (ecc_point *) b; 1491*85732ac8SCy Schubert mp_int *modulus = &e->prime; 1492*85732ac8SCy Schubert int ret; 1493*85732ac8SCy Schubert 1494*85732ac8SCy Schubert if (TEST_FAIL()) 1495*85732ac8SCy Schubert return -1; 1496*85732ac8SCy Schubert 1497*85732ac8SCy Schubert ret = mp_init(&mu); 1498*85732ac8SCy Schubert if (ret != MP_OKAY) 1499*85732ac8SCy Schubert return -1; 1500*85732ac8SCy Schubert 1501*85732ac8SCy Schubert ret = mp_montgomery_calc_normalization(&mu, modulus); 1502*85732ac8SCy Schubert if (ret != MP_OKAY) { 1503*85732ac8SCy Schubert mp_clear(&mu); 1504*85732ac8SCy Schubert return -1; 1505*85732ac8SCy Schubert } 1506*85732ac8SCy Schubert 1507*85732ac8SCy Schubert if (!mp_isone(&mu)) { 1508*85732ac8SCy Schubert ta = wc_ecc_new_point(); 1509*85732ac8SCy Schubert if (!ta) { 1510*85732ac8SCy Schubert mp_clear(&mu); 1511*85732ac8SCy Schubert return -1; 1512*85732ac8SCy Schubert } 1513*85732ac8SCy Schubert tb = wc_ecc_new_point(); 1514*85732ac8SCy Schubert if (!tb) { 1515*85732ac8SCy Schubert wc_ecc_del_point(ta); 1516*85732ac8SCy Schubert mp_clear(&mu); 1517*85732ac8SCy Schubert return -1; 1518*85732ac8SCy Schubert } 1519*85732ac8SCy Schubert 1520*85732ac8SCy Schubert if (mp_mulmod(pa->x, &mu, modulus, ta->x) != MP_OKAY || 1521*85732ac8SCy Schubert mp_mulmod(pa->y, &mu, modulus, ta->y) != MP_OKAY || 1522*85732ac8SCy Schubert mp_mulmod(pa->z, &mu, modulus, ta->z) != MP_OKAY || 1523*85732ac8SCy Schubert mp_mulmod(pb->x, &mu, modulus, tb->x) != MP_OKAY || 1524*85732ac8SCy Schubert mp_mulmod(pb->y, &mu, modulus, tb->y) != MP_OKAY || 1525*85732ac8SCy Schubert mp_mulmod(pb->z, &mu, modulus, tb->z) != MP_OKAY) { 1526*85732ac8SCy Schubert ret = -1; 1527*85732ac8SCy Schubert goto end; 1528*85732ac8SCy Schubert } 1529*85732ac8SCy Schubert pa = ta; 1530*85732ac8SCy Schubert pb = tb; 1531*85732ac8SCy Schubert } 1532*85732ac8SCy Schubert 1533*85732ac8SCy Schubert ret = ecc_projective_add_point(pa, pb, (ecc_point *) c, &e->a, 1534*85732ac8SCy Schubert &e->prime, e->mont_b); 1535*85732ac8SCy Schubert if (ret != 0) { 1536*85732ac8SCy Schubert ret = -1; 1537*85732ac8SCy Schubert goto end; 1538*85732ac8SCy Schubert } 1539*85732ac8SCy Schubert 1540*85732ac8SCy Schubert if (ecc_map((ecc_point *) c, &e->prime, e->mont_b) != MP_OKAY) 1541*85732ac8SCy Schubert ret = -1; 1542*85732ac8SCy Schubert else 1543*85732ac8SCy Schubert ret = 0; 1544*85732ac8SCy Schubert end: 1545*85732ac8SCy Schubert wc_ecc_del_point(tb); 1546*85732ac8SCy Schubert wc_ecc_del_point(ta); 1547*85732ac8SCy Schubert mp_clear(&mu); 1548*85732ac8SCy Schubert return ret; 1549*85732ac8SCy Schubert } 1550*85732ac8SCy Schubert 1551*85732ac8SCy Schubert 1552*85732ac8SCy Schubert int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p, 1553*85732ac8SCy Schubert const struct crypto_bignum *b, 1554*85732ac8SCy Schubert struct crypto_ec_point *res) 1555*85732ac8SCy Schubert { 1556*85732ac8SCy Schubert int ret; 1557*85732ac8SCy Schubert 1558*85732ac8SCy Schubert if (TEST_FAIL()) 1559*85732ac8SCy Schubert return -1; 1560*85732ac8SCy Schubert 1561*85732ac8SCy Schubert ret = wc_ecc_mulmod((mp_int *) b, (ecc_point *) p, (ecc_point *) res, 1562*85732ac8SCy Schubert &e->a, &e->prime, 1); 1563*85732ac8SCy Schubert return ret == 0 ? 0 : -1; 1564*85732ac8SCy Schubert } 1565*85732ac8SCy Schubert 1566*85732ac8SCy Schubert 1567*85732ac8SCy Schubert int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p) 1568*85732ac8SCy Schubert { 1569*85732ac8SCy Schubert ecc_point *point = (ecc_point *) p; 1570*85732ac8SCy Schubert 1571*85732ac8SCy Schubert if (TEST_FAIL()) 1572*85732ac8SCy Schubert return -1; 1573*85732ac8SCy Schubert 1574*85732ac8SCy Schubert if (mp_sub(&e->prime, point->y, point->y) != MP_OKAY) 1575*85732ac8SCy Schubert return -1; 1576*85732ac8SCy Schubert 1577*85732ac8SCy Schubert return 0; 1578*85732ac8SCy Schubert } 1579*85732ac8SCy Schubert 1580*85732ac8SCy Schubert 1581*85732ac8SCy Schubert int crypto_ec_point_solve_y_coord(struct crypto_ec *e, 1582*85732ac8SCy Schubert struct crypto_ec_point *p, 1583*85732ac8SCy Schubert const struct crypto_bignum *x, int y_bit) 1584*85732ac8SCy Schubert { 1585*85732ac8SCy Schubert byte buf[1 + 2 * MAX_ECC_BYTES]; 1586*85732ac8SCy Schubert int ret; 1587*85732ac8SCy Schubert int prime_len = crypto_ec_prime_len(e); 1588*85732ac8SCy Schubert 1589*85732ac8SCy Schubert if (TEST_FAIL()) 1590*85732ac8SCy Schubert return -1; 1591*85732ac8SCy Schubert 1592*85732ac8SCy Schubert buf[0] = y_bit ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN; 1593*85732ac8SCy Schubert ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len); 1594*85732ac8SCy Schubert if (ret <= 0) 1595*85732ac8SCy Schubert return -1; 1596*85732ac8SCy Schubert ret = wc_ecc_import_point_der(buf, 1 + 2 * ret, e->key.idx, 1597*85732ac8SCy Schubert (ecc_point *) p); 1598*85732ac8SCy Schubert if (ret != 0) 1599*85732ac8SCy Schubert return -1; 1600*85732ac8SCy Schubert 1601*85732ac8SCy Schubert return 0; 1602*85732ac8SCy Schubert } 1603*85732ac8SCy Schubert 1604*85732ac8SCy Schubert 1605*85732ac8SCy Schubert struct crypto_bignum * 1606*85732ac8SCy Schubert crypto_ec_point_compute_y_sqr(struct crypto_ec *e, 1607*85732ac8SCy Schubert const struct crypto_bignum *x) 1608*85732ac8SCy Schubert { 1609*85732ac8SCy Schubert mp_int *y2 = NULL; 1610*85732ac8SCy Schubert mp_int t; 1611*85732ac8SCy Schubert int calced = 0; 1612*85732ac8SCy Schubert 1613*85732ac8SCy Schubert if (TEST_FAIL()) 1614*85732ac8SCy Schubert return NULL; 1615*85732ac8SCy Schubert 1616*85732ac8SCy Schubert if (mp_init(&t) != MP_OKAY) 1617*85732ac8SCy Schubert return NULL; 1618*85732ac8SCy Schubert 1619*85732ac8SCy Schubert y2 = (mp_int *) crypto_bignum_init(); 1620*85732ac8SCy Schubert if (!y2) 1621*85732ac8SCy Schubert goto done; 1622*85732ac8SCy Schubert 1623*85732ac8SCy Schubert if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 || 1624*85732ac8SCy Schubert mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 || 1625*85732ac8SCy Schubert mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 || 1626*85732ac8SCy Schubert mp_addmod(y2, &t, &e->prime, y2) != 0 || 1627*85732ac8SCy Schubert mp_addmod(y2, &e->b, &e->prime, y2) != 0) 1628*85732ac8SCy Schubert goto done; 1629*85732ac8SCy Schubert 1630*85732ac8SCy Schubert calced = 1; 1631*85732ac8SCy Schubert done: 1632*85732ac8SCy Schubert if (!calced) { 1633*85732ac8SCy Schubert if (y2) { 1634*85732ac8SCy Schubert mp_clear(y2); 1635*85732ac8SCy Schubert os_free(y2); 1636*85732ac8SCy Schubert } 1637*85732ac8SCy Schubert mp_clear(&t); 1638*85732ac8SCy Schubert } 1639*85732ac8SCy Schubert 1640*85732ac8SCy Schubert return (struct crypto_bignum *) y2; 1641*85732ac8SCy Schubert } 1642*85732ac8SCy Schubert 1643*85732ac8SCy Schubert 1644*85732ac8SCy Schubert int crypto_ec_point_is_at_infinity(struct crypto_ec *e, 1645*85732ac8SCy Schubert const struct crypto_ec_point *p) 1646*85732ac8SCy Schubert { 1647*85732ac8SCy Schubert return wc_ecc_point_is_at_infinity((ecc_point *) p); 1648*85732ac8SCy Schubert } 1649*85732ac8SCy Schubert 1650*85732ac8SCy Schubert 1651*85732ac8SCy Schubert int crypto_ec_point_is_on_curve(struct crypto_ec *e, 1652*85732ac8SCy Schubert const struct crypto_ec_point *p) 1653*85732ac8SCy Schubert { 1654*85732ac8SCy Schubert return wc_ecc_is_point((ecc_point *) p, &e->a, &e->b, &e->prime) == 1655*85732ac8SCy Schubert MP_OKAY; 1656*85732ac8SCy Schubert } 1657*85732ac8SCy Schubert 1658*85732ac8SCy Schubert 1659*85732ac8SCy Schubert int crypto_ec_point_cmp(const struct crypto_ec *e, 1660*85732ac8SCy Schubert const struct crypto_ec_point *a, 1661*85732ac8SCy Schubert const struct crypto_ec_point *b) 1662*85732ac8SCy Schubert { 1663*85732ac8SCy Schubert return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b); 1664*85732ac8SCy Schubert } 1665*85732ac8SCy Schubert 1666*85732ac8SCy Schubert 1667*85732ac8SCy Schubert struct crypto_ecdh { 1668*85732ac8SCy Schubert struct crypto_ec *ec; 1669*85732ac8SCy Schubert }; 1670*85732ac8SCy Schubert 1671*85732ac8SCy Schubert struct crypto_ecdh * crypto_ecdh_init(int group) 1672*85732ac8SCy Schubert { 1673*85732ac8SCy Schubert struct crypto_ecdh *ecdh = NULL; 1674*85732ac8SCy Schubert WC_RNG rng; 1675*85732ac8SCy Schubert int ret; 1676*85732ac8SCy Schubert 1677*85732ac8SCy Schubert if (wc_InitRng(&rng) != 0) 1678*85732ac8SCy Schubert goto fail; 1679*85732ac8SCy Schubert 1680*85732ac8SCy Schubert ecdh = os_zalloc(sizeof(*ecdh)); 1681*85732ac8SCy Schubert if (!ecdh) 1682*85732ac8SCy Schubert goto fail; 1683*85732ac8SCy Schubert 1684*85732ac8SCy Schubert ecdh->ec = crypto_ec_init(group); 1685*85732ac8SCy Schubert if (!ecdh->ec) 1686*85732ac8SCy Schubert goto fail; 1687*85732ac8SCy Schubert 1688*85732ac8SCy Schubert ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key, 1689*85732ac8SCy Schubert ecdh->ec->key.dp->id); 1690*85732ac8SCy Schubert if (ret < 0) 1691*85732ac8SCy Schubert goto fail; 1692*85732ac8SCy Schubert 1693*85732ac8SCy Schubert done: 1694*85732ac8SCy Schubert wc_FreeRng(&rng); 1695*85732ac8SCy Schubert 1696*85732ac8SCy Schubert return ecdh; 1697*85732ac8SCy Schubert fail: 1698*85732ac8SCy Schubert crypto_ecdh_deinit(ecdh); 1699*85732ac8SCy Schubert ecdh = NULL; 1700*85732ac8SCy Schubert goto done; 1701*85732ac8SCy Schubert } 1702*85732ac8SCy Schubert 1703*85732ac8SCy Schubert 1704*85732ac8SCy Schubert void crypto_ecdh_deinit(struct crypto_ecdh *ecdh) 1705*85732ac8SCy Schubert { 1706*85732ac8SCy Schubert if (ecdh) { 1707*85732ac8SCy Schubert crypto_ec_deinit(ecdh->ec); 1708*85732ac8SCy Schubert os_free(ecdh); 1709*85732ac8SCy Schubert } 1710*85732ac8SCy Schubert } 1711*85732ac8SCy Schubert 1712*85732ac8SCy Schubert 1713*85732ac8SCy Schubert struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y) 1714*85732ac8SCy Schubert { 1715*85732ac8SCy Schubert struct wpabuf *buf = NULL; 1716*85732ac8SCy Schubert int ret; 1717*85732ac8SCy Schubert int len = ecdh->ec->key.dp->size; 1718*85732ac8SCy Schubert 1719*85732ac8SCy Schubert buf = wpabuf_alloc(inc_y ? 2 * len : len); 1720*85732ac8SCy Schubert if (!buf) 1721*85732ac8SCy Schubert goto fail; 1722*85732ac8SCy Schubert 1723*85732ac8SCy Schubert ret = crypto_bignum_to_bin((struct crypto_bignum *) 1724*85732ac8SCy Schubert ecdh->ec->key.pubkey.x, wpabuf_put(buf, len), 1725*85732ac8SCy Schubert len, len); 1726*85732ac8SCy Schubert if (ret < 0) 1727*85732ac8SCy Schubert goto fail; 1728*85732ac8SCy Schubert if (inc_y) { 1729*85732ac8SCy Schubert ret = crypto_bignum_to_bin((struct crypto_bignum *) 1730*85732ac8SCy Schubert ecdh->ec->key.pubkey.y, 1731*85732ac8SCy Schubert wpabuf_put(buf, len), len, len); 1732*85732ac8SCy Schubert if (ret < 0) 1733*85732ac8SCy Schubert goto fail; 1734*85732ac8SCy Schubert } 1735*85732ac8SCy Schubert 1736*85732ac8SCy Schubert done: 1737*85732ac8SCy Schubert return buf; 1738*85732ac8SCy Schubert fail: 1739*85732ac8SCy Schubert wpabuf_free(buf); 1740*85732ac8SCy Schubert buf = NULL; 1741*85732ac8SCy Schubert goto done; 1742*85732ac8SCy Schubert } 1743*85732ac8SCy Schubert 1744*85732ac8SCy Schubert 1745*85732ac8SCy Schubert struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y, 1746*85732ac8SCy Schubert const u8 *key, size_t len) 1747*85732ac8SCy Schubert { 1748*85732ac8SCy Schubert int ret; 1749*85732ac8SCy Schubert struct wpabuf *pubkey = NULL; 1750*85732ac8SCy Schubert struct wpabuf *secret = NULL; 1751*85732ac8SCy Schubert word32 key_len = ecdh->ec->key.dp->size; 1752*85732ac8SCy Schubert ecc_point *point = NULL; 1753*85732ac8SCy Schubert size_t need_key_len = inc_y ? 2 * key_len : key_len; 1754*85732ac8SCy Schubert 1755*85732ac8SCy Schubert if (len < need_key_len) 1756*85732ac8SCy Schubert goto fail; 1757*85732ac8SCy Schubert pubkey = wpabuf_alloc(1 + 2 * key_len); 1758*85732ac8SCy Schubert if (!pubkey) 1759*85732ac8SCy Schubert goto fail; 1760*85732ac8SCy Schubert wpabuf_put_u8(pubkey, inc_y ? ECC_POINT_UNCOMP : ECC_POINT_COMP_EVEN); 1761*85732ac8SCy Schubert wpabuf_put_data(pubkey, key, need_key_len); 1762*85732ac8SCy Schubert 1763*85732ac8SCy Schubert point = wc_ecc_new_point(); 1764*85732ac8SCy Schubert if (!point) 1765*85732ac8SCy Schubert goto fail; 1766*85732ac8SCy Schubert 1767*85732ac8SCy Schubert ret = wc_ecc_import_point_der(wpabuf_mhead(pubkey), 1 + 2 * key_len, 1768*85732ac8SCy Schubert ecdh->ec->key.idx, point); 1769*85732ac8SCy Schubert if (ret != MP_OKAY) 1770*85732ac8SCy Schubert goto fail; 1771*85732ac8SCy Schubert 1772*85732ac8SCy Schubert secret = wpabuf_alloc(key_len); 1773*85732ac8SCy Schubert if (!secret) 1774*85732ac8SCy Schubert goto fail; 1775*85732ac8SCy Schubert 1776*85732ac8SCy Schubert ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point, 1777*85732ac8SCy Schubert wpabuf_put(secret, key_len), &key_len); 1778*85732ac8SCy Schubert if (ret != MP_OKAY) 1779*85732ac8SCy Schubert goto fail; 1780*85732ac8SCy Schubert 1781*85732ac8SCy Schubert done: 1782*85732ac8SCy Schubert wc_ecc_del_point(point); 1783*85732ac8SCy Schubert wpabuf_free(pubkey); 1784*85732ac8SCy Schubert return secret; 1785*85732ac8SCy Schubert fail: 1786*85732ac8SCy Schubert wpabuf_free(secret); 1787*85732ac8SCy Schubert secret = NULL; 1788*85732ac8SCy Schubert goto done; 1789*85732ac8SCy Schubert } 1790*85732ac8SCy Schubert 1791*85732ac8SCy Schubert #endif /* CONFIG_ECC */ 1792