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