1132718Skan/*
2132718Skan * WPA Supplicant / wrapper functions for libgcrypt
3169689Skan * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
4132718Skan *
5132718Skan * This program is free software; you can redistribute it and/or modify
6132718Skan * it under the terms of the GNU General Public License version 2 as
7132718Skan * published by the Free Software Foundation.
8132718Skan *
9132718Skan * Alternatively, this software may be distributed under the terms of BSD
10132718Skan * license.
11132718Skan *
12132718Skan * See README and COPYING for more details.
13132718Skan */
14132718Skan
15132718Skan#include "includes.h"
16132718Skan#include <gcrypt.h>
17132718Skan
18132718Skan#include "common.h"
19132718Skan#include "crypto.h"
20132718Skan
21132718Skanint md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
22132718Skan{
23169689Skan	gcry_md_hd_t hd;
24169689Skan	unsigned char *p;
25132718Skan	size_t i;
26132718Skan
27132718Skan	if (gcry_md_open(&hd, GCRY_MD_MD4, 0) != GPG_ERR_NO_ERROR)
28132718Skan		return -1;
29132718Skan	for (i = 0; i < num_elem; i++)
30132718Skan		gcry_md_write(hd, addr[i], len[i]);
31132718Skan	p = gcry_md_read(hd, GCRY_MD_MD4);
32132718Skan	if (p)
33132718Skan		memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD4));
34132718Skan	gcry_md_close(hd);
35132718Skan	return 0;
36132718Skan}
37132718Skan
38132718Skan
39132718Skanvoid des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
40132718Skan{
41132718Skan	gcry_cipher_hd_t hd;
42132718Skan	u8 pkey[8], next, tmp;
43132718Skan	int i;
44132718Skan
45169689Skan	/* Add parity bits to the key */
46169689Skan	next = 0;
47132718Skan	for (i = 0; i < 7; i++) {
48132718Skan		tmp = key[i];
49132718Skan		pkey[i] = (tmp >> i) | next | 1;
50132718Skan		next = tmp << (7 - i);
51132718Skan	}
52132718Skan	pkey[i] = next | 1;
53132718Skan
54132718Skan	gcry_cipher_open(&hd, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
55132718Skan	gcry_err_code(gcry_cipher_setkey(hd, pkey, 8));
56132718Skan	gcry_cipher_encrypt(hd, cypher, 8, clear, 8);
57132718Skan	gcry_cipher_close(hd);
58132718Skan}
59132718Skan
60132718Skan
61132718Skanint md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
62132718Skan{
63132718Skan	gcry_md_hd_t hd;
64132718Skan	unsigned char *p;
65132718Skan	size_t i;
66132718Skan
67132718Skan	if (gcry_md_open(&hd, GCRY_MD_MD5, 0) != GPG_ERR_NO_ERROR)
68132718Skan		return -1;
69132718Skan	for (i = 0; i < num_elem; i++)
70132718Skan		gcry_md_write(hd, addr[i], len[i]);
71132718Skan	p = gcry_md_read(hd, GCRY_MD_MD5);
72132718Skan	if (p)
73132718Skan		memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_MD5));
74132718Skan	gcry_md_close(hd);
75132718Skan	return 0;
76132718Skan}
77132718Skan
78132718Skan
79132718Skanint sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
80132718Skan{
81132718Skan	gcry_md_hd_t hd;
82132718Skan	unsigned char *p;
83132718Skan	size_t i;
84132718Skan
85132718Skan	if (gcry_md_open(&hd, GCRY_MD_SHA1, 0) != GPG_ERR_NO_ERROR)
86132718Skan		return -1;
87132718Skan	for (i = 0; i < num_elem; i++)
88132718Skan		gcry_md_write(hd, addr[i], len[i]);
89132718Skan	p = gcry_md_read(hd, GCRY_MD_SHA1);
90132718Skan	if (p)
91132718Skan		memcpy(mac, p, gcry_md_get_algo_dlen(GCRY_MD_SHA1));
92132718Skan	gcry_md_close(hd);
93132718Skan	return 0;
94132718Skan}
95132718Skan
96132718Skan
97132718Skanvoid * aes_encrypt_init(const u8 *key, size_t len)
98132718Skan{
99169689Skan	gcry_cipher_hd_t hd;
100169689Skan
101169689Skan	if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) !=
102169689Skan	    GPG_ERR_NO_ERROR) {
103169689Skan		printf("cipher open failed\n");
104132718Skan		return NULL;
105132718Skan	}
106132718Skan	if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) {
107132718Skan		printf("setkey failed\n");
108132718Skan		gcry_cipher_close(hd);
109132718Skan		return NULL;
110132718Skan	}
111132718Skan
112132718Skan	return hd;
113132718Skan}
114132718Skan
115132718Skan
116132718Skanvoid aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
117132718Skan{
118132718Skan	gcry_cipher_hd_t hd = ctx;
119132718Skan	gcry_cipher_encrypt(hd, crypt, 16, plain, 16);
120132718Skan}
121132718Skan
122132718Skan
123169689Skanvoid aes_encrypt_deinit(void *ctx)
124169689Skan{
125132718Skan	gcry_cipher_hd_t hd = ctx;
126169689Skan	gcry_cipher_close(hd);
127169689Skan}
128169689Skan
129169689Skan
130169689Skanvoid * aes_decrypt_init(const u8 *key, size_t len)
131169689Skan{
132169689Skan	gcry_cipher_hd_t hd;
133169689Skan
134169689Skan	if (gcry_cipher_open(&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0) !=
135169689Skan	    GPG_ERR_NO_ERROR)
136169689Skan		return NULL;
137169689Skan	if (gcry_cipher_setkey(hd, key, len) != GPG_ERR_NO_ERROR) {
138169689Skan		gcry_cipher_close(hd);
139132718Skan		return NULL;
140132718Skan	}
141132718Skan
142132718Skan	return hd;
143132718Skan}
144132718Skan
145132718Skan
146132718Skanvoid aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
147132718Skan{
148132718Skan	gcry_cipher_hd_t hd = ctx;
149132718Skan	gcry_cipher_decrypt(hd, plain, 16, crypt, 16);
150132718Skan}
151132718Skan
152132718Skan
153132718Skanvoid aes_decrypt_deinit(void *ctx)
154132718Skan{
155132718Skan	gcry_cipher_hd_t hd = ctx;
156132718Skan	gcry_cipher_close(hd);
157132718Skan}
158132718Skan
159132718Skan
160132718Skanint crypto_mod_exp(const u8 *base, size_t base_len,
161132718Skan		   const u8 *power, size_t power_len,
162132718Skan		   const u8 *modulus, size_t modulus_len,
163132718Skan		   u8 *result, size_t *result_len)
164132718Skan{
165132718Skan	gcry_mpi_t bn_base = NULL, bn_exp = NULL, bn_modulus = NULL,
166132718Skan		bn_result = NULL;
167132718Skan	int ret = -1;
168132718Skan
169132718Skan	if (gcry_mpi_scan(&bn_base, GCRYMPI_FMT_USG, base, base_len, NULL) !=
170132718Skan	    GPG_ERR_NO_ERROR ||
171132718Skan	    gcry_mpi_scan(&bn_exp, GCRYMPI_FMT_USG, power, power_len, NULL) !=
172132718Skan	    GPG_ERR_NO_ERROR ||
173132718Skan	    gcry_mpi_scan(&bn_modulus, GCRYMPI_FMT_USG, modulus, modulus_len,
174132718Skan			  NULL) != GPG_ERR_NO_ERROR)
175132718Skan		goto error;
176132718Skan	bn_result = gcry_mpi_new(modulus_len * 8);
177132718Skan
178132718Skan	gcry_mpi_powm(bn_result, bn_base, bn_exp, bn_modulus);
179132718Skan
180132718Skan	if (gcry_mpi_print(GCRYMPI_FMT_USG, result, *result_len, result_len,
181132718Skan			   bn_result) != GPG_ERR_NO_ERROR)
182132718Skan		goto error;
183169689Skan
184132718Skan	ret = 0;
185132718Skan
186132718Skanerror:
187132718Skan	gcry_mpi_release(bn_base);
188132718Skan	gcry_mpi_release(bn_exp);
189132718Skan	gcry_mpi_release(bn_modulus);
190132718Skan	gcry_mpi_release(bn_result);
191132718Skan	return ret;
192132718Skan}
193132718Skan
194169689Skan
195161651Skanstruct crypto_cipher {
196132718Skan	gcry_cipher_hd_t enc;
197132718Skan	gcry_cipher_hd_t dec;
198132718Skan};
199132718Skan
200132718Skan
201132718Skanstruct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
202132718Skan					  const u8 *iv, const u8 *key,
203132718Skan					  size_t key_len)
204132718Skan{
205132718Skan	struct crypto_cipher *ctx;
206132718Skan	gcry_error_t res;
207132718Skan	enum gcry_cipher_algos a;
208132718Skan	int ivlen;
209132718Skan
210132718Skan	ctx = os_zalloc(sizeof(*ctx));
211132718Skan	if (ctx == NULL)
212132718Skan		return NULL;
213132718Skan
214132718Skan	switch (alg) {
215132718Skan	case CRYPTO_CIPHER_ALG_RC4:
216132718Skan		a = GCRY_CIPHER_ARCFOUR;
217132718Skan		res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_STREAM,
218132718Skan				       0);
219132718Skan		gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_STREAM, 0);
220132718Skan		break;
221132718Skan	case CRYPTO_CIPHER_ALG_AES:
222132718Skan		if (key_len == 24)
223132718Skan			a = GCRY_CIPHER_AES192;
224132718Skan		else if (key_len == 32)
225132718Skan			a = GCRY_CIPHER_AES256;
226132718Skan		else
227132718Skan			a = GCRY_CIPHER_AES;
228132718Skan		res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
229132718Skan		gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
230132718Skan		break;
231132718Skan	case CRYPTO_CIPHER_ALG_3DES:
232132718Skan		a = GCRY_CIPHER_3DES;
233132718Skan		res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
234132718Skan		gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
235132718Skan		break;
236132718Skan	case CRYPTO_CIPHER_ALG_DES:
237132718Skan		a = GCRY_CIPHER_DES;
238132718Skan		res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
239132718Skan		gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
240132718Skan		break;
241132718Skan	case CRYPTO_CIPHER_ALG_RC2:
242132718Skan		if (key_len == 5)
243132718Skan			a = GCRY_CIPHER_RFC2268_40;
244132718Skan		else
245132718Skan			a = GCRY_CIPHER_RFC2268_128;
246132718Skan		res = gcry_cipher_open(&ctx->enc, a, GCRY_CIPHER_MODE_CBC, 0);
247132718Skan		gcry_cipher_open(&ctx->dec, a, GCRY_CIPHER_MODE_CBC, 0);
248132718Skan		break;
249132718Skan	default:
250132718Skan		os_free(ctx);
251132718Skan		return NULL;
252132718Skan	}
253132718Skan
254132718Skan	if (res != GPG_ERR_NO_ERROR) {
255132718Skan		os_free(ctx);
256132718Skan		return NULL;
257132718Skan	}
258132718Skan
259132718Skan	if (gcry_cipher_setkey(ctx->enc, key, key_len) != GPG_ERR_NO_ERROR ||
260132718Skan	    gcry_cipher_setkey(ctx->dec, key, key_len) != GPG_ERR_NO_ERROR) {
261132718Skan		gcry_cipher_close(ctx->enc);
262132718Skan		gcry_cipher_close(ctx->dec);
263132718Skan		os_free(ctx);
264132718Skan		return NULL;
265169689Skan	}
266132718Skan
267132718Skan	ivlen = gcry_cipher_get_algo_blklen(a);
268132718Skan	if (gcry_cipher_setiv(ctx->enc, iv, ivlen) != GPG_ERR_NO_ERROR ||
269132718Skan	    gcry_cipher_setiv(ctx->dec, iv, ivlen) != GPG_ERR_NO_ERROR) {
270169689Skan		gcry_cipher_close(ctx->enc);
271132718Skan		gcry_cipher_close(ctx->dec);
272132718Skan		os_free(ctx);
273132718Skan		return NULL;
274169689Skan	}
275132718Skan
276132718Skan	return ctx;
277132718Skan}
278132718Skan
279132718Skan
280132718Skanint crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
281132718Skan			  u8 *crypt, size_t len)
282169689Skan{
283132718Skan	if (gcry_cipher_encrypt(ctx->enc, crypt, len, plain, len) !=
284132718Skan	    GPG_ERR_NO_ERROR)
285132718Skan		return -1;
286132718Skan	return 0;
287132718Skan}
288132718Skan
289132718Skan
290132718Skanint crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
291132718Skan			  u8 *plain, size_t len)
292132718Skan{
293132718Skan	if (gcry_cipher_decrypt(ctx->dec, plain, len, crypt, len) !=
294132718Skan	    GPG_ERR_NO_ERROR)
295132718Skan		return -1;
296132718Skan	return 0;
297132718Skan}
298132718Skan
299132718Skan
300132718Skanvoid crypto_cipher_deinit(struct crypto_cipher *ctx)
301132718Skan{
302132718Skan	gcry_cipher_close(ctx->enc);
303132718Skan	gcry_cipher_close(ctx->dec);
304132718Skan	os_free(ctx);
305132718Skan}
306132718Skan