18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant / Crypto wrapper for LibTomCrypt (for internal TLSv1) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <tomcrypt.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef mp_init_multi 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_init_multi ltc_init_multi 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_clear_multi ltc_deinit_multi 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_state md; 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md4_init(&md); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md4_process(&md, addr[i], len[i]); 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md4_done(&md, mac); 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 pkey[8], next, tmp; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key skey; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Add parity bits to the key */ 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = 0; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 7; i++) { 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = key[i]; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = (tmp >> i) | next | 1; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt next = tmp << (7 - i); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkey[i] = next | 1; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt des_setup(pkey, 8, 0, &skey); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt des_ecb_encrypt(clear, cypher, &skey); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt des_done(&skey); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_state md; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md5_init(&md); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md5_process(&md, addr[i], len[i]); 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt md5_done(&md, mac); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_state md; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sha1_init(&md); 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_elem; i++) 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sha1_process(&md, addr[i], len[i]); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sha1_done(&md, mac); 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_encrypt_init(const u8 *key, size_t len) 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt skey = os_malloc(sizeof(*skey)); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (skey == NULL) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_setup(key, len, 0, skey) != CRYPT_OK) { 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(skey); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return skey; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey = ctx; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_ecb_encrypt(plain, crypt, skey); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_encrypt_deinit(void *ctx) 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey = ctx; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_done(skey); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(skey); 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * aes_decrypt_init(const u8 *key, size_t len) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt skey = os_malloc(sizeof(*skey)); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (skey == NULL) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (aes_setup(key, len, 0, skey) != CRYPT_OK) { 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(skey); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return skey; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey = ctx; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_ecb_encrypt(plain, (u8 *) crypt, skey); 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid aes_decrypt_deinit(void *ctx) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_key *skey = ctx; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt aes_done(skey); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(skey); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_hash { 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt enum crypto_hash_alg alg; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int error; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hash_state md; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_state hmac; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } u; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key, 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_hash *ctx; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->alg = alg; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_MD5: 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md5_init(&ctx->u.md) != CRYPT_OK) 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_SHA1: 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha1_init(&ctx->u.md) != CRYPT_OK) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_MD5: 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac_init(&ctx->u.hmac, find_hash("md5"), key, key_len) != 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_OK) 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_SHA1: 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac_init(&ctx->u.hmac, find_hash("sha1"), key, key_len) != 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CRYPT_OK) 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ctx; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL || ctx->error) 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ctx->alg) { 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_MD5: 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->error = md5_process(&ctx->u.md, data, len) != CRYPT_OK; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_SHA1: 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->error = sha1_process(&ctx->u.md, data, len) != CRYPT_OK; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_MD5: 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_SHA1: 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->error = hmac_process(&ctx->u.hmac, data, len) != CRYPT_OK; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len) 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long clen; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mac == NULL || len == NULL) { 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx->error) { 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -2; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ctx->alg) { 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_MD5: 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 16) { 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 16; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 16; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (md5_done(&ctx->u.md, mac) != CRYPT_OK) 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_SHA1: 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 20) { 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 20; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 20; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sha1_done(&ctx->u.md, mac) != CRYPT_OK) 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_SHA1: 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 20) { 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 20; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* continue */ 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_HASH_ALG_HMAC_MD5: 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*len < 16) { 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = 16; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clen = *len; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (hmac_done(&ctx->u.hmac, mac, &clen) != CRYPT_OK) { 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = clen; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -2; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher { 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int rc4; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt union { 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt symmetric_CBC cbc; 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct { 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t used_bytes; 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 key[16]; 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t keylen; 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } rc4; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } u; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *iv, const u8 *key, 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t key_len) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_cipher *ctx; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int idx, res, rc4 = 0; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (alg) { 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_AES: 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = find_cipher("aes"); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_3DES: 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = find_cipher("3des"); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_DES: 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = find_cipher("des"); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC2: 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = find_cipher("rc2"); 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case CRYPTO_CIPHER_ALG_RC4: 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt idx = -1; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4 = 1; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx == NULL) 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rc4) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->rc4 = 1; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key_len > sizeof(ctx->u.rc4.key)) { 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->u.rc4.keylen = key_len; 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(ctx->u.rc4.key, key, key_len); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = cbc_start(idx, iv, key, key_len, 0, &ctx->u.cbc); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "LibTomCrypt: Cipher start " 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %s", error_to_string(res)); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ctx; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *crypt, size_t len) 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx->rc4) { 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plain != crypt) 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(crypt, plain, len); 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->u.rc4.used_bytes, crypt, len); 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->u.rc4.used_bytes += len; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = cbc_encrypt(plain, crypt, len, &ctx->u.cbc); 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC encryption " 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %s", error_to_string(res)); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t len) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ctx->rc4) { 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (plain != crypt) 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(plain, crypt, len); 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rc4_skip(ctx->u.rc4.key, ctx->u.rc4.keylen, 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->u.rc4.used_bytes, plain, len); 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ctx->u.rc4.used_bytes += len; 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = cbc_decrypt(crypt, plain, len, &ctx->u.cbc); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "LibTomCrypt: CBC decryption " 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed: %s", error_to_string(res)); 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_cipher_deinit(struct crypto_cipher *ctx) 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!ctx->rc4) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt cbc_done(&ctx->u.cbc); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(ctx); 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key { 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_key rsa; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_private_key { 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_key rsa; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len) 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_public_key *pk; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pk = os_zalloc(sizeof(*pk)); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk == NULL) 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = rsa_import(key, len, &pk->rsa); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import " 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "public key (res=%d '%s')", 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res, error_to_string(res)); 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk->rsa.type != PK_PUBLIC) { 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "LibTomCrypt: Public key was not of " 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "correct type"); 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_free(&pk->rsa); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pk; 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_private_key * crypto_private_key_import(const u8 *key, 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len, 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *passwd) 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct crypto_private_key *pk; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pk = os_zalloc(sizeof(*pk)); 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk == NULL) 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = rsa_import(key, len, &pk->rsa); 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "LibTomCrypt: Failed to import " 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "private key (res=%d '%s')", 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res, error_to_string(res)); 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk->rsa.type != PK_PRIVATE) { 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "LibTomCrypt: Private key was not of " 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "correct type"); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_free(&pk->rsa); 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(pk); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pk; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct crypto_public_key * crypto_public_key_from_cert(const u8 *buf, 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No X.509 support in LibTomCrypt */ 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int pkcs1_generate_encryption_block(u8 block_type, size_t modlen, 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t ps_len; 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #1 v1.5, 8.1: 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EB = 00 || BT || PS || 00 || D 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BT = 00 or 01 for private-key operation; 02 for public-key operation 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PS = k-3-||D||; at least eight octets 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (BT=0: PS=0x00, BT=1: PS=0xff, BT=2: PS=pseudorandom non-zero) 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * k = length of modulus in octets (modlen) 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (modlen < 12 || modlen > *outlen || inlen > modlen - 11) { 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Invalid buffer " 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "lengths (modlen=%lu outlen=%lu inlen=%lu)", 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned long) modlen, 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) *outlen, 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) inlen); 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = out; 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x00; 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = block_type; /* BT */ 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ps_len = modlen - inlen - 3; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (block_type) { 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 0: 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0x00, ps_len); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ps_len; 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 1: 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(pos, 0xff, ps_len); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += ps_len; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 2: 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_get_random(pos, ps_len) < 0) { 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Failed to get " 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "random data for PS", __func__); 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (ps_len--) { 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == 0x00) 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = 0x01; 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "PKCS #1: %s - Unsupported block type " 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%d", __func__, block_type); 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = 0x00; 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, in, inlen); /* D */ 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int crypto_rsa_encrypt_pkcs1(int block_type, rsa_key *key, int key_type, 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long len, modlen; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt modlen = mp_unsigned_bin_size(key->N); 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pkcs1_generate_encryption_block(block_type, modlen, in, inlen, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, outlen) < 0) 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = *outlen; 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = rsa_exptmod(out, modlen, out, &len, key_type, key); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s", 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error_to_string(res)); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *outlen = len; 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key, 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return crypto_rsa_encrypt_pkcs1(2, &key->rsa, PK_PUBLIC, in, inlen, 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, outlen); 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_private_key_sign_pkcs1(struct crypto_private_key *key, 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *in, size_t inlen, 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t *outlen) 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return crypto_rsa_encrypt_pkcs1(1, &key->rsa, PK_PRIVATE, in, inlen, 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out, outlen); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_public_key_free(struct crypto_public_key *key) 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key) { 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_free(&key->rsa); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(key); 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_private_key_free(struct crypto_private_key *key) 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key) { 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rsa_free(&key->rsa); 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(key); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_public_key_decrypt_pkcs1(struct crypto_public_key *key, 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *crypt, size_t crypt_len, 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *plain, size_t *plain_len) 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned long len; 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos; 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = *plain_len; 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = rsa_exptmod(crypt, crypt_len, plain, &len, PK_PUBLIC, 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &key->rsa); 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res != CRYPT_OK) { 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "LibTomCrypt: rsa_exptmod failed: %s", 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt error_to_string(res)); 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PKCS #1 v1.5, 8.1: 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EB = 00 || BT || PS || 00 || D 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * BT = 01 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PS = k-3-||D|| times FF 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * k = length of modulus in octets 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len < 3 + 8 + 16 /* min hash len */ || 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plain[0] != 0x00 || plain[1] != 0x01 || plain[2] != 0xff) { 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "structure"); 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = plain + 3; 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos < plain + len && *pos == 0xff) 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos - plain - 2 < 8) { 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* PKCS #1 v1.5, 8.1: At least eight octets long PS */ 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature " 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "padding"); 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 16 /* min hash len */ >= plain + len || *pos != 0x00) { 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB " 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "structure (2)"); 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len -= pos - plain; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Strip PKCS #1 header */ 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memmove(plain, pos, len); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *plain_len = len; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_global_init(void) 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ltc_mp = tfm_desc; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: only register algorithms that are really needed */ 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (register_hash(&md4_desc) < 0 || 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt register_hash(&md5_desc) < 0 || 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt register_hash(&sha1_desc) < 0 || 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt register_cipher(&aes_desc) < 0 || 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt register_cipher(&des_desc) < 0 || 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt register_cipher(&des3_desc) < 0) { 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLSv1: Failed to register " 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "hash/cipher functions"); 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid crypto_global_deinit(void) 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_MODEXP 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint crypto_mod_exp(const u8 *base, size_t base_len, 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *power, size_t power_len, 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *modulus, size_t modulus_len, 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *result, size_t *result_len) 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *b, *p, *m, *r; 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mp_init_multi(&b, &p, &m, &r, NULL) != CRYPT_OK) 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mp_read_unsigned_bin(b, (u8 *) base, base_len) != CRYPT_OK || 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mp_read_unsigned_bin(p, (u8 *) power, power_len) != CRYPT_OK || 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mp_read_unsigned_bin(m, (u8 *) modulus, modulus_len) != CRYPT_OK) 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mp_exptmod(b, p, m, r) != CRYPT_OK) 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *result_len = mp_unsigned_bin_size(r); 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (mp_to_unsigned_bin(r, result) != CRYPT_OK) 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mp_clear_multi(b, p, m, r, NULL); 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mp_clear_multi(b, p, m, r, NULL); 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_MODEXP */ 727