Home | History | Annotate | Download | only in crypto
      1 /*
      2  * WPA Supplicant / wrapper functions for libgcrypt
      3  * Copyright (c) 2004-2009, Jouni Malinen <j (at) 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 
     15 int 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 
     33 int 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 
     56 int 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 
     74 int 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 
     92 void * 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 
    111 int 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 
    119 void aes_encrypt_deinit(void *ctx)
    120 {
    121 	gcry_cipher_hd_t hd = ctx;
    122 	gcry_cipher_close(hd);
    123 }
    124 
    125 
    126 void * 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 
    142 int 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 
    150 void aes_decrypt_deinit(void *ctx)
    151 {
    152 	gcry_cipher_hd_t hd = ctx;
    153 	gcry_cipher_close(hd);
    154 }
    155 
    156 
    157 int 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 
    183 error:
    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 
    192 struct crypto_cipher {
    193 	gcry_cipher_hd_t enc;
    194 	gcry_cipher_hd_t dec;
    195 };
    196 
    197 
    198 struct 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 
    277 int 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 
    287 int 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 
    297 void 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