2 * WPA Supplicant / wrapper functions for libgcrypt
3 * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
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.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
21 int md4_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
27 if (gcry_md_open(&hd
, GCRY_MD_MD4
, 0) != GPG_ERR_NO_ERROR
)
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
);
33 memcpy(mac
, p
, gcry_md_get_algo_dlen(GCRY_MD_MD4
));
39 void des_encrypt(const u8
*clear
, const u8
*key
, u8
*cypher
)
42 u8 pkey
[8], next
, tmp
;
45 /* Add parity bits to the key */
47 for (i
= 0; i
< 7; i
++) {
49 pkey
[i
] = (tmp
>> i
) | next
| 1;
50 next
= tmp
<< (7 - i
);
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
);
61 int md5_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
67 if (gcry_md_open(&hd
, GCRY_MD_MD5
, 0) != GPG_ERR_NO_ERROR
)
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
);
73 memcpy(mac
, p
, gcry_md_get_algo_dlen(GCRY_MD_MD5
));
79 int sha1_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
, u8
*mac
)
85 if (gcry_md_open(&hd
, GCRY_MD_SHA1
, 0) != GPG_ERR_NO_ERROR
)
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
);
91 memcpy(mac
, p
, gcry_md_get_algo_dlen(GCRY_MD_SHA1
));
97 void * aes_encrypt_init(const u8
*key
, size_t len
)
101 if (gcry_cipher_open(&hd
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_ECB
, 0) !=
103 printf("cipher open failed\n");
106 if (gcry_cipher_setkey(hd
, key
, len
) != GPG_ERR_NO_ERROR
) {
107 printf("setkey failed\n");
108 gcry_cipher_close(hd
);
116 void aes_encrypt(void *ctx
, const u8
*plain
, u8
*crypt
)
118 gcry_cipher_hd_t hd
= ctx
;
119 gcry_cipher_encrypt(hd
, crypt
, 16, plain
, 16);
123 void aes_encrypt_deinit(void *ctx
)
125 gcry_cipher_hd_t hd
= ctx
;
126 gcry_cipher_close(hd
);
130 void * aes_decrypt_init(const u8
*key
, size_t len
)
134 if (gcry_cipher_open(&hd
, GCRY_CIPHER_AES
, GCRY_CIPHER_MODE_ECB
, 0) !=
137 if (gcry_cipher_setkey(hd
, key
, len
) != GPG_ERR_NO_ERROR
) {
138 gcry_cipher_close(hd
);
146 void aes_decrypt(void *ctx
, const u8
*crypt
, u8
*plain
)
148 gcry_cipher_hd_t hd
= ctx
;
149 gcry_cipher_decrypt(hd
, plain
, 16, crypt
, 16);
153 void aes_decrypt_deinit(void *ctx
)
155 gcry_cipher_hd_t hd
= ctx
;
156 gcry_cipher_close(hd
);
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
)
165 gcry_mpi_t bn_base
= NULL
, bn_exp
= NULL
, bn_modulus
= NULL
,
169 if (gcry_mpi_scan(&bn_base
, GCRYMPI_FMT_USG
, base
, base_len
, NULL
) !=
171 gcry_mpi_scan(&bn_exp
, GCRYMPI_FMT_USG
, power
, power_len
, NULL
) !=
173 gcry_mpi_scan(&bn_modulus
, GCRYMPI_FMT_USG
, modulus
, modulus_len
,
174 NULL
) != GPG_ERR_NO_ERROR
)
176 bn_result
= gcry_mpi_new(modulus_len
* 8);
178 gcry_mpi_powm(bn_result
, bn_base
, bn_exp
, bn_modulus
);
180 if (gcry_mpi_print(GCRYMPI_FMT_USG
, result
, *result_len
, result_len
,
181 bn_result
) != GPG_ERR_NO_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
);
195 struct crypto_cipher
{
196 gcry_cipher_hd_t enc
;
197 gcry_cipher_hd_t dec
;
201 struct crypto_cipher
* crypto_cipher_init(enum crypto_cipher_alg alg
,
202 const u8
*iv
, const u8
*key
,
205 struct crypto_cipher
*ctx
;
207 enum gcry_cipher_algos a
;
210 ctx
= os_zalloc(sizeof(*ctx
));
215 case CRYPTO_CIPHER_ALG_RC4
:
216 a
= GCRY_CIPHER_ARCFOUR
;
217 res
= gcry_cipher_open(&ctx
->enc
, a
, GCRY_CIPHER_MODE_STREAM
,
219 gcry_cipher_open(&ctx
->dec
, a
, GCRY_CIPHER_MODE_STREAM
, 0);
221 case CRYPTO_CIPHER_ALG_AES
:
223 a
= GCRY_CIPHER_AES192
;
224 else if (key_len
== 32)
225 a
= GCRY_CIPHER_AES256
;
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);
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);
236 case CRYPTO_CIPHER_ALG_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);
241 case CRYPTO_CIPHER_ALG_RC2
:
243 a
= GCRY_CIPHER_RFC2268_40
;
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);
254 if (res
!= GPG_ERR_NO_ERROR
) {
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
);
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
);
280 int crypto_cipher_encrypt(struct crypto_cipher
*ctx
, const u8
*plain
,
281 u8
*crypt
, size_t len
)
283 if (gcry_cipher_encrypt(ctx
->enc
, crypt
, len
, plain
, len
) !=
290 int crypto_cipher_decrypt(struct crypto_cipher
*ctx
, const u8
*crypt
,
291 u8
*plain
, size_t len
)
293 if (gcry_cipher_decrypt(ctx
->dec
, plain
, len
, crypt
, len
) !=
300 void crypto_cipher_deinit(struct crypto_cipher
*ctx
)
302 gcry_cipher_close(ctx
->enc
);
303 gcry_cipher_close(ctx
->dec
);