$search
00001 /* 00002 * WPA Supplicant / wrapper functions for libgcrypt 00003 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 00013 */ 00014 00015 #include "includes.h" 00016 #include <gcrypt.h> 00017 00018 #include "common.h" 00019 #include "crypto.h" 00020 00021 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 00022 { 00023 gcry_md_hd_t hd; 00024 unsigned char *p; 00025 size_t i; 00026 00027 if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR) 00028 return -1; 00029 for (i = 0; i < num_elem; i++) 00030 gcry_md_write(hd, addr[i], len[i]); 00031 p = gcry_md_read(hd, GCRY_MD_MD4); 00032 if (p) 00033 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4)); 00034 gcry_md_close(hd); 00035 return 0; 00036 } 00037 00038 00039 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher) 00040 { 00041 gcry_cipher_hd_t hd; 00042 u8 pkey[8], next, tmp; 00043 int i; 00044 00045 /* Add parity bits to the key */ 00046 next = 0; 00047 for (i = 0; i < 7; i++) { 00048 tmp = key[i]; 00049 pkey[i] = (tmp >> i) | next | 1; 00050 next = tmp << (7 - i); 00051 } 00052 pkey[i] = next | 1; 00053 00054 gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); 00055 gcry_err_code(gcry_cipher_setkey(hd, pkey, 8)); 00056 gcry_cipher_encrypt(hd, cypher, 8, clear, 8); 00057 gcry_cipher_close(hd); 00058 } 00059 00060 00061 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 00062 { 00063 gcry_md_hd_t hd; 00064 unsigned char *p; 00065 size_t i; 00066 00067 if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR) 00068 return -1; 00069 for (i = 0; i < num_elem; i++) 00070 gcry_md_write(hd, addr[i], len[i]); 00071 p = gcry_md_read(hd, GCRY_MD_MD5); 00072 if (p) 00073 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5)); 00074 gcry_md_close(hd); 00075 return 0; 00076 } 00077 00078 00079 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac) 00080 { 00081 gcry_md_hd_t hd; 00082 unsigned char *p; 00083 size_t i; 00084 00085 if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR) 00086 return -1; 00087 for (i = 0; i < num_elem; i++) 00088 gcry_md_write(hd, addr[i], len[i]); 00089 p = gcry_md_read(hd, GCRY_MD_SHA1); 00090 if (p) 00091 memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1)); 00092 gcry_md_close(hd); 00093 return 0; 00094 } 00095 00096 00097 void * aes_encrypt_init(const u8 *key, size_t len) 00098 { 00099 gcry_cipher_hd_t hd; 00100 00101 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 00102 GPG_ERR_NO_ERROR) { 00103 printf("cipher open failed\n"); 00104 return NULL; 00105 } 00106 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 00107 printf("setkey failed\n"); 00108 gcry_cipher_close(hd); 00109 return NULL; 00110 } 00111 00112 return hd; 00113 } 00114 00115 00116 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt) 00117 { 00118 gcry_cipher_hd_t hd = ctx; 00119 gcry_cipher_encrypt(hd, crypt, 16, plain, 16); 00120 } 00121 00122 00123 void aes_encrypt_deinit(void *ctx) 00124 { 00125 gcry_cipher_hd_t hd = ctx; 00126 gcry_cipher_close(hd); 00127 } 00128 00129 00130 void * aes_decrypt_init(const u8 *key, size_t len) 00131 { 00132 gcry_cipher_hd_t hd; 00133 00134 if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) != 00135 GPG_ERR_NO_ERROR) 00136 return NULL; 00137 if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) { 00138 gcry_cipher_close(hd); 00139 return NULL; 00140 } 00141 00142 return hd; 00143 } 00144 00145 00146 void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain) 00147 { 00148 gcry_cipher_hd_t hd = ctx; 00149 gcry_cipher_decrypt(hd, plain, 16, crypt, 16); 00150 } 00151 00152 00153 void aes_decrypt_deinit(void *ctx) 00154 { 00155 gcry_cipher_hd_t hd = ctx; 00156 gcry_cipher_close(hd); 00157 } 00158 00159 00160 int crypto_mod_exp(const u8 *base, size_t base_len, 00161 const u8 *power, size_t power_len, 00162 const u8 *modulus, size_t modulus_len, 00163 u8 *result, size_t *result_len) 00164 { 00165 gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL, 00166 bn_result = NULL; 00167 int ret = -1; 00168 00169 if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) != 00170 GPG_ERR_NO_ERROR || 00171 gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) != 00172 GPG_ERR_NO_ERROR || 00173 gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len, 00174 NULL) != GPG_ERR_NO_ERROR) 00175 goto error; 00176 bn_result = gcry_mpi_new(modulus_len * 8); 00177 00178 gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus); 00179 00180 if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len, 00181 bn_result) != GPG_ERR_NO_ERROR) 00182 goto error; 00183 00184 ret = 0; 00185 00186 error: 00187 gcry_mpi_release(bn_base); 00188 gcry_mpi_release(bn_exp); 00189 gcry_mpi_release(bn_modulus); 00190 gcry_mpi_release(bn_result); 00191 return ret; 00192 } 00193 00194 00195 struct crypto_cipher { 00196 gcry_cipher_hd_t enc; 00197 gcry_cipher_hd_t dec; 00198 }; 00199 00200 00201 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg, 00202 const u8 *iv, const u8 *key, 00203 size_t key_len) 00204 { 00205 struct crypto_cipher *ctx; 00206 gcry_error_t res; 00207 enum gcry_cipher_algos a; 00208 int ivlen; 00209 00210 ctx = os_zalloc(sizeof(*ctx)); 00211 if (ctx == NULL) 00212 return NULL; 00213 00214 switch (alg) { 00215 case CRYPTO_CIPHER_ALG_RC4: 00216 a = GCRY_CIPHER_ARCFOUR; 00217 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM, 00218 0); 00219 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0); 00220 break; 00221 case CRYPTO_CIPHER_ALG_AES: 00222 if (key_len == 24) 00223 a = GCRY_CIPHER_AES192; 00224 else if (key_len == 32) 00225 a = GCRY_CIPHER_AES256; 00226 else 00227 a = GCRY_CIPHER_AES; 00228 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 00229 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 00230 break; 00231 case CRYPTO_CIPHER_ALG_3DES: 00232 a = GCRY_CIPHER_3DES; 00233 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 00234 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 00235 break; 00236 case CRYPTO_CIPHER_ALG_DES: 00237 a = GCRY_CIPHER_DES; 00238 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 00239 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 00240 break; 00241 case CRYPTO_CIPHER_ALG_RC2: 00242 if (key_len == 5) 00243 a = GCRY_CIPHER_RFC2268_40; 00244 else 00245 a = GCRY_CIPHER_RFC2268_128; 00246 res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0); 00247 gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0); 00248 break; 00249 default: 00250 os_free(ctx); 00251 return NULL; 00252 } 00253 00254 if (res != GPG_ERR_NO_ERROR) { 00255 os_free(ctx); 00256 return NULL; 00257 } 00258 00259 if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR || 00260 gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) { 00261 gcry_cipher_close(ctx->enc); 00262 gcry_cipher_close(ctx->dec); 00263 os_free(ctx); 00264 return NULL; 00265 } 00266 00267 ivlen = gcry_cipher_get_algo_blklen(a); 00268 if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR || 00269 gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) { 00270 gcry_cipher_close(ctx->enc); 00271 gcry_cipher_close(ctx->dec); 00272 os_free(ctx); 00273 return NULL; 00274 } 00275 00276 return ctx; 00277 } 00278 00279 00280 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain, 00281 u8 *crypt, size_t len) 00282 { 00283 if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) != 00284 GPG_ERR_NO_ERROR) 00285 return -1; 00286 return 0; 00287 } 00288 00289 00290 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt, 00291 u8 *plain, size_t len) 00292 { 00293 if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) != 00294 GPG_ERR_NO_ERROR) 00295 return -1; 00296 return 0; 00297 } 00298 00299 00300 void crypto_cipher_deinit(struct crypto_cipher *ctx) 00301 { 00302 gcry_cipher_close(ctx->enc); 00303 gcry_cipher_close(ctx->dec); 00304 os_free(ctx); 00305 }