2c865f0dea96b0ec1cf2d9cdfcecb7a8ef2d4177
[libeap.git] / src / crypto / crypto_openssl.c
1 /*
2  * WPA Supplicant / wrapper functions for libcrypto
3  * Copyright (c) 2004-2009, Jouni Malinen <j@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 <openssl/opensslv.h>
17 #include <openssl/err.h>
18 #include <openssl/des.h>
19 #include <openssl/aes.h>
20 #include <openssl/bn.h>
21 #include <openssl/evp.h>
22
23 #include "common.h"
24 #include "crypto.h"
25
26 #if OPENSSL_VERSION_NUMBER < 0x00907000
27 #define DES_key_schedule des_key_schedule
28 #define DES_cblock des_cblock
29 #define DES_set_key(key, schedule) des_set_key((key), *(schedule))
30 #define DES_ecb_encrypt(input, output, ks, enc) \
31         des_ecb_encrypt((input), (output), *(ks), (enc))
32 #endif /* openssl < 0.9.7 */
33
34
35 int openssl_digest_vector(const EVP_MD *type, int non_fips, size_t num_elem,
36                           const u8 *addr[], const size_t *len, u8 *mac)
37 {
38         EVP_MD_CTX ctx;
39         size_t i;
40         unsigned int mac_len;
41
42         EVP_MD_CTX_init(&ctx);
43 #ifdef CONFIG_FIPS
44 #ifdef OPENSSL_FIPS
45         if (non_fips)
46                 EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
47 #endif /* OPENSSL_FIPS */
48 #endif /* CONFIG_FIPS */
49         if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
50                 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
51                            ERR_error_string(ERR_get_error(), NULL));
52                 return -1;
53         }
54         for (i = 0; i < num_elem; i++) {
55                 if (!EVP_DigestUpdate(&ctx, addr[i], len[i])) {
56                         wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
57                                    "failed: %s",
58                                    ERR_error_string(ERR_get_error(), NULL));
59                         return -1;
60                 }
61         }
62         if (!EVP_DigestFinal(&ctx, mac, &mac_len)) {
63                 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
64                            ERR_error_string(ERR_get_error(), NULL));
65                 return -1;
66         }
67
68         return 0;
69 }
70
71
72 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
73 {
74         return openssl_digest_vector(EVP_md4(), 0, num_elem, addr, len, mac);
75 }
76
77
78 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
79 {
80         u8 pkey[8], next, tmp;
81         int i;
82         DES_key_schedule ks;
83
84         /* Add parity bits to the key */
85         next = 0;
86         for (i = 0; i < 7; i++) {
87                 tmp = key[i];
88                 pkey[i] = (tmp >> i) | next | 1;
89                 next = tmp << (7 - i);
90         }
91         pkey[i] = next | 1;
92
93         DES_set_key(&pkey, &ks);
94         DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
95                         DES_ENCRYPT);
96 }
97
98
99 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
100 {
101         return openssl_digest_vector(EVP_md5(), 0, num_elem, addr, len, mac);
102 }
103
104
105 #ifdef CONFIG_FIPS
106 int md5_vector_non_fips_allow(size_t num_elem, const u8 *addr[],
107                               const size_t *len, u8 *mac)
108 {
109         return openssl_digest_vector(EVP_md5(), 1, num_elem, addr, len, mac);
110 }
111 #endif /* CONFIG_FIPS */
112
113
114 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
115 {
116         return openssl_digest_vector(EVP_sha1(), 0, num_elem, addr, len, mac);
117 }
118
119
120 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
121                   u8 *mac)
122 {
123         return openssl_digest_vector(EVP_sha256(), 0, num_elem, addr, len,
124                                      mac);
125 }
126
127
128 void * aes_encrypt_init(const u8 *key, size_t len)
129 {
130         AES_KEY *ak;
131         ak = os_malloc(sizeof(*ak));
132         if (ak == NULL)
133                 return NULL;
134         if (AES_set_encrypt_key(key, 8 * len, ak) < 0) {
135                 os_free(ak);
136                 return NULL;
137         }
138         return ak;
139 }
140
141
142 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
143 {
144         AES_encrypt(plain, crypt, ctx);
145 }
146
147
148 void aes_encrypt_deinit(void *ctx)
149 {
150         os_free(ctx);
151 }
152
153
154 void * aes_decrypt_init(const u8 *key, size_t len)
155 {
156         AES_KEY *ak;
157         ak = os_malloc(sizeof(*ak));
158         if (ak == NULL)
159                 return NULL;
160         if (AES_set_decrypt_key(key, 8 * len, ak) < 0) {
161                 os_free(ak);
162                 return NULL;
163         }
164         return ak;
165 }
166
167
168 void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
169 {
170         AES_decrypt(crypt, plain, ctx);
171 }
172
173
174 void aes_decrypt_deinit(void *ctx)
175 {
176         os_free(ctx);
177 }
178
179
180 int crypto_mod_exp(const u8 *base, size_t base_len,
181                    const u8 *power, size_t power_len,
182                    const u8 *modulus, size_t modulus_len,
183                    u8 *result, size_t *result_len)
184 {
185         BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result;
186         int ret = -1;
187         BN_CTX *ctx;
188
189         ctx = BN_CTX_new();
190         if (ctx == NULL)
191                 return -1;
192
193         bn_base = BN_bin2bn(base, base_len, NULL);
194         bn_exp = BN_bin2bn(power, power_len, NULL);
195         bn_modulus = BN_bin2bn(modulus, modulus_len, NULL);
196         bn_result = BN_new();
197
198         if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
199             bn_result == NULL)
200                 goto error;
201
202         if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
203                 goto error;
204
205         *result_len = BN_bn2bin(bn_result, result);
206         ret = 0;
207
208 error:
209         BN_free(bn_base);
210         BN_free(bn_exp);
211         BN_free(bn_modulus);
212         BN_free(bn_result);
213         BN_CTX_free(ctx);
214         return ret;
215 }
216
217
218 struct crypto_cipher {
219         EVP_CIPHER_CTX enc;
220         EVP_CIPHER_CTX dec;
221 };
222
223
224 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
225                                           const u8 *iv, const u8 *key,
226                                           size_t key_len)
227 {
228         struct crypto_cipher *ctx;
229         const EVP_CIPHER *cipher;
230
231         ctx = os_zalloc(sizeof(*ctx));
232         if (ctx == NULL)
233                 return NULL;
234
235         switch (alg) {
236 #ifndef OPENSSL_NO_RC4
237         case CRYPTO_CIPHER_ALG_RC4:
238                 cipher = EVP_rc4();
239                 break;
240 #endif /* OPENSSL_NO_RC4 */
241 #ifndef OPENSSL_NO_AES
242         case CRYPTO_CIPHER_ALG_AES:
243                 switch (key_len) {
244                 case 16:
245                         cipher = EVP_aes_128_cbc();
246                         break;
247                 case 24:
248                         cipher = EVP_aes_192_cbc();
249                         break;
250                 case 32:
251                         cipher = EVP_aes_256_cbc();
252                         break;
253                 default:
254                         os_free(ctx);
255                         return NULL;
256                 }
257                 break;
258 #endif /* OPENSSL_NO_AES */
259 #ifndef OPENSSL_NO_DES
260         case CRYPTO_CIPHER_ALG_3DES:
261                 cipher = EVP_des_ede3_cbc();
262                 break;
263         case CRYPTO_CIPHER_ALG_DES:
264                 cipher = EVP_des_cbc();
265                 break;
266 #endif /* OPENSSL_NO_DES */
267 #ifndef OPENSSL_NO_RC2
268         case CRYPTO_CIPHER_ALG_RC2:
269                 cipher = EVP_rc2_ecb();
270                 break;
271 #endif /* OPENSSL_NO_RC2 */
272         default:
273                 os_free(ctx);
274                 return NULL;
275         }
276
277         EVP_CIPHER_CTX_init(&ctx->enc);
278         EVP_CIPHER_CTX_set_padding(&ctx->enc, 0);
279         if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) ||
280             !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) ||
281             !EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, key, iv)) {
282                 EVP_CIPHER_CTX_cleanup(&ctx->enc);
283                 os_free(ctx);
284                 return NULL;
285         }
286
287         EVP_CIPHER_CTX_init(&ctx->dec);
288         EVP_CIPHER_CTX_set_padding(&ctx->dec, 0);
289         if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) ||
290             !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) ||
291             !EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, key, iv)) {
292                 EVP_CIPHER_CTX_cleanup(&ctx->enc);
293                 EVP_CIPHER_CTX_cleanup(&ctx->dec);
294                 os_free(ctx);
295                 return NULL;
296         }
297
298         return ctx;
299 }
300
301
302 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
303                           u8 *crypt, size_t len)
304 {
305         int outl;
306         if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len))
307                 return -1;
308         return 0;
309 }
310
311
312 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
313                           u8 *plain, size_t len)
314 {
315         int outl;
316         outl = len;
317         if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len))
318                 return -1;
319         return 0;
320 }
321
322
323 void crypto_cipher_deinit(struct crypto_cipher *ctx)
324 {
325         EVP_CIPHER_CTX_cleanup(&ctx->enc);
326         EVP_CIPHER_CTX_cleanup(&ctx->dec);
327         os_free(ctx);
328 }