1/* 2 * WPA Supplicant / wrapper functions for libgcrypt 3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9#include "includes.h" 10#include <gcrypt.h> 11 12#include "common.h" 13#include "crypto.h" 14 15int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 16{ 17 gcry_md_hd_t hd; 18 unsigned char *p; 19 size_t i; 20 21 if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR) 22 return -1; 23 for (i = 0; i < num_elem; i++) 24 gcry_md_write(hd, addr[i], len[i]); 25 p = gcry_md_read(hd, GCRY_MD_MD4); 26 if (p) 27 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4)); 28 gcry_md_close(hd); 29 return 0; 30} 31 32 33int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 34{ 35 gcry_cipher_hd_t hd; 36 u8 pkey[8], next, tmp; 37 int i; 38 39 /* Add parity bits to the key */ 40 next = 0; 41 for (i = 0; i < 7; i++) { 42 tmp = key[i]; 43 pkey[i] = (tmp >> i) | next | 1; 44 next = tmp << (7 - i); 45 } 46 pkey[i] = next | 1; 47 48 gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); 49 gcry_err_code(gcry_cipher_setkey(hd, pkey, 8)); 50 gcry_cipher_encrypt(hd, cypher, 8, clear, 8); 51 gcry_cipher_close(hd); 52 return 0; 53} 54 55 56int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 57{ 58 gcry_md_hd_t hd; 59 unsigned char *p; 60 size_t i; 61 62 if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR) 63 return -1; 64 for (i = 0; i < num_elem; i++) 65 gcry_md_write(hd, addr[i], len[i]); 66 p = gcry_md_read(hd, GCRY_MD_MD5); 67 if (p) 68 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5)); 69 gcry_md_close(hd); 70 return 0; 71} 72 73 74int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 75{ 76 gcry_md_hd_t hd; 77 unsigned char *p; 78 size_t i; 79 80 if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR) 81 return -1; 82 for (i = 0; i < num_elem; i++) 83 gcry_md_write(hd, addr[i], len[i]); 84 p = gcry_md_read(hd, GCRY_MD_SHA1); 85 if (p) 86 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1)); 87 gcry_md_close(hd); 88 return 0; 89} 90 91 92void * aes_encrypt_init(const u8 *key, size_t len) 93{ 94 gcry_cipher_hd_t hd; 95 96 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 97 GPG_ERR_NO_ERROR) { 98 printf("cipher open failed\n"); 99 return NULL; 100 } 101 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 102 printf("setkey failed\n"); 103 gcry_cipher_close(hd); 104 return NULL; 105 } 106 107 return hd; 108} 109 110 111int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 112{ 113 gcry_cipher_hd_t hd = ctx; 114 gcry_cipher_encrypt(hd, crypt, 16, plain, 16); 115 return 0; 116} 117 118 119void aes_encrypt_deinit(void *ctx) 120{ 121 gcry_cipher_hd_t hd = ctx; 122 gcry_cipher_close(hd); 123} 124 125 126void * aes_decrypt_init(const u8 *key, size_t len) 127{ 128 gcry_cipher_hd_t hd; 129 130 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 131 GPG_ERR_NO_ERROR) 132 return NULL; 133 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 134 gcry_cipher_close(hd); 135 return NULL; 136 } 137 138 return hd; 139} 140 141 142int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 143{ 144 gcry_cipher_hd_t hd = ctx; 145 gcry_cipher_decrypt(hd, plain, 16, crypt, 16); 146 return 0; 147} 148 149 150void aes_decrypt_deinit(void *ctx) 151{ 152 gcry_cipher_hd_t hd = ctx; 153 gcry_cipher_close(hd); 154} 155 156 157int crypto_mod_exp(const u8 *base, size_t base_len, 158 const u8 *power, size_t power_len, 159 const u8 *modulus, size_t modulus_len, 160 u8 *result, size_t *result_len) 161{ 162 gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL, 163 bn_result = NULL; 164 int ret = -1; 165 166 if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) != 167 GPG_ERR_NO_ERROR || 168 gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) != 169 GPG_ERR_NO_ERROR || 170 gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len, 171 NULL) != GPG_ERR_NO_ERROR) 172 goto error; 173 bn_result = gcry_mpi_new(modulus_len * 8); 174 175 gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus); 176 177 if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len, 178 bn_result) != GPG_ERR_NO_ERROR) 179 goto error; 180 181 ret = 0; 182 183error: 184 gcry_mpi_release(bn_base); 185 gcry_mpi_release(bn_exp); 186 gcry_mpi_release(bn_modulus); 187 gcry_mpi_release(bn_result); 188 return ret; 189} 190 191 192struct crypto_cipher { 193 gcry_cipher_hd_t enc; 194 gcry_cipher_hd_t dec; 195}; 196 197 198struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 199 const u8 *iv, const u8 *key, 200 size_t key_len) 201{ 202 struct crypto_cipher *ctx; 203 gcry_error_t res; 204 enum gcry_cipher_algos a; 205 int ivlen; 206 207 ctx = os_zalloc(sizeof(*ctx)); 208 if (ctx == NULL) 209 return NULL; 210 211 switch (alg) { 212 case CRYPTO_CIPHER_ALG_RC4: 213 a = GCRY_CIPHER_ARCFOUR; 214 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM, 215 0); 216 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0); 217 break; 218 case CRYPTO_CIPHER_ALG_AES: 219 if (key_len == 24) 220 a = GCRY_CIPHER_AES192; 221 else if (key_len == 32) 222 a = GCRY_CIPHER_AES256; 223 else 224 a = GCRY_CIPHER_AES; 225 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 226 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 227 break; 228 case CRYPTO_CIPHER_ALG_3DES: 229 a = GCRY_CIPHER_3DES; 230 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 231 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 232 break; 233 case CRYPTO_CIPHER_ALG_DES: 234 a = GCRY_CIPHER_DES; 235 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 236 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 237 break; 238 case CRYPTO_CIPHER_ALG_RC2: 239 if (key_len == 5) 240 a = GCRY_CIPHER_RFC2268_40; 241 else 242 a = GCRY_CIPHER_RFC2268_128; 243 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 244 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 245 break; 246 default: 247 os_free(ctx); 248 return NULL; 249 } 250 251 if (res != GPG_ERR_NO_ERROR) { 252 os_free(ctx); 253 return NULL; 254 } 255 256 if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR || 257 gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) { 258 gcry_cipher_close(ctx->enc); 259 gcry_cipher_close(ctx->dec); 260 os_free(ctx); 261 return NULL; 262 } 263 264 ivlen = gcry_cipher_get_algo_blklen(a); 265 if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR || 266 gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) { 267 gcry_cipher_close(ctx->enc); 268 gcry_cipher_close(ctx->dec); 269 os_free(ctx); 270 return NULL; 271 } 272 273 return ctx; 274} 275 276 277int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 278 u8 *crypt, size_t len) 279{ 280 if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) != 281 GPG_ERR_NO_ERROR) 282 return -1; 283 return 0; 284} 285 286 287int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 288 u8 *plain, size_t len) 289{ 290 if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) != 291 GPG_ERR_NO_ERROR) 292 return -1; 293 return 0; 294} 295 296 297void crypto_cipher_deinit(struct crypto_cipher *ctx) 298{ 299 gcry_cipher_close(ctx->enc); 300 gcry_cipher_close(ctx->dec); 301 os_free(ctx); 302} 303