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 33void 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} 53 54 55int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 56{ 57 gcry_md_hd_t hd; 58 unsigned char *p; 59 size_t i; 60 61 if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR) 62 return -1; 63 for (i = 0; i < num_elem; i++) 64 gcry_md_write(hd, addr[i], len[i]); 65 p = gcry_md_read(hd, GCRY_MD_MD5); 66 if (p) 67 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5)); 68 gcry_md_close(hd); 69 return 0; 70} 71 72 73int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 74{ 75 gcry_md_hd_t hd; 76 unsigned char *p; 77 size_t i; 78 79 if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR) 80 return -1; 81 for (i = 0; i < num_elem; i++) 82 gcry_md_write(hd, addr[i], len[i]); 83 p = gcry_md_read(hd, GCRY_MD_SHA1); 84 if (p) 85 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1)); 86 gcry_md_close(hd); 87 return 0; 88} 89 90 91void * aes_encrypt_init(const u8 *key, size_t len) 92{ 93 gcry_cipher_hd_t hd; 94 95 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 96 GPG_ERR_NO_ERROR) { 97 printf("cipher open failed\n"); 98 return NULL; 99 } 100 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 101 printf("setkey failed\n"); 102 gcry_cipher_close(hd); 103 return NULL; 104 } 105 106 return hd; 107} 108 109 110void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 111{ 112 gcry_cipher_hd_t hd = ctx; 113 gcry_cipher_encrypt(hd, crypt, 16, plain, 16); 114} 115 116 117void aes_encrypt_deinit(void *ctx) 118{ 119 gcry_cipher_hd_t hd = ctx; 120 gcry_cipher_close(hd); 121} 122 123 124void * aes_decrypt_init(const u8 *key, size_t len) 125{ 126 gcry_cipher_hd_t hd; 127 128 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 129 GPG_ERR_NO_ERROR) 130 return NULL; 131 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 132 gcry_cipher_close(hd); 133 return NULL; 134 } 135 136 return hd; 137} 138 139 140void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 141{ 142 gcry_cipher_hd_t hd = ctx; 143 gcry_cipher_decrypt(hd, plain, 16, crypt, 16); 144} 145 146 147void aes_decrypt_deinit(void *ctx) 148{ 149 gcry_cipher_hd_t hd = ctx; 150 gcry_cipher_close(hd); 151} 152 153 154int crypto_mod_exp(const u8 *base, size_t base_len, 155 const u8 *power, size_t power_len, 156 const u8 *modulus, size_t modulus_len, 157 u8 *result, size_t *result_len) 158{ 159 gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL, 160 bn_result = NULL; 161 int ret = -1; 162 163 if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) != 164 GPG_ERR_NO_ERROR || 165 gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) != 166 GPG_ERR_NO_ERROR || 167 gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len, 168 NULL) != GPG_ERR_NO_ERROR) 169 goto error; 170 bn_result = gcry_mpi_new(modulus_len * 8); 171 172 gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus); 173 174 if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len, 175 bn_result) != GPG_ERR_NO_ERROR) 176 goto error; 177 178 ret = 0; 179 180error: 181 gcry_mpi_release(bn_base); 182 gcry_mpi_release(bn_exp); 183 gcry_mpi_release(bn_modulus); 184 gcry_mpi_release(bn_result); 185 return ret; 186} 187 188 189struct crypto_cipher { 190 gcry_cipher_hd_t enc; 191 gcry_cipher_hd_t dec; 192}; 193 194 195struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 196 const u8 *iv, const u8 *key, 197 size_t key_len) 198{ 199 struct crypto_cipher *ctx; 200 gcry_error_t res; 201 enum gcry_cipher_algos a; 202 int ivlen; 203 204 ctx = os_zalloc(sizeof(*ctx)); 205 if (ctx == NULL) 206 return NULL; 207 208 switch (alg) { 209 case CRYPTO_CIPHER_ALG_RC4: 210 a = GCRY_CIPHER_ARCFOUR; 211 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM, 212 0); 213 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0); 214 break; 215 case CRYPTO_CIPHER_ALG_AES: 216 if (key_len == 24) 217 a = GCRY_CIPHER_AES192; 218 else if (key_len == 32) 219 a = GCRY_CIPHER_AES256; 220 else 221 a = GCRY_CIPHER_AES; 222 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 223 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 224 break; 225 case CRYPTO_CIPHER_ALG_3DES: 226 a = GCRY_CIPHER_3DES; 227 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 228 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 229 break; 230 case CRYPTO_CIPHER_ALG_DES: 231 a = GCRY_CIPHER_DES; 232 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 233 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 234 break; 235 case CRYPTO_CIPHER_ALG_RC2: 236 if (key_len == 5) 237 a = GCRY_CIPHER_RFC2268_40; 238 else 239 a = GCRY_CIPHER_RFC2268_128; 240 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 241 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 242 break; 243 default: 244 os_free(ctx); 245 return NULL; 246 } 247 248 if (res != GPG_ERR_NO_ERROR) { 249 os_free(ctx); 250 return NULL; 251 } 252 253 if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR || 254 gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) { 255 gcry_cipher_close(ctx->enc); 256 gcry_cipher_close(ctx->dec); 257 os_free(ctx); 258 return NULL; 259 } 260 261 ivlen = gcry_cipher_get_algo_blklen(a); 262 if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR || 263 gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) { 264 gcry_cipher_close(ctx->enc); 265 gcry_cipher_close(ctx->dec); 266 os_free(ctx); 267 return NULL; 268 } 269 270 return ctx; 271} 272 273 274int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 275 u8 *crypt, size_t len) 276{ 277 if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) != 278 GPG_ERR_NO_ERROR) 279 return -1; 280 return 0; 281} 282 283 284int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 285 u8 *plain, size_t len) 286{ 287 if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) != 288 GPG_ERR_NO_ERROR) 289 return -1; 290 return 0; 291} 292 293 294void crypto_cipher_deinit(struct crypto_cipher *ctx) 295{ 296 gcry_cipher_close(ctx->enc); 297 gcry_cipher_close(ctx->dec); 298 os_free(ctx); 299} 300