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