1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant / wrapper functions for libcrypto 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2005, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/opensslv.h> 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/md4.h> 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/md5.h> 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/sha.h> 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/des.h> 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/aes.h> 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/bn.h> 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <openssl/evp.h> 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "crypto.h" 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if OPENSSL_VERSION_NUMBER < 0x00907000 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define DES_key_schedule des_key_schedule 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define DES_cblock des_cblock 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define DES_set_key(key, schedule) des_set_key((key), *(schedule)) 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define DES_ecb_encrypt(input, output, ks, enc) \ 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt des_ecb_encrypt((input), (output), *(ks), (enc)) 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* openssl < 0.9.7 */ 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD4_CTX ctx; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD4_Init(&ctx); 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < num_elem; i++) 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD4_Update(&ctx, addr[i], len[i]); 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD4_Final(mac, &ctx); 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 pkey[8], next, tmp; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DES_key_schedule ks; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Add parity bits to the key */ 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = 0; 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 7; i++) { 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = key[i]; 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pkey[i] = (tmp >> i) | next | 1; 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = tmp << (7 - i); 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pkey[i] = next | 1; 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DES_set_key(&pkey, &ks); 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks, 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DES_ENCRYPT); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_CTX ctx; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_Init(&ctx); 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < num_elem; i++) 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_Update(&ctx, addr[i], len[i]); 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MD5_Final(mac, &ctx); 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA_CTX ctx; 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_Init(&ctx); 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < num_elem; i++) 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_Update(&ctx, addr[i], len[i]); 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_Final(mac, &ctx); 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef CONFIG_NO_FIPS186_2_PRF 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void sha1_transform(u8 *state, const u8 data[64]) 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA_CTX context; 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&context, 0, sizeof(context)); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(&context.h0, state, 5 * 4); 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SHA1_Transform(&context, data); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(state, &context.h0, 5 * 4); 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen) 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 xkey[64]; 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 t[5], _t[5]; 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i, j, m, k; 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *xpos = x; 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 carry; 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (seed_len > sizeof(xkey)) 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt seed_len = sizeof(xkey); 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIPS 186-2 + change notice 1 */ 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(xkey, seed, seed_len); 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(xkey + seed_len, 0, 64 - seed_len); 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[0] = 0x67452301; 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[1] = 0xEFCDAB89; 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[2] = 0x98BADCFE; 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[3] = 0x10325476; 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt t[4] = 0xC3D2E1F0; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt m = xlen / 40; 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (j = 0; j < m; j++) { 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XSEED_j = 0 */ 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 2; i++) { 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XVAL = (XKEY + XSEED_j) mod 2^b */ 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* w_i = G(t, XVAL) */ 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(_t, t, 20); 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sha1_transform((u8 *) _t, xkey); 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[0] = host_to_be32(_t[0]); 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[1] = host_to_be32(_t[1]); 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[2] = host_to_be32(_t[2]); 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[3] = host_to_be32(_t[3]); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _t[4] = host_to_be32(_t[4]); 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(xpos, _t, 20); 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* XKEY = (1 + XKEY + w_i) mod 2^b */ 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry = 1; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (k = 19; k >= 0; k--) { 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry += xkey[k] + xpos[k]; 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt xkey[k] = carry & 0xff; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt carry >>= 8; 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt xpos += 20; 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* x_j = w_0|w_1 */ 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_NO_FIPS186_2_PRF */ 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid * aes_encrypt_init(const u8 *key, size_t len) 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt AES_KEY *ak; 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ak = os_malloc(sizeof(*ak)); 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ak == NULL) 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (AES_set_encrypt_key(key, 8 * len, ak) < 0) { 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ak); 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ak; 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt AES_encrypt(plain, crypt, ctx); 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid aes_encrypt_deinit(void *ctx) 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid * aes_decrypt_init(const u8 *key, size_t len) 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt AES_KEY *ak; 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ak = os_malloc(sizeof(*ak)); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ak == NULL) 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (AES_set_decrypt_key(key, 8 * len, ak) < 0) { 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ak); 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ak; 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt AES_decrypt(crypt, plain, ctx); 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid aes_decrypt_deinit(void *ctx) 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint crypto_mod_exp(const u8 *base, size_t base_len, 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *power, size_t power_len, 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *modulus, size_t modulus_len, 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *result, size_t *result_len) 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result; 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = -1; 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_CTX *ctx; 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctx = BN_CTX_new(); 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctx == NULL) 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bn_base = BN_bin2bn(base, base_len, NULL); 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bn_exp = BN_bin2bn(power, power_len, NULL); 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bn_modulus = BN_bin2bn(modulus, modulus_len, NULL); 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bn_result = BN_new(); 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL || 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bn_result == NULL) 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto error; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1) 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto error; 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *result_len = BN_bn2bin(bn_result, result); 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = 0; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidterror: 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_free(bn_base); 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_free(bn_exp); 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_free(bn_modulus); 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_free(bn_result); 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BN_CTX_free(ctx); 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct crypto_cipher { 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX enc; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX dec; 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *iv, const u8 *key, 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t key_len) 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct crypto_cipher *ctx; 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const EVP_CIPHER *cipher; 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctx = os_zalloc(sizeof(*ctx)); 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctx == NULL) 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (alg) { 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef OPENSSL_NO_RC4 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CRYPTO_CIPHER_ALG_RC4: 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_rc4(); 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* OPENSSL_NO_RC4 */ 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef OPENSSL_NO_AES 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CRYPTO_CIPHER_ALG_AES: 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (key_len) { 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 16: 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_aes_128_cbc(); 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 24: 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_aes_192_cbc(); 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case 32: 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_aes_256_cbc(); 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* OPENSSL_NO_AES */ 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef OPENSSL_NO_DES 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CRYPTO_CIPHER_ALG_3DES: 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_des_ede3_cbc(); 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CRYPTO_CIPHER_ALG_DES: 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_des_cbc(); 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* OPENSSL_NO_DES */ 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef OPENSSL_NO_RC2 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case CRYPTO_CIPHER_ALG_RC2: 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt cipher = EVP_rc2_ecb(); 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* OPENSSL_NO_RC2 */ 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_init(&ctx->enc); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_set_padding(&ctx->enc, 0); 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) || 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) || 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, key, iv)) { 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_cleanup(&ctx->enc); 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_init(&ctx->dec); 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_set_padding(&ctx->dec, 0); 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) || 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) || 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt !EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, key, iv)) { 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_cleanup(&ctx->enc); 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_cleanup(&ctx->dec); 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ctx; 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *crypt, size_t len) 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int outl; 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len)) 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *plain, size_t len) 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int outl; 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outl = len; 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len)) 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid crypto_cipher_deinit(struct crypto_cipher *ctx) 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_cleanup(&ctx->enc); 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVP_CIPHER_CTX_cleanup(&ctx->dec); 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(ctx); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 361