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