blob: 9e344d1de8e0080bcf48cc29dc7f44935777f1fb [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08002 * Wrapper functions for OpenSSL libcrypto
Dmitry Shmidt807291d2015-01-27 13:40:23 -08003 * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08005 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07007 */
8
9#include "includes.h"
10#include <openssl/opensslv.h>
11#include <openssl/err.h>
12#include <openssl/des.h>
13#include <openssl/aes.h>
14#include <openssl/bn.h>
15#include <openssl/evp.h>
16#include <openssl/dh.h>
Dmitry Shmidt04949592012-07-19 12:16:46 -070017#include <openssl/hmac.h>
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070018#include <openssl/rand.h>
19#ifdef CONFIG_OPENSSL_CMAC
20#include <openssl/cmac.h>
21#endif /* CONFIG_OPENSSL_CMAC */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -080022#ifdef CONFIG_ECC
23#include <openssl/ec.h>
24#endif /* CONFIG_ECC */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070025
26#include "common.h"
27#include "wpabuf.h"
28#include "dh_group5.h"
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -080029#include "sha1.h"
30#include "sha256.h"
Dmitry Shmidt807291d2015-01-27 13:40:23 -080031#include "sha384.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070032#include "crypto.h"
33
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034static BIGNUM * get_group5_prime(void)
35{
Dmitry Shmidt216983b2015-02-06 10:50:36 -080036#ifdef OPENSSL_IS_BORINGSSL
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070037 static const unsigned char RFC3526_PRIME_1536[] = {
38 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
39 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
40 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
41 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
42 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
43 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
44 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
45 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
46 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
47 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
48 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
49 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
50 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
51 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
52 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
53 0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
54 };
55 return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), NULL);
Dmitry Shmidt216983b2015-02-06 10:50:36 -080056#else /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070057 return get_rfc3526_prime_1536(NULL);
Dmitry Shmidt216983b2015-02-06 10:50:36 -080058#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070059}
60
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070061#ifdef OPENSSL_NO_SHA256
62#define NO_SHA256_WRAPPER
63#endif
64
Dmitry Shmidt61d9df32012-08-29 16:22:06 -070065static int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
66 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070067{
68 EVP_MD_CTX ctx;
69 size_t i;
70 unsigned int mac_len;
71
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080072 if (TEST_FAIL())
73 return -1;
74
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070075 EVP_MD_CTX_init(&ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070076 if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
77 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
78 ERR_error_string(ERR_get_error(), NULL));
79 return -1;
80 }
81 for (i = 0; i < num_elem; i++) {
82 if (!EVP_DigestUpdate(&ctx, addr[i], len[i])) {
83 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
84 "failed: %s",
85 ERR_error_string(ERR_get_error(), NULL));
86 return -1;
87 }
88 }
89 if (!EVP_DigestFinal(&ctx, mac, &mac_len)) {
90 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
91 ERR_error_string(ERR_get_error(), NULL));
92 return -1;
93 }
94
95 return 0;
96}
97
98
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080099#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700100int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
101{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700102 return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700103}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800104#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700105
106
107void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
108{
109 u8 pkey[8], next, tmp;
110 int i;
111 DES_key_schedule ks;
112
113 /* Add parity bits to the key */
114 next = 0;
115 for (i = 0; i < 7; i++) {
116 tmp = key[i];
117 pkey[i] = (tmp >> i) | next | 1;
118 next = tmp << (7 - i);
119 }
120 pkey[i] = next | 1;
121
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700122 DES_set_key((DES_cblock *) &pkey, &ks);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700123 DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
124 DES_ENCRYPT);
125}
126
127
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800128#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700129int rc4_skip(const u8 *key, size_t keylen, size_t skip,
130 u8 *data, size_t data_len)
131{
132#ifdef OPENSSL_NO_RC4
133 return -1;
134#else /* OPENSSL_NO_RC4 */
135 EVP_CIPHER_CTX ctx;
136 int outl;
137 int res = -1;
138 unsigned char skip_buf[16];
139
140 EVP_CIPHER_CTX_init(&ctx);
141 if (!EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
142 !EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
143 !EVP_CIPHER_CTX_set_key_length(&ctx, keylen) ||
144 !EVP_CipherInit_ex(&ctx, NULL, NULL, key, NULL, 1))
145 goto out;
146
147 while (skip >= sizeof(skip_buf)) {
148 size_t len = skip;
149 if (len > sizeof(skip_buf))
150 len = sizeof(skip_buf);
151 if (!EVP_CipherUpdate(&ctx, skip_buf, &outl, skip_buf, len))
152 goto out;
153 skip -= len;
154 }
155
156 if (EVP_CipherUpdate(&ctx, data, &outl, data, data_len))
157 res = 0;
158
159out:
160 EVP_CIPHER_CTX_cleanup(&ctx);
161 return res;
162#endif /* OPENSSL_NO_RC4 */
163}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800164#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700165
166
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800167#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700168int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
169{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700170 return openssl_digest_vector(EVP_md5(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700171}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800172#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700173
174
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700175int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
176{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700177 return openssl_digest_vector(EVP_sha1(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700178}
179
180
181#ifndef NO_SHA256_WRAPPER
182int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
183 u8 *mac)
184{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700185 return openssl_digest_vector(EVP_sha256(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700186}
187#endif /* NO_SHA256_WRAPPER */
188
189
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700190static const EVP_CIPHER * aes_get_evp_cipher(size_t keylen)
191{
192 switch (keylen) {
193 case 16:
194 return EVP_aes_128_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700195#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700196 case 24:
197 return EVP_aes_192_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700198#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700199 case 32:
200 return EVP_aes_256_ecb();
201 }
202
203 return NULL;
204}
205
206
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700207void * aes_encrypt_init(const u8 *key, size_t len)
208{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700209 EVP_CIPHER_CTX *ctx;
210 const EVP_CIPHER *type;
211
212 type = aes_get_evp_cipher(len);
213 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700214 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700215
216 ctx = os_malloc(sizeof(*ctx));
217 if (ctx == NULL)
218 return NULL;
219 EVP_CIPHER_CTX_init(ctx);
220 if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
221 os_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700222 return NULL;
223 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700224 EVP_CIPHER_CTX_set_padding(ctx, 0);
225 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700226}
227
228
229void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
230{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700231 EVP_CIPHER_CTX *c = ctx;
232 int clen = 16;
233 if (EVP_EncryptUpdate(c, crypt, &clen, plain, 16) != 1) {
234 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptUpdate failed: %s",
235 ERR_error_string(ERR_get_error(), NULL));
236 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700237}
238
239
240void aes_encrypt_deinit(void *ctx)
241{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700242 EVP_CIPHER_CTX *c = ctx;
243 u8 buf[16];
244 int len = sizeof(buf);
245 if (EVP_EncryptFinal_ex(c, buf, &len) != 1) {
246 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptFinal_ex failed: "
247 "%s", ERR_error_string(ERR_get_error(), NULL));
248 }
249 if (len != 0) {
250 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
251 "in AES encrypt", len);
252 }
253 EVP_CIPHER_CTX_cleanup(c);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800254 bin_clear_free(c, sizeof(*c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700255}
256
257
258void * aes_decrypt_init(const u8 *key, size_t len)
259{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700260 EVP_CIPHER_CTX *ctx;
261 const EVP_CIPHER *type;
262
263 type = aes_get_evp_cipher(len);
264 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700265 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700266
267 ctx = os_malloc(sizeof(*ctx));
268 if (ctx == NULL)
269 return NULL;
270 EVP_CIPHER_CTX_init(ctx);
271 if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
272 os_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700273 return NULL;
274 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700275 EVP_CIPHER_CTX_set_padding(ctx, 0);
276 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700277}
278
279
280void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
281{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700282 EVP_CIPHER_CTX *c = ctx;
283 int plen = 16;
284 if (EVP_DecryptUpdate(c, plain, &plen, crypt, 16) != 1) {
285 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptUpdate failed: %s",
286 ERR_error_string(ERR_get_error(), NULL));
287 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700288}
289
290
291void aes_decrypt_deinit(void *ctx)
292{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700293 EVP_CIPHER_CTX *c = ctx;
294 u8 buf[16];
295 int len = sizeof(buf);
296 if (EVP_DecryptFinal_ex(c, buf, &len) != 1) {
297 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptFinal_ex failed: "
298 "%s", ERR_error_string(ERR_get_error(), NULL));
299 }
300 if (len != 0) {
301 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
302 "in AES decrypt", len);
303 }
304 EVP_CIPHER_CTX_cleanup(c);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800305 bin_clear_free(c, sizeof(*c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700306}
307
308
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800309#ifndef CONFIG_FIPS
310#ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
311
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800312int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
313{
314 AES_KEY actx;
315 int res;
316
317 if (AES_set_encrypt_key(kek, kek_len << 3, &actx))
318 return -1;
319 res = AES_wrap_key(&actx, NULL, cipher, plain, n * 8);
320 OPENSSL_cleanse(&actx, sizeof(actx));
321 return res <= 0 ? -1 : 0;
322}
323
324
325int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
326 u8 *plain)
327{
328 AES_KEY actx;
329 int res;
330
331 if (AES_set_decrypt_key(kek, kek_len << 3, &actx))
332 return -1;
333 res = AES_unwrap_key(&actx, NULL, plain, cipher, (n + 1) * 8);
334 OPENSSL_cleanse(&actx, sizeof(actx));
335 return res <= 0 ? -1 : 0;
336}
337
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800338#endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
339#endif /* CONFIG_FIPS */
340
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800341
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700342int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
343{
344 EVP_CIPHER_CTX ctx;
345 int clen, len;
346 u8 buf[16];
347
348 EVP_CIPHER_CTX_init(&ctx);
349 if (EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
350 return -1;
351 EVP_CIPHER_CTX_set_padding(&ctx, 0);
352
353 clen = data_len;
354 if (EVP_EncryptUpdate(&ctx, data, &clen, data, data_len) != 1 ||
355 clen != (int) data_len)
356 return -1;
357
358 len = sizeof(buf);
359 if (EVP_EncryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
360 return -1;
361 EVP_CIPHER_CTX_cleanup(&ctx);
362
363 return 0;
364}
365
366
367int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
368{
369 EVP_CIPHER_CTX ctx;
370 int plen, len;
371 u8 buf[16];
372
373 EVP_CIPHER_CTX_init(&ctx);
374 if (EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
375 return -1;
376 EVP_CIPHER_CTX_set_padding(&ctx, 0);
377
378 plen = data_len;
379 if (EVP_DecryptUpdate(&ctx, data, &plen, data, data_len) != 1 ||
380 plen != (int) data_len)
381 return -1;
382
383 len = sizeof(buf);
384 if (EVP_DecryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
385 return -1;
386 EVP_CIPHER_CTX_cleanup(&ctx);
387
388 return 0;
389}
390
391
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700392int crypto_mod_exp(const u8 *base, size_t base_len,
393 const u8 *power, size_t power_len,
394 const u8 *modulus, size_t modulus_len,
395 u8 *result, size_t *result_len)
396{
397 BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result;
398 int ret = -1;
399 BN_CTX *ctx;
400
401 ctx = BN_CTX_new();
402 if (ctx == NULL)
403 return -1;
404
405 bn_base = BN_bin2bn(base, base_len, NULL);
406 bn_exp = BN_bin2bn(power, power_len, NULL);
407 bn_modulus = BN_bin2bn(modulus, modulus_len, NULL);
408 bn_result = BN_new();
409
410 if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
411 bn_result == NULL)
412 goto error;
413
414 if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
415 goto error;
416
417 *result_len = BN_bn2bin(bn_result, result);
418 ret = 0;
419
420error:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700421 BN_clear_free(bn_base);
422 BN_clear_free(bn_exp);
423 BN_clear_free(bn_modulus);
424 BN_clear_free(bn_result);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700425 BN_CTX_free(ctx);
426 return ret;
427}
428
429
430struct crypto_cipher {
431 EVP_CIPHER_CTX enc;
432 EVP_CIPHER_CTX dec;
433};
434
435
436struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
437 const u8 *iv, const u8 *key,
438 size_t key_len)
439{
440 struct crypto_cipher *ctx;
441 const EVP_CIPHER *cipher;
442
443 ctx = os_zalloc(sizeof(*ctx));
444 if (ctx == NULL)
445 return NULL;
446
447 switch (alg) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800448#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700449#ifndef OPENSSL_NO_RC4
450 case CRYPTO_CIPHER_ALG_RC4:
451 cipher = EVP_rc4();
452 break;
453#endif /* OPENSSL_NO_RC4 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800454#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700455#ifndef OPENSSL_NO_AES
456 case CRYPTO_CIPHER_ALG_AES:
457 switch (key_len) {
458 case 16:
459 cipher = EVP_aes_128_cbc();
460 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700461#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 case 24:
463 cipher = EVP_aes_192_cbc();
464 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700465#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700466 case 32:
467 cipher = EVP_aes_256_cbc();
468 break;
469 default:
470 os_free(ctx);
471 return NULL;
472 }
473 break;
474#endif /* OPENSSL_NO_AES */
475#ifndef OPENSSL_NO_DES
476 case CRYPTO_CIPHER_ALG_3DES:
477 cipher = EVP_des_ede3_cbc();
478 break;
479 case CRYPTO_CIPHER_ALG_DES:
480 cipher = EVP_des_cbc();
481 break;
482#endif /* OPENSSL_NO_DES */
483#ifndef OPENSSL_NO_RC2
484 case CRYPTO_CIPHER_ALG_RC2:
485 cipher = EVP_rc2_ecb();
486 break;
487#endif /* OPENSSL_NO_RC2 */
488 default:
489 os_free(ctx);
490 return NULL;
491 }
492
493 EVP_CIPHER_CTX_init(&ctx->enc);
494 EVP_CIPHER_CTX_set_padding(&ctx->enc, 0);
495 if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) ||
496 !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) ||
497 !EVP_EncryptInit_ex(&ctx->enc, NULL, NULL, key, iv)) {
498 EVP_CIPHER_CTX_cleanup(&ctx->enc);
499 os_free(ctx);
500 return NULL;
501 }
502
503 EVP_CIPHER_CTX_init(&ctx->dec);
504 EVP_CIPHER_CTX_set_padding(&ctx->dec, 0);
505 if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) ||
506 !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) ||
507 !EVP_DecryptInit_ex(&ctx->dec, NULL, NULL, key, iv)) {
508 EVP_CIPHER_CTX_cleanup(&ctx->enc);
509 EVP_CIPHER_CTX_cleanup(&ctx->dec);
510 os_free(ctx);
511 return NULL;
512 }
513
514 return ctx;
515}
516
517
518int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
519 u8 *crypt, size_t len)
520{
521 int outl;
522 if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len))
523 return -1;
524 return 0;
525}
526
527
528int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
529 u8 *plain, size_t len)
530{
531 int outl;
532 outl = len;
533 if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len))
534 return -1;
535 return 0;
536}
537
538
539void crypto_cipher_deinit(struct crypto_cipher *ctx)
540{
541 EVP_CIPHER_CTX_cleanup(&ctx->enc);
542 EVP_CIPHER_CTX_cleanup(&ctx->dec);
543 os_free(ctx);
544}
545
546
547void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
548{
549 DH *dh;
550 struct wpabuf *pubkey = NULL, *privkey = NULL;
551 size_t publen, privlen;
552
553 *priv = NULL;
554 *publ = NULL;
555
556 dh = DH_new();
557 if (dh == NULL)
558 return NULL;
559
560 dh->g = BN_new();
561 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
562 goto err;
563
564 dh->p = get_group5_prime();
565 if (dh->p == NULL)
566 goto err;
567
568 if (DH_generate_key(dh) != 1)
569 goto err;
570
571 publen = BN_num_bytes(dh->pub_key);
572 pubkey = wpabuf_alloc(publen);
573 if (pubkey == NULL)
574 goto err;
575 privlen = BN_num_bytes(dh->priv_key);
576 privkey = wpabuf_alloc(privlen);
577 if (privkey == NULL)
578 goto err;
579
580 BN_bn2bin(dh->pub_key, wpabuf_put(pubkey, publen));
581 BN_bn2bin(dh->priv_key, wpabuf_put(privkey, privlen));
582
583 *priv = privkey;
584 *publ = pubkey;
585 return dh;
586
587err:
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800588 wpabuf_clear_free(pubkey);
589 wpabuf_clear_free(privkey);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700590 DH_free(dh);
591 return NULL;
592}
593
594
Dmitry Shmidt04949592012-07-19 12:16:46 -0700595void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
596{
597 DH *dh;
598
599 dh = DH_new();
600 if (dh == NULL)
601 return NULL;
602
603 dh->g = BN_new();
604 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
605 goto err;
606
607 dh->p = get_group5_prime();
608 if (dh->p == NULL)
609 goto err;
610
611 dh->priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
612 if (dh->priv_key == NULL)
613 goto err;
614
615 dh->pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
616 if (dh->pub_key == NULL)
617 goto err;
618
619 if (DH_generate_key(dh) != 1)
620 goto err;
621
622 return dh;
623
624err:
625 DH_free(dh);
626 return NULL;
627}
628
629
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700630struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
631 const struct wpabuf *own_private)
632{
633 BIGNUM *pub_key;
634 struct wpabuf *res = NULL;
635 size_t rlen;
636 DH *dh = ctx;
637 int keylen;
638
639 if (ctx == NULL)
640 return NULL;
641
642 pub_key = BN_bin2bn(wpabuf_head(peer_public), wpabuf_len(peer_public),
643 NULL);
644 if (pub_key == NULL)
645 return NULL;
646
647 rlen = DH_size(dh);
648 res = wpabuf_alloc(rlen);
649 if (res == NULL)
650 goto err;
651
652 keylen = DH_compute_key(wpabuf_mhead(res), pub_key, dh);
653 if (keylen < 0)
654 goto err;
655 wpabuf_put(res, keylen);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700656 BN_clear_free(pub_key);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700657
658 return res;
659
660err:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700661 BN_clear_free(pub_key);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800662 wpabuf_clear_free(res);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700663 return NULL;
664}
665
666
667void dh5_free(void *ctx)
668{
669 DH *dh;
670 if (ctx == NULL)
671 return;
672 dh = ctx;
673 DH_free(dh);
674}
Dmitry Shmidt04949592012-07-19 12:16:46 -0700675
676
677struct crypto_hash {
678 HMAC_CTX ctx;
679};
680
681
682struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
683 size_t key_len)
684{
685 struct crypto_hash *ctx;
686 const EVP_MD *md;
687
688 switch (alg) {
689#ifndef OPENSSL_NO_MD5
690 case CRYPTO_HASH_ALG_HMAC_MD5:
691 md = EVP_md5();
692 break;
693#endif /* OPENSSL_NO_MD5 */
694#ifndef OPENSSL_NO_SHA
695 case CRYPTO_HASH_ALG_HMAC_SHA1:
696 md = EVP_sha1();
697 break;
698#endif /* OPENSSL_NO_SHA */
699#ifndef OPENSSL_NO_SHA256
700#ifdef CONFIG_SHA256
701 case CRYPTO_HASH_ALG_HMAC_SHA256:
702 md = EVP_sha256();
703 break;
704#endif /* CONFIG_SHA256 */
705#endif /* OPENSSL_NO_SHA256 */
706 default:
707 return NULL;
708 }
709
710 ctx = os_zalloc(sizeof(*ctx));
711 if (ctx == NULL)
712 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700713 HMAC_CTX_init(&ctx->ctx);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700714
715#if OPENSSL_VERSION_NUMBER < 0x00909000
716 HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL);
717#else /* openssl < 0.9.9 */
718 if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800719 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700720 return NULL;
721 }
722#endif /* openssl < 0.9.9 */
723
724 return ctx;
725}
726
727
728void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
729{
730 if (ctx == NULL)
731 return;
732 HMAC_Update(&ctx->ctx, data, len);
733}
734
735
736int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
737{
738 unsigned int mdlen;
739 int res;
740
741 if (ctx == NULL)
742 return -2;
743
744 if (mac == NULL || len == NULL) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800745 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700746 return 0;
747 }
748
749 mdlen = *len;
750#if OPENSSL_VERSION_NUMBER < 0x00909000
751 HMAC_Final(&ctx->ctx, mac, &mdlen);
752 res = 1;
753#else /* openssl < 0.9.9 */
754 res = HMAC_Final(&ctx->ctx, mac, &mdlen);
755#endif /* openssl < 0.9.9 */
756 HMAC_CTX_cleanup(&ctx->ctx);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800757 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700758
759 if (res == 1) {
760 *len = mdlen;
761 return 0;
762 }
763
764 return -1;
765}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700766
767
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800768static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
769 size_t key_len, size_t num_elem,
770 const u8 *addr[], const size_t *len, u8 *mac,
771 unsigned int mdlen)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700772{
773 HMAC_CTX ctx;
774 size_t i;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700775 int res;
776
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800777 if (TEST_FAIL())
778 return -1;
779
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700780 HMAC_CTX_init(&ctx);
781#if OPENSSL_VERSION_NUMBER < 0x00909000
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800782 HMAC_Init_ex(&ctx, key, key_len, type, NULL);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700783#else /* openssl < 0.9.9 */
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800784 if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700785 return -1;
786#endif /* openssl < 0.9.9 */
787
788 for (i = 0; i < num_elem; i++)
789 HMAC_Update(&ctx, addr[i], len[i]);
790
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700791#if OPENSSL_VERSION_NUMBER < 0x00909000
792 HMAC_Final(&ctx, mac, &mdlen);
793 res = 1;
794#else /* openssl < 0.9.9 */
795 res = HMAC_Final(&ctx, mac, &mdlen);
796#endif /* openssl < 0.9.9 */
797 HMAC_CTX_cleanup(&ctx);
798
799 return res == 1 ? 0 : -1;
800}
801
802
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800803#ifndef CONFIG_FIPS
804
805int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
806 const u8 *addr[], const size_t *len, u8 *mac)
807{
808 return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
809 mac, 16);
810}
811
812
813int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
814 u8 *mac)
815{
816 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
817}
818
819#endif /* CONFIG_FIPS */
820
821
822int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
823 int iterations, u8 *buf, size_t buflen)
824{
825 if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
826 ssid_len, iterations, buflen, buf) != 1)
827 return -1;
828 return 0;
829}
830
831
832int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
833 const u8 *addr[], const size_t *len, u8 *mac)
834{
835 return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
836 len, mac, 20);
837}
838
839
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700840int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
841 u8 *mac)
842{
843 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
844}
845
846
847#ifdef CONFIG_SHA256
848
849int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
850 const u8 *addr[], const size_t *len, u8 *mac)
851{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800852 return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
853 len, mac, 32);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700854}
855
856
857int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
858 size_t data_len, u8 *mac)
859{
860 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
861}
862
863#endif /* CONFIG_SHA256 */
864
865
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800866#ifdef CONFIG_SHA384
867
868int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
869 const u8 *addr[], const size_t *len, u8 *mac)
870{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800871 return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
872 len, mac, 32);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800873}
874
875
876int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
877 size_t data_len, u8 *mac)
878{
879 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
880}
881
882#endif /* CONFIG_SHA384 */
883
884
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700885int crypto_get_random(void *buf, size_t len)
886{
887 if (RAND_bytes(buf, len) != 1)
888 return -1;
889 return 0;
890}
891
892
893#ifdef CONFIG_OPENSSL_CMAC
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800894int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
895 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700896{
897 CMAC_CTX *ctx;
898 int ret = -1;
899 size_t outlen, i;
900
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800901 if (TEST_FAIL())
902 return -1;
903
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700904 ctx = CMAC_CTX_new();
905 if (ctx == NULL)
906 return -1;
907
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800908 if (key_len == 32) {
909 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
910 goto fail;
911 } else if (key_len == 16) {
912 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
913 goto fail;
914 } else {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700915 goto fail;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800916 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700917 for (i = 0; i < num_elem; i++) {
918 if (!CMAC_Update(ctx, addr[i], len[i]))
919 goto fail;
920 }
921 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
922 goto fail;
923
924 ret = 0;
925fail:
926 CMAC_CTX_free(ctx);
927 return ret;
928}
929
930
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800931int omac1_aes_128_vector(const u8 *key, size_t num_elem,
932 const u8 *addr[], const size_t *len, u8 *mac)
933{
934 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
935}
936
937
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700938int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
939{
940 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
941}
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800942
943
944int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
945{
946 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
947}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700948#endif /* CONFIG_OPENSSL_CMAC */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -0800949
950
951struct crypto_bignum * crypto_bignum_init(void)
952{
953 return (struct crypto_bignum *) BN_new();
954}
955
956
957struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
958{
959 BIGNUM *bn = BN_bin2bn(buf, len, NULL);
960 return (struct crypto_bignum *) bn;
961}
962
963
964void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
965{
966 if (clear)
967 BN_clear_free((BIGNUM *) n);
968 else
969 BN_free((BIGNUM *) n);
970}
971
972
973int crypto_bignum_to_bin(const struct crypto_bignum *a,
974 u8 *buf, size_t buflen, size_t padlen)
975{
976 int num_bytes, offset;
977
978 if (padlen > buflen)
979 return -1;
980
981 num_bytes = BN_num_bytes((const BIGNUM *) a);
982 if ((size_t) num_bytes > buflen)
983 return -1;
984 if (padlen > (size_t) num_bytes)
985 offset = padlen - num_bytes;
986 else
987 offset = 0;
988
989 os_memset(buf, 0, offset);
990 BN_bn2bin((const BIGNUM *) a, buf + offset);
991
992 return num_bytes + offset;
993}
994
995
996int crypto_bignum_add(const struct crypto_bignum *a,
997 const struct crypto_bignum *b,
998 struct crypto_bignum *c)
999{
1000 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1001 0 : -1;
1002}
1003
1004
1005int crypto_bignum_mod(const struct crypto_bignum *a,
1006 const struct crypto_bignum *b,
1007 struct crypto_bignum *c)
1008{
1009 int res;
1010 BN_CTX *bnctx;
1011
1012 bnctx = BN_CTX_new();
1013 if (bnctx == NULL)
1014 return -1;
1015 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
1016 bnctx);
1017 BN_CTX_free(bnctx);
1018
1019 return res ? 0 : -1;
1020}
1021
1022
1023int crypto_bignum_exptmod(const struct crypto_bignum *a,
1024 const struct crypto_bignum *b,
1025 const struct crypto_bignum *c,
1026 struct crypto_bignum *d)
1027{
1028 int res;
1029 BN_CTX *bnctx;
1030
1031 bnctx = BN_CTX_new();
1032 if (bnctx == NULL)
1033 return -1;
1034 res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1035 (const BIGNUM *) c, bnctx);
1036 BN_CTX_free(bnctx);
1037
1038 return res ? 0 : -1;
1039}
1040
1041
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001042int crypto_bignum_inverse(const struct crypto_bignum *a,
1043 const struct crypto_bignum *b,
1044 struct crypto_bignum *c)
1045{
1046 BIGNUM *res;
1047 BN_CTX *bnctx;
1048
1049 bnctx = BN_CTX_new();
1050 if (bnctx == NULL)
1051 return -1;
1052 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
1053 (const BIGNUM *) b, bnctx);
1054 BN_CTX_free(bnctx);
1055
1056 return res ? 0 : -1;
1057}
1058
1059
1060int crypto_bignum_sub(const struct crypto_bignum *a,
1061 const struct crypto_bignum *b,
1062 struct crypto_bignum *c)
1063{
1064 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1065 0 : -1;
1066}
1067
1068
1069int crypto_bignum_div(const struct crypto_bignum *a,
1070 const struct crypto_bignum *b,
1071 struct crypto_bignum *c)
1072{
1073 int res;
1074
1075 BN_CTX *bnctx;
1076
1077 bnctx = BN_CTX_new();
1078 if (bnctx == NULL)
1079 return -1;
1080 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
1081 (const BIGNUM *) b, bnctx);
1082 BN_CTX_free(bnctx);
1083
1084 return res ? 0 : -1;
1085}
1086
1087
1088int crypto_bignum_mulmod(const struct crypto_bignum *a,
1089 const struct crypto_bignum *b,
1090 const struct crypto_bignum *c,
1091 struct crypto_bignum *d)
1092{
1093 int res;
1094
1095 BN_CTX *bnctx;
1096
1097 bnctx = BN_CTX_new();
1098 if (bnctx == NULL)
1099 return -1;
1100 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1101 (const BIGNUM *) c, bnctx);
1102 BN_CTX_free(bnctx);
1103
1104 return res ? 0 : -1;
1105}
1106
1107
1108int crypto_bignum_cmp(const struct crypto_bignum *a,
1109 const struct crypto_bignum *b)
1110{
1111 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
1112}
1113
1114
1115int crypto_bignum_bits(const struct crypto_bignum *a)
1116{
1117 return BN_num_bits((const BIGNUM *) a);
1118}
1119
1120
1121int crypto_bignum_is_zero(const struct crypto_bignum *a)
1122{
1123 return BN_is_zero((const BIGNUM *) a);
1124}
1125
1126
1127int crypto_bignum_is_one(const struct crypto_bignum *a)
1128{
1129 return BN_is_one((const BIGNUM *) a);
1130}
1131
1132
Dmitry Shmidt41712582015-06-29 11:02:15 -07001133int crypto_bignum_legendre(const struct crypto_bignum *a,
1134 const struct crypto_bignum *p)
1135{
1136 BN_CTX *bnctx;
1137 BIGNUM *exp = NULL, *tmp = NULL;
1138 int res = -2;
1139
1140 bnctx = BN_CTX_new();
1141 if (bnctx == NULL)
1142 return -2;
1143
1144 exp = BN_new();
1145 tmp = BN_new();
1146 if (!exp || !tmp ||
1147 /* exp = (p-1) / 2 */
1148 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
1149 !BN_rshift1(exp, exp) ||
1150 !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
1151 bnctx))
1152 goto fail;
1153
1154 if (BN_is_word(tmp, 1))
1155 res = 1;
1156 else if (BN_is_zero(tmp))
1157 res = 0;
1158 else
1159 res = -1;
1160
1161fail:
1162 BN_clear_free(tmp);
1163 BN_clear_free(exp);
1164 BN_CTX_free(bnctx);
1165 return res;
1166}
1167
1168
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001169#ifdef CONFIG_ECC
1170
1171struct crypto_ec {
1172 EC_GROUP *group;
1173 BN_CTX *bnctx;
1174 BIGNUM *prime;
1175 BIGNUM *order;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001176 BIGNUM *a;
1177 BIGNUM *b;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001178};
1179
1180struct crypto_ec * crypto_ec_init(int group)
1181{
1182 struct crypto_ec *e;
1183 int nid;
1184
1185 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1186 switch (group) {
1187 case 19:
1188 nid = NID_X9_62_prime256v1;
1189 break;
1190 case 20:
1191 nid = NID_secp384r1;
1192 break;
1193 case 21:
1194 nid = NID_secp521r1;
1195 break;
1196 case 25:
1197 nid = NID_X9_62_prime192v1;
1198 break;
1199 case 26:
1200 nid = NID_secp224r1;
1201 break;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001202#ifdef NID_brainpoolP224r1
1203 case 27:
1204 nid = NID_brainpoolP224r1;
1205 break;
1206#endif /* NID_brainpoolP224r1 */
1207#ifdef NID_brainpoolP256r1
1208 case 28:
1209 nid = NID_brainpoolP256r1;
1210 break;
1211#endif /* NID_brainpoolP256r1 */
1212#ifdef NID_brainpoolP384r1
1213 case 29:
1214 nid = NID_brainpoolP384r1;
1215 break;
1216#endif /* NID_brainpoolP384r1 */
1217#ifdef NID_brainpoolP512r1
1218 case 30:
1219 nid = NID_brainpoolP512r1;
1220 break;
1221#endif /* NID_brainpoolP512r1 */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001222 default:
1223 return NULL;
1224 }
1225
1226 e = os_zalloc(sizeof(*e));
1227 if (e == NULL)
1228 return NULL;
1229
1230 e->bnctx = BN_CTX_new();
1231 e->group = EC_GROUP_new_by_curve_name(nid);
1232 e->prime = BN_new();
1233 e->order = BN_new();
Dmitry Shmidt41712582015-06-29 11:02:15 -07001234 e->a = BN_new();
1235 e->b = BN_new();
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001236 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
Dmitry Shmidt41712582015-06-29 11:02:15 -07001237 e->order == NULL || e->a == NULL || e->b == NULL ||
1238 !EC_GROUP_get_curve_GFp(e->group, e->prime, e->a, e->b, e->bnctx) ||
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001239 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
1240 crypto_ec_deinit(e);
1241 e = NULL;
1242 }
1243
1244 return e;
1245}
1246
1247
1248void crypto_ec_deinit(struct crypto_ec *e)
1249{
1250 if (e == NULL)
1251 return;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001252 BN_clear_free(e->b);
1253 BN_clear_free(e->a);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001254 BN_clear_free(e->order);
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001255 BN_clear_free(e->prime);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001256 EC_GROUP_free(e->group);
1257 BN_CTX_free(e->bnctx);
1258 os_free(e);
1259}
1260
1261
1262struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1263{
1264 if (e == NULL)
1265 return NULL;
1266 return (struct crypto_ec_point *) EC_POINT_new(e->group);
1267}
1268
1269
1270size_t crypto_ec_prime_len(struct crypto_ec *e)
1271{
1272 return BN_num_bytes(e->prime);
1273}
1274
1275
1276size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1277{
1278 return BN_num_bits(e->prime);
1279}
1280
1281
1282const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1283{
1284 return (const struct crypto_bignum *) e->prime;
1285}
1286
1287
1288const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1289{
1290 return (const struct crypto_bignum *) e->order;
1291}
1292
1293
1294void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1295{
1296 if (clear)
1297 EC_POINT_clear_free((EC_POINT *) p);
1298 else
1299 EC_POINT_free((EC_POINT *) p);
1300}
1301
1302
1303int crypto_ec_point_to_bin(struct crypto_ec *e,
1304 const struct crypto_ec_point *point, u8 *x, u8 *y)
1305{
1306 BIGNUM *x_bn, *y_bn;
1307 int ret = -1;
1308 int len = BN_num_bytes(e->prime);
1309
1310 x_bn = BN_new();
1311 y_bn = BN_new();
1312
1313 if (x_bn && y_bn &&
1314 EC_POINT_get_affine_coordinates_GFp(e->group, (EC_POINT *) point,
1315 x_bn, y_bn, e->bnctx)) {
1316 if (x) {
1317 crypto_bignum_to_bin((struct crypto_bignum *) x_bn,
1318 x, len, len);
1319 }
1320 if (y) {
1321 crypto_bignum_to_bin((struct crypto_bignum *) y_bn,
1322 y, len, len);
1323 }
1324 ret = 0;
1325 }
1326
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001327 BN_clear_free(x_bn);
1328 BN_clear_free(y_bn);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001329 return ret;
1330}
1331
1332
1333struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1334 const u8 *val)
1335{
1336 BIGNUM *x, *y;
1337 EC_POINT *elem;
1338 int len = BN_num_bytes(e->prime);
1339
1340 x = BN_bin2bn(val, len, NULL);
1341 y = BN_bin2bn(val + len, len, NULL);
1342 elem = EC_POINT_new(e->group);
1343 if (x == NULL || y == NULL || elem == NULL) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001344 BN_clear_free(x);
1345 BN_clear_free(y);
1346 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001347 return NULL;
1348 }
1349
1350 if (!EC_POINT_set_affine_coordinates_GFp(e->group, elem, x, y,
1351 e->bnctx)) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001352 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001353 elem = NULL;
1354 }
1355
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001356 BN_clear_free(x);
1357 BN_clear_free(y);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001358
1359 return (struct crypto_ec_point *) elem;
1360}
1361
1362
1363int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1364 const struct crypto_ec_point *b,
1365 struct crypto_ec_point *c)
1366{
1367 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
1368 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
1369}
1370
1371
1372int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1373 const struct crypto_bignum *b,
1374 struct crypto_ec_point *res)
1375{
1376 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
1377 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
1378 ? 0 : -1;
1379}
1380
1381
1382int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1383{
1384 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
1385}
1386
1387
1388int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
1389 struct crypto_ec_point *p,
1390 const struct crypto_bignum *x, int y_bit)
1391{
1392 if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
1393 (const BIGNUM *) x, y_bit,
1394 e->bnctx) ||
1395 !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx))
1396 return -1;
1397 return 0;
1398}
1399
1400
Dmitry Shmidt41712582015-06-29 11:02:15 -07001401struct crypto_bignum *
1402crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1403 const struct crypto_bignum *x)
1404{
1405 BIGNUM *tmp, *tmp2, *y_sqr = NULL;
1406
1407 tmp = BN_new();
1408 tmp2 = BN_new();
1409
1410 /* y^2 = x^3 + ax + b */
1411 if (tmp && tmp2 &&
1412 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1413 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1414 BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
1415 BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
1416 BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
1417 y_sqr = tmp2;
1418 tmp2 = NULL;
1419 }
1420
1421 BN_clear_free(tmp);
1422 BN_clear_free(tmp2);
1423
1424 return (struct crypto_bignum *) y_sqr;
1425}
1426
1427
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001428int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1429 const struct crypto_ec_point *p)
1430{
1431 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
1432}
1433
1434
1435int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1436 const struct crypto_ec_point *p)
1437{
Dmitry Shmidt41712582015-06-29 11:02:15 -07001438 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
1439 e->bnctx) == 1;
1440}
1441
1442
1443int crypto_ec_point_cmp(const struct crypto_ec *e,
1444 const struct crypto_ec_point *a,
1445 const struct crypto_ec_point *b)
1446{
1447 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
1448 (const EC_POINT *) b, e->bnctx);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001449}
1450
1451#endif /* CONFIG_ECC */