blob: b53bc4a3985cd04dc240a0977988a5408213a307 [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{
Dmitry Shmidt55840ad2015-12-14 12:45:46 -080068#if OPENSSL_VERSION_NUMBER >= 0x10100000L
69 EVP_MD_CTX *ctx;
70 size_t i;
71 unsigned int mac_len;
72
73 if (TEST_FAIL())
74 return -1;
75
76 ctx = EVP_MD_CTX_new();
77 if (!ctx)
78 return -1;
79 if (!EVP_DigestInit_ex(ctx, type, NULL)) {
80 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
81 ERR_error_string(ERR_get_error(), NULL));
82 EVP_MD_CTX_free(ctx);
83 return -1;
84 }
85 for (i = 0; i < num_elem; i++) {
86 if (!EVP_DigestUpdate(ctx, addr[i], len[i])) {
87 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
88 "failed: %s",
89 ERR_error_string(ERR_get_error(), NULL));
90 EVP_MD_CTX_free(ctx);
91 return -1;
92 }
93 }
94 if (!EVP_DigestFinal(ctx, mac, &mac_len)) {
95 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
96 ERR_error_string(ERR_get_error(), NULL));
97 EVP_MD_CTX_free(ctx);
98 return -1;
99 }
100 EVP_MD_CTX_free(ctx);
101
102 return 0;
103#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700104 EVP_MD_CTX ctx;
105 size_t i;
106 unsigned int mac_len;
107
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800108 if (TEST_FAIL())
109 return -1;
110
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700111 EVP_MD_CTX_init(&ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700112 if (!EVP_DigestInit_ex(&ctx, type, NULL)) {
113 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
114 ERR_error_string(ERR_get_error(), NULL));
115 return -1;
116 }
117 for (i = 0; i < num_elem; i++) {
118 if (!EVP_DigestUpdate(&ctx, addr[i], len[i])) {
119 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
120 "failed: %s",
121 ERR_error_string(ERR_get_error(), NULL));
122 return -1;
123 }
124 }
125 if (!EVP_DigestFinal(&ctx, mac, &mac_len)) {
126 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
127 ERR_error_string(ERR_get_error(), NULL));
128 return -1;
129 }
130
131 return 0;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800132#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700133}
134
135
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800136#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700137int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
138{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700139 return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700140}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800141#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700142
143
144void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
145{
146 u8 pkey[8], next, tmp;
147 int i;
148 DES_key_schedule ks;
149
150 /* Add parity bits to the key */
151 next = 0;
152 for (i = 0; i < 7; i++) {
153 tmp = key[i];
154 pkey[i] = (tmp >> i) | next | 1;
155 next = tmp << (7 - i);
156 }
157 pkey[i] = next | 1;
158
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700159 DES_set_key((DES_cblock *) &pkey, &ks);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700160 DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
161 DES_ENCRYPT);
162}
163
164
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800165#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700166int rc4_skip(const u8 *key, size_t keylen, size_t skip,
167 u8 *data, size_t data_len)
168{
169#ifdef OPENSSL_NO_RC4
170 return -1;
171#else /* OPENSSL_NO_RC4 */
172 EVP_CIPHER_CTX ctx;
173 int outl;
174 int res = -1;
175 unsigned char skip_buf[16];
176
177 EVP_CIPHER_CTX_init(&ctx);
178 if (!EVP_CIPHER_CTX_set_padding(&ctx, 0) ||
179 !EVP_CipherInit_ex(&ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
180 !EVP_CIPHER_CTX_set_key_length(&ctx, keylen) ||
181 !EVP_CipherInit_ex(&ctx, NULL, NULL, key, NULL, 1))
182 goto out;
183
184 while (skip >= sizeof(skip_buf)) {
185 size_t len = skip;
186 if (len > sizeof(skip_buf))
187 len = sizeof(skip_buf);
188 if (!EVP_CipherUpdate(&ctx, skip_buf, &outl, skip_buf, len))
189 goto out;
190 skip -= len;
191 }
192
193 if (EVP_CipherUpdate(&ctx, data, &outl, data, data_len))
194 res = 0;
195
196out:
197 EVP_CIPHER_CTX_cleanup(&ctx);
198 return res;
199#endif /* OPENSSL_NO_RC4 */
200}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800201#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700202
203
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800204#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700205int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
206{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700207 return openssl_digest_vector(EVP_md5(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700208}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800209#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700210
211
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700212int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
213{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700214 return openssl_digest_vector(EVP_sha1(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700215}
216
217
218#ifndef NO_SHA256_WRAPPER
219int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
220 u8 *mac)
221{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700222 return openssl_digest_vector(EVP_sha256(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700223}
224#endif /* NO_SHA256_WRAPPER */
225
226
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700227static const EVP_CIPHER * aes_get_evp_cipher(size_t keylen)
228{
229 switch (keylen) {
230 case 16:
231 return EVP_aes_128_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700232#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700233 case 24:
234 return EVP_aes_192_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700235#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700236 case 32:
237 return EVP_aes_256_ecb();
238 }
239
240 return NULL;
241}
242
243
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700244void * aes_encrypt_init(const u8 *key, size_t len)
245{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700246 EVP_CIPHER_CTX *ctx;
247 const EVP_CIPHER *type;
248
249 type = aes_get_evp_cipher(len);
250 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700251 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700252
253 ctx = os_malloc(sizeof(*ctx));
254 if (ctx == NULL)
255 return NULL;
256 EVP_CIPHER_CTX_init(ctx);
257 if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
258 os_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700259 return NULL;
260 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700261 EVP_CIPHER_CTX_set_padding(ctx, 0);
262 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700263}
264
265
266void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
267{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700268 EVP_CIPHER_CTX *c = ctx;
269 int clen = 16;
270 if (EVP_EncryptUpdate(c, crypt, &clen, plain, 16) != 1) {
271 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptUpdate failed: %s",
272 ERR_error_string(ERR_get_error(), NULL));
273 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700274}
275
276
277void aes_encrypt_deinit(void *ctx)
278{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700279 EVP_CIPHER_CTX *c = ctx;
280 u8 buf[16];
281 int len = sizeof(buf);
282 if (EVP_EncryptFinal_ex(c, buf, &len) != 1) {
283 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptFinal_ex failed: "
284 "%s", ERR_error_string(ERR_get_error(), NULL));
285 }
286 if (len != 0) {
287 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
288 "in AES encrypt", len);
289 }
290 EVP_CIPHER_CTX_cleanup(c);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800291 bin_clear_free(c, sizeof(*c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700292}
293
294
295void * aes_decrypt_init(const u8 *key, size_t len)
296{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700297 EVP_CIPHER_CTX *ctx;
298 const EVP_CIPHER *type;
299
300 type = aes_get_evp_cipher(len);
301 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700302 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700303
304 ctx = os_malloc(sizeof(*ctx));
305 if (ctx == NULL)
306 return NULL;
307 EVP_CIPHER_CTX_init(ctx);
308 if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
309 os_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700310 return NULL;
311 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700312 EVP_CIPHER_CTX_set_padding(ctx, 0);
313 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700314}
315
316
317void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
318{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700319 EVP_CIPHER_CTX *c = ctx;
320 int plen = 16;
321 if (EVP_DecryptUpdate(c, plain, &plen, crypt, 16) != 1) {
322 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptUpdate failed: %s",
323 ERR_error_string(ERR_get_error(), NULL));
324 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700325}
326
327
328void aes_decrypt_deinit(void *ctx)
329{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700330 EVP_CIPHER_CTX *c = ctx;
331 u8 buf[16];
332 int len = sizeof(buf);
333 if (EVP_DecryptFinal_ex(c, buf, &len) != 1) {
334 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptFinal_ex failed: "
335 "%s", ERR_error_string(ERR_get_error(), NULL));
336 }
337 if (len != 0) {
338 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
339 "in AES decrypt", len);
340 }
341 EVP_CIPHER_CTX_cleanup(c);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800342 bin_clear_free(c, sizeof(*c));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700343}
344
345
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800346#ifndef CONFIG_FIPS
347#ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
348
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800349int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
350{
351 AES_KEY actx;
352 int res;
353
354 if (AES_set_encrypt_key(kek, kek_len << 3, &actx))
355 return -1;
356 res = AES_wrap_key(&actx, NULL, cipher, plain, n * 8);
357 OPENSSL_cleanse(&actx, sizeof(actx));
358 return res <= 0 ? -1 : 0;
359}
360
361
362int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
363 u8 *plain)
364{
365 AES_KEY actx;
366 int res;
367
368 if (AES_set_decrypt_key(kek, kek_len << 3, &actx))
369 return -1;
370 res = AES_unwrap_key(&actx, NULL, plain, cipher, (n + 1) * 8);
371 OPENSSL_cleanse(&actx, sizeof(actx));
372 return res <= 0 ? -1 : 0;
373}
374
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800375#endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
376#endif /* CONFIG_FIPS */
377
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800378
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700379int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
380{
381 EVP_CIPHER_CTX ctx;
382 int clen, len;
383 u8 buf[16];
384
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800385 if (TEST_FAIL())
386 return -1;
387
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700388 EVP_CIPHER_CTX_init(&ctx);
389 if (EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
390 return -1;
391 EVP_CIPHER_CTX_set_padding(&ctx, 0);
392
393 clen = data_len;
394 if (EVP_EncryptUpdate(&ctx, data, &clen, data, data_len) != 1 ||
395 clen != (int) data_len)
396 return -1;
397
398 len = sizeof(buf);
399 if (EVP_EncryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
400 return -1;
401 EVP_CIPHER_CTX_cleanup(&ctx);
402
403 return 0;
404}
405
406
407int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
408{
409 EVP_CIPHER_CTX ctx;
410 int plen, len;
411 u8 buf[16];
412
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800413 if (TEST_FAIL())
414 return -1;
415
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700416 EVP_CIPHER_CTX_init(&ctx);
417 if (EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
418 return -1;
419 EVP_CIPHER_CTX_set_padding(&ctx, 0);
420
421 plen = data_len;
422 if (EVP_DecryptUpdate(&ctx, data, &plen, data, data_len) != 1 ||
423 plen != (int) data_len)
424 return -1;
425
426 len = sizeof(buf);
427 if (EVP_DecryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
428 return -1;
429 EVP_CIPHER_CTX_cleanup(&ctx);
430
431 return 0;
432}
433
434
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700435int crypto_mod_exp(const u8 *base, size_t base_len,
436 const u8 *power, size_t power_len,
437 const u8 *modulus, size_t modulus_len,
438 u8 *result, size_t *result_len)
439{
440 BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result;
441 int ret = -1;
442 BN_CTX *ctx;
443
444 ctx = BN_CTX_new();
445 if (ctx == NULL)
446 return -1;
447
448 bn_base = BN_bin2bn(base, base_len, NULL);
449 bn_exp = BN_bin2bn(power, power_len, NULL);
450 bn_modulus = BN_bin2bn(modulus, modulus_len, NULL);
451 bn_result = BN_new();
452
453 if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
454 bn_result == NULL)
455 goto error;
456
457 if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
458 goto error;
459
460 *result_len = BN_bn2bin(bn_result, result);
461 ret = 0;
462
463error:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700464 BN_clear_free(bn_base);
465 BN_clear_free(bn_exp);
466 BN_clear_free(bn_modulus);
467 BN_clear_free(bn_result);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700468 BN_CTX_free(ctx);
469 return ret;
470}
471
472
473struct crypto_cipher {
474 EVP_CIPHER_CTX enc;
475 EVP_CIPHER_CTX dec;
476};
477
478
479struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
480 const u8 *iv, const u8 *key,
481 size_t key_len)
482{
483 struct crypto_cipher *ctx;
484 const EVP_CIPHER *cipher;
485
486 ctx = os_zalloc(sizeof(*ctx));
487 if (ctx == NULL)
488 return NULL;
489
490 switch (alg) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800491#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700492#ifndef OPENSSL_NO_RC4
493 case CRYPTO_CIPHER_ALG_RC4:
494 cipher = EVP_rc4();
495 break;
496#endif /* OPENSSL_NO_RC4 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800497#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700498#ifndef OPENSSL_NO_AES
499 case CRYPTO_CIPHER_ALG_AES:
500 switch (key_len) {
501 case 16:
502 cipher = EVP_aes_128_cbc();
503 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700504#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700505 case 24:
506 cipher = EVP_aes_192_cbc();
507 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700508#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700509 case 32:
510 cipher = EVP_aes_256_cbc();
511 break;
512 default:
513 os_free(ctx);
514 return NULL;
515 }
516 break;
517#endif /* OPENSSL_NO_AES */
518#ifndef OPENSSL_NO_DES
519 case CRYPTO_CIPHER_ALG_3DES:
520 cipher = EVP_des_ede3_cbc();
521 break;
522 case CRYPTO_CIPHER_ALG_DES:
523 cipher = EVP_des_cbc();
524 break;
525#endif /* OPENSSL_NO_DES */
526#ifndef OPENSSL_NO_RC2
527 case CRYPTO_CIPHER_ALG_RC2:
528 cipher = EVP_rc2_ecb();
529 break;
530#endif /* OPENSSL_NO_RC2 */
531 default:
532 os_free(ctx);
533 return NULL;
534 }
535
536 EVP_CIPHER_CTX_init(&ctx->enc);
537 EVP_CIPHER_CTX_set_padding(&ctx->enc, 0);
538 if (!EVP_EncryptInit_ex(&ctx->enc, cipher, NULL, NULL, NULL) ||
539 !EVP_CIPHER_CTX_set_key_length(&ctx->enc, key_len) ||
540 !EVP_EncryptInit_ex(&ctx->enc, NULL, NULL, key, iv)) {
541 EVP_CIPHER_CTX_cleanup(&ctx->enc);
542 os_free(ctx);
543 return NULL;
544 }
545
546 EVP_CIPHER_CTX_init(&ctx->dec);
547 EVP_CIPHER_CTX_set_padding(&ctx->dec, 0);
548 if (!EVP_DecryptInit_ex(&ctx->dec, cipher, NULL, NULL, NULL) ||
549 !EVP_CIPHER_CTX_set_key_length(&ctx->dec, key_len) ||
550 !EVP_DecryptInit_ex(&ctx->dec, NULL, NULL, key, iv)) {
551 EVP_CIPHER_CTX_cleanup(&ctx->enc);
552 EVP_CIPHER_CTX_cleanup(&ctx->dec);
553 os_free(ctx);
554 return NULL;
555 }
556
557 return ctx;
558}
559
560
561int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
562 u8 *crypt, size_t len)
563{
564 int outl;
565 if (!EVP_EncryptUpdate(&ctx->enc, crypt, &outl, plain, len))
566 return -1;
567 return 0;
568}
569
570
571int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
572 u8 *plain, size_t len)
573{
574 int outl;
575 outl = len;
576 if (!EVP_DecryptUpdate(&ctx->dec, plain, &outl, crypt, len))
577 return -1;
578 return 0;
579}
580
581
582void crypto_cipher_deinit(struct crypto_cipher *ctx)
583{
584 EVP_CIPHER_CTX_cleanup(&ctx->enc);
585 EVP_CIPHER_CTX_cleanup(&ctx->dec);
586 os_free(ctx);
587}
588
589
590void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
591{
592 DH *dh;
593 struct wpabuf *pubkey = NULL, *privkey = NULL;
594 size_t publen, privlen;
595
596 *priv = NULL;
597 *publ = NULL;
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 if (DH_generate_key(dh) != 1)
612 goto err;
613
614 publen = BN_num_bytes(dh->pub_key);
615 pubkey = wpabuf_alloc(publen);
616 if (pubkey == NULL)
617 goto err;
618 privlen = BN_num_bytes(dh->priv_key);
619 privkey = wpabuf_alloc(privlen);
620 if (privkey == NULL)
621 goto err;
622
623 BN_bn2bin(dh->pub_key, wpabuf_put(pubkey, publen));
624 BN_bn2bin(dh->priv_key, wpabuf_put(privkey, privlen));
625
626 *priv = privkey;
627 *publ = pubkey;
628 return dh;
629
630err:
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800631 wpabuf_clear_free(pubkey);
632 wpabuf_clear_free(privkey);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700633 DH_free(dh);
634 return NULL;
635}
636
637
Dmitry Shmidt04949592012-07-19 12:16:46 -0700638void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
639{
640 DH *dh;
641
642 dh = DH_new();
643 if (dh == NULL)
644 return NULL;
645
646 dh->g = BN_new();
647 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
648 goto err;
649
650 dh->p = get_group5_prime();
651 if (dh->p == NULL)
652 goto err;
653
654 dh->priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
655 if (dh->priv_key == NULL)
656 goto err;
657
658 dh->pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
659 if (dh->pub_key == NULL)
660 goto err;
661
662 if (DH_generate_key(dh) != 1)
663 goto err;
664
665 return dh;
666
667err:
668 DH_free(dh);
669 return NULL;
670}
671
672
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700673struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
674 const struct wpabuf *own_private)
675{
676 BIGNUM *pub_key;
677 struct wpabuf *res = NULL;
678 size_t rlen;
679 DH *dh = ctx;
680 int keylen;
681
682 if (ctx == NULL)
683 return NULL;
684
685 pub_key = BN_bin2bn(wpabuf_head(peer_public), wpabuf_len(peer_public),
686 NULL);
687 if (pub_key == NULL)
688 return NULL;
689
690 rlen = DH_size(dh);
691 res = wpabuf_alloc(rlen);
692 if (res == NULL)
693 goto err;
694
695 keylen = DH_compute_key(wpabuf_mhead(res), pub_key, dh);
696 if (keylen < 0)
697 goto err;
698 wpabuf_put(res, keylen);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700699 BN_clear_free(pub_key);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700700
701 return res;
702
703err:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700704 BN_clear_free(pub_key);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800705 wpabuf_clear_free(res);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700706 return NULL;
707}
708
709
710void dh5_free(void *ctx)
711{
712 DH *dh;
713 if (ctx == NULL)
714 return;
715 dh = ctx;
716 DH_free(dh);
717}
Dmitry Shmidt04949592012-07-19 12:16:46 -0700718
719
720struct crypto_hash {
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800721#if OPENSSL_VERSION_NUMBER >= 0x10100000L
722 HMAC_CTX *ctx;
723#else
Dmitry Shmidt04949592012-07-19 12:16:46 -0700724 HMAC_CTX ctx;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800725#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700726};
727
728
729struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
730 size_t key_len)
731{
732 struct crypto_hash *ctx;
733 const EVP_MD *md;
734
735 switch (alg) {
736#ifndef OPENSSL_NO_MD5
737 case CRYPTO_HASH_ALG_HMAC_MD5:
738 md = EVP_md5();
739 break;
740#endif /* OPENSSL_NO_MD5 */
741#ifndef OPENSSL_NO_SHA
742 case CRYPTO_HASH_ALG_HMAC_SHA1:
743 md = EVP_sha1();
744 break;
745#endif /* OPENSSL_NO_SHA */
746#ifndef OPENSSL_NO_SHA256
747#ifdef CONFIG_SHA256
748 case CRYPTO_HASH_ALG_HMAC_SHA256:
749 md = EVP_sha256();
750 break;
751#endif /* CONFIG_SHA256 */
752#endif /* OPENSSL_NO_SHA256 */
753 default:
754 return NULL;
755 }
756
757 ctx = os_zalloc(sizeof(*ctx));
758 if (ctx == NULL)
759 return NULL;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800760#if OPENSSL_VERSION_NUMBER >= 0x10100000L
761 ctx->ctx = HMAC_CTX_new();
762 if (!ctx->ctx) {
763 os_free(ctx);
764 return NULL;
765 }
766
767 if (HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL) != 1) {
768 HMAC_CTX_free(ctx->ctx);
769 bin_clear_free(ctx, sizeof(*ctx));
770 return NULL;
771 }
772#else
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700773 HMAC_CTX_init(&ctx->ctx);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700774
775#if OPENSSL_VERSION_NUMBER < 0x00909000
776 HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL);
777#else /* openssl < 0.9.9 */
778 if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800779 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700780 return NULL;
781 }
782#endif /* openssl < 0.9.9 */
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800783#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700784
785 return ctx;
786}
787
788
789void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
790{
791 if (ctx == NULL)
792 return;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800793#if OPENSSL_VERSION_NUMBER >= 0x10100000L
794 HMAC_Update(ctx->ctx, data, len);
795#else
Dmitry Shmidt04949592012-07-19 12:16:46 -0700796 HMAC_Update(&ctx->ctx, data, len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800797#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700798}
799
800
801int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
802{
803 unsigned int mdlen;
804 int res;
805
806 if (ctx == NULL)
807 return -2;
808
809 if (mac == NULL || len == NULL) {
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800810#if OPENSSL_VERSION_NUMBER >= 0x10100000L
811 HMAC_CTX_free(ctx->ctx);
812#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800813 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700814 return 0;
815 }
816
817 mdlen = *len;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800818#if OPENSSL_VERSION_NUMBER >= 0x10100000L
819 res = HMAC_Final(ctx->ctx, mac, &mdlen);
820 HMAC_CTX_free(ctx->ctx);
821#else
Dmitry Shmidt04949592012-07-19 12:16:46 -0700822#if OPENSSL_VERSION_NUMBER < 0x00909000
823 HMAC_Final(&ctx->ctx, mac, &mdlen);
824 res = 1;
825#else /* openssl < 0.9.9 */
826 res = HMAC_Final(&ctx->ctx, mac, &mdlen);
827#endif /* openssl < 0.9.9 */
828 HMAC_CTX_cleanup(&ctx->ctx);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800829#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800830 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700831
832 if (res == 1) {
833 *len = mdlen;
834 return 0;
835 }
836
837 return -1;
838}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700839
840
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800841static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
842 size_t key_len, size_t num_elem,
843 const u8 *addr[], const size_t *len, u8 *mac,
844 unsigned int mdlen)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700845{
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800846#if OPENSSL_VERSION_NUMBER >= 0x10100000L
847 HMAC_CTX *ctx;
848 size_t i;
849 int res;
850
851 if (TEST_FAIL())
852 return -1;
853
854 ctx = HMAC_CTX_new();
855 if (!ctx)
856 return -1;
857 res = HMAC_Init_ex(ctx, key, key_len, type, NULL);
858 if (res != 1)
859 goto done;
860
861 for (i = 0; i < num_elem; i++)
862 HMAC_Update(ctx, addr[i], len[i]);
863
864 res = HMAC_Final(ctx, mac, &mdlen);
865done:
866 HMAC_CTX_free(ctx);
867
868 return res == 1 ? 0 : -1;
869#else
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700870 HMAC_CTX ctx;
871 size_t i;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700872 int res;
873
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800874 if (TEST_FAIL())
875 return -1;
876
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700877 HMAC_CTX_init(&ctx);
878#if OPENSSL_VERSION_NUMBER < 0x00909000
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800879 HMAC_Init_ex(&ctx, key, key_len, type, NULL);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700880#else /* openssl < 0.9.9 */
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800881 if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700882 return -1;
883#endif /* openssl < 0.9.9 */
884
885 for (i = 0; i < num_elem; i++)
886 HMAC_Update(&ctx, addr[i], len[i]);
887
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700888#if OPENSSL_VERSION_NUMBER < 0x00909000
889 HMAC_Final(&ctx, mac, &mdlen);
890 res = 1;
891#else /* openssl < 0.9.9 */
892 res = HMAC_Final(&ctx, mac, &mdlen);
893#endif /* openssl < 0.9.9 */
894 HMAC_CTX_cleanup(&ctx);
895
896 return res == 1 ? 0 : -1;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800897#endif
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700898}
899
900
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800901#ifndef CONFIG_FIPS
902
903int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
904 const u8 *addr[], const size_t *len, u8 *mac)
905{
906 return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
907 mac, 16);
908}
909
910
911int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
912 u8 *mac)
913{
914 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
915}
916
917#endif /* CONFIG_FIPS */
918
919
920int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
921 int iterations, u8 *buf, size_t buflen)
922{
923 if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
924 ssid_len, iterations, buflen, buf) != 1)
925 return -1;
926 return 0;
927}
928
929
930int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
931 const u8 *addr[], const size_t *len, u8 *mac)
932{
933 return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
934 len, mac, 20);
935}
936
937
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700938int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
939 u8 *mac)
940{
941 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
942}
943
944
945#ifdef CONFIG_SHA256
946
947int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
948 const u8 *addr[], const size_t *len, u8 *mac)
949{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800950 return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
951 len, mac, 32);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700952}
953
954
955int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
956 size_t data_len, u8 *mac)
957{
958 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
959}
960
961#endif /* CONFIG_SHA256 */
962
963
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800964#ifdef CONFIG_SHA384
965
966int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
967 const u8 *addr[], const size_t *len, u8 *mac)
968{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800969 return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
970 len, mac, 32);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800971}
972
973
974int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
975 size_t data_len, u8 *mac)
976{
977 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
978}
979
980#endif /* CONFIG_SHA384 */
981
982
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700983int crypto_get_random(void *buf, size_t len)
984{
985 if (RAND_bytes(buf, len) != 1)
986 return -1;
987 return 0;
988}
989
990
991#ifdef CONFIG_OPENSSL_CMAC
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800992int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
993 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700994{
995 CMAC_CTX *ctx;
996 int ret = -1;
997 size_t outlen, i;
998
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800999 if (TEST_FAIL())
1000 return -1;
1001
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001002 ctx = CMAC_CTX_new();
1003 if (ctx == NULL)
1004 return -1;
1005
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001006 if (key_len == 32) {
1007 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
1008 goto fail;
1009 } else if (key_len == 16) {
1010 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
1011 goto fail;
1012 } else {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001013 goto fail;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001014 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001015 for (i = 0; i < num_elem; i++) {
1016 if (!CMAC_Update(ctx, addr[i], len[i]))
1017 goto fail;
1018 }
1019 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
1020 goto fail;
1021
1022 ret = 0;
1023fail:
1024 CMAC_CTX_free(ctx);
1025 return ret;
1026}
1027
1028
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001029int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1030 const u8 *addr[], const size_t *len, u8 *mac)
1031{
1032 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1033}
1034
1035
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001036int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1037{
1038 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1039}
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001040
1041
1042int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1043{
1044 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1045}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001046#endif /* CONFIG_OPENSSL_CMAC */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001047
1048
1049struct crypto_bignum * crypto_bignum_init(void)
1050{
1051 return (struct crypto_bignum *) BN_new();
1052}
1053
1054
1055struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1056{
1057 BIGNUM *bn = BN_bin2bn(buf, len, NULL);
1058 return (struct crypto_bignum *) bn;
1059}
1060
1061
1062void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1063{
1064 if (clear)
1065 BN_clear_free((BIGNUM *) n);
1066 else
1067 BN_free((BIGNUM *) n);
1068}
1069
1070
1071int crypto_bignum_to_bin(const struct crypto_bignum *a,
1072 u8 *buf, size_t buflen, size_t padlen)
1073{
1074 int num_bytes, offset;
1075
1076 if (padlen > buflen)
1077 return -1;
1078
1079 num_bytes = BN_num_bytes((const BIGNUM *) a);
1080 if ((size_t) num_bytes > buflen)
1081 return -1;
1082 if (padlen > (size_t) num_bytes)
1083 offset = padlen - num_bytes;
1084 else
1085 offset = 0;
1086
1087 os_memset(buf, 0, offset);
1088 BN_bn2bin((const BIGNUM *) a, buf + offset);
1089
1090 return num_bytes + offset;
1091}
1092
1093
1094int crypto_bignum_add(const struct crypto_bignum *a,
1095 const struct crypto_bignum *b,
1096 struct crypto_bignum *c)
1097{
1098 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1099 0 : -1;
1100}
1101
1102
1103int crypto_bignum_mod(const struct crypto_bignum *a,
1104 const struct crypto_bignum *b,
1105 struct crypto_bignum *c)
1106{
1107 int res;
1108 BN_CTX *bnctx;
1109
1110 bnctx = BN_CTX_new();
1111 if (bnctx == NULL)
1112 return -1;
1113 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
1114 bnctx);
1115 BN_CTX_free(bnctx);
1116
1117 return res ? 0 : -1;
1118}
1119
1120
1121int crypto_bignum_exptmod(const struct crypto_bignum *a,
1122 const struct crypto_bignum *b,
1123 const struct crypto_bignum *c,
1124 struct crypto_bignum *d)
1125{
1126 int res;
1127 BN_CTX *bnctx;
1128
1129 bnctx = BN_CTX_new();
1130 if (bnctx == NULL)
1131 return -1;
1132 res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1133 (const BIGNUM *) c, bnctx);
1134 BN_CTX_free(bnctx);
1135
1136 return res ? 0 : -1;
1137}
1138
1139
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001140int crypto_bignum_inverse(const struct crypto_bignum *a,
1141 const struct crypto_bignum *b,
1142 struct crypto_bignum *c)
1143{
1144 BIGNUM *res;
1145 BN_CTX *bnctx;
1146
1147 bnctx = BN_CTX_new();
1148 if (bnctx == NULL)
1149 return -1;
1150 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
1151 (const BIGNUM *) b, bnctx);
1152 BN_CTX_free(bnctx);
1153
1154 return res ? 0 : -1;
1155}
1156
1157
1158int crypto_bignum_sub(const struct crypto_bignum *a,
1159 const struct crypto_bignum *b,
1160 struct crypto_bignum *c)
1161{
1162 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1163 0 : -1;
1164}
1165
1166
1167int crypto_bignum_div(const struct crypto_bignum *a,
1168 const struct crypto_bignum *b,
1169 struct crypto_bignum *c)
1170{
1171 int res;
1172
1173 BN_CTX *bnctx;
1174
1175 bnctx = BN_CTX_new();
1176 if (bnctx == NULL)
1177 return -1;
1178 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
1179 (const BIGNUM *) b, bnctx);
1180 BN_CTX_free(bnctx);
1181
1182 return res ? 0 : -1;
1183}
1184
1185
1186int crypto_bignum_mulmod(const struct crypto_bignum *a,
1187 const struct crypto_bignum *b,
1188 const struct crypto_bignum *c,
1189 struct crypto_bignum *d)
1190{
1191 int res;
1192
1193 BN_CTX *bnctx;
1194
1195 bnctx = BN_CTX_new();
1196 if (bnctx == NULL)
1197 return -1;
1198 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1199 (const BIGNUM *) c, bnctx);
1200 BN_CTX_free(bnctx);
1201
1202 return res ? 0 : -1;
1203}
1204
1205
1206int crypto_bignum_cmp(const struct crypto_bignum *a,
1207 const struct crypto_bignum *b)
1208{
1209 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
1210}
1211
1212
1213int crypto_bignum_bits(const struct crypto_bignum *a)
1214{
1215 return BN_num_bits((const BIGNUM *) a);
1216}
1217
1218
1219int crypto_bignum_is_zero(const struct crypto_bignum *a)
1220{
1221 return BN_is_zero((const BIGNUM *) a);
1222}
1223
1224
1225int crypto_bignum_is_one(const struct crypto_bignum *a)
1226{
1227 return BN_is_one((const BIGNUM *) a);
1228}
1229
1230
Dmitry Shmidt41712582015-06-29 11:02:15 -07001231int crypto_bignum_legendre(const struct crypto_bignum *a,
1232 const struct crypto_bignum *p)
1233{
1234 BN_CTX *bnctx;
1235 BIGNUM *exp = NULL, *tmp = NULL;
1236 int res = -2;
1237
1238 bnctx = BN_CTX_new();
1239 if (bnctx == NULL)
1240 return -2;
1241
1242 exp = BN_new();
1243 tmp = BN_new();
1244 if (!exp || !tmp ||
1245 /* exp = (p-1) / 2 */
1246 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
1247 !BN_rshift1(exp, exp) ||
1248 !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
1249 bnctx))
1250 goto fail;
1251
1252 if (BN_is_word(tmp, 1))
1253 res = 1;
1254 else if (BN_is_zero(tmp))
1255 res = 0;
1256 else
1257 res = -1;
1258
1259fail:
1260 BN_clear_free(tmp);
1261 BN_clear_free(exp);
1262 BN_CTX_free(bnctx);
1263 return res;
1264}
1265
1266
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001267#ifdef CONFIG_ECC
1268
1269struct crypto_ec {
1270 EC_GROUP *group;
1271 BN_CTX *bnctx;
1272 BIGNUM *prime;
1273 BIGNUM *order;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001274 BIGNUM *a;
1275 BIGNUM *b;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001276};
1277
1278struct crypto_ec * crypto_ec_init(int group)
1279{
1280 struct crypto_ec *e;
1281 int nid;
1282
1283 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1284 switch (group) {
1285 case 19:
1286 nid = NID_X9_62_prime256v1;
1287 break;
1288 case 20:
1289 nid = NID_secp384r1;
1290 break;
1291 case 21:
1292 nid = NID_secp521r1;
1293 break;
1294 case 25:
1295 nid = NID_X9_62_prime192v1;
1296 break;
1297 case 26:
1298 nid = NID_secp224r1;
1299 break;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001300#ifdef NID_brainpoolP224r1
1301 case 27:
1302 nid = NID_brainpoolP224r1;
1303 break;
1304#endif /* NID_brainpoolP224r1 */
1305#ifdef NID_brainpoolP256r1
1306 case 28:
1307 nid = NID_brainpoolP256r1;
1308 break;
1309#endif /* NID_brainpoolP256r1 */
1310#ifdef NID_brainpoolP384r1
1311 case 29:
1312 nid = NID_brainpoolP384r1;
1313 break;
1314#endif /* NID_brainpoolP384r1 */
1315#ifdef NID_brainpoolP512r1
1316 case 30:
1317 nid = NID_brainpoolP512r1;
1318 break;
1319#endif /* NID_brainpoolP512r1 */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001320 default:
1321 return NULL;
1322 }
1323
1324 e = os_zalloc(sizeof(*e));
1325 if (e == NULL)
1326 return NULL;
1327
1328 e->bnctx = BN_CTX_new();
1329 e->group = EC_GROUP_new_by_curve_name(nid);
1330 e->prime = BN_new();
1331 e->order = BN_new();
Dmitry Shmidt41712582015-06-29 11:02:15 -07001332 e->a = BN_new();
1333 e->b = BN_new();
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001334 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
Dmitry Shmidt41712582015-06-29 11:02:15 -07001335 e->order == NULL || e->a == NULL || e->b == NULL ||
1336 !EC_GROUP_get_curve_GFp(e->group, e->prime, e->a, e->b, e->bnctx) ||
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001337 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
1338 crypto_ec_deinit(e);
1339 e = NULL;
1340 }
1341
1342 return e;
1343}
1344
1345
1346void crypto_ec_deinit(struct crypto_ec *e)
1347{
1348 if (e == NULL)
1349 return;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001350 BN_clear_free(e->b);
1351 BN_clear_free(e->a);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001352 BN_clear_free(e->order);
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001353 BN_clear_free(e->prime);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001354 EC_GROUP_free(e->group);
1355 BN_CTX_free(e->bnctx);
1356 os_free(e);
1357}
1358
1359
1360struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1361{
1362 if (e == NULL)
1363 return NULL;
1364 return (struct crypto_ec_point *) EC_POINT_new(e->group);
1365}
1366
1367
1368size_t crypto_ec_prime_len(struct crypto_ec *e)
1369{
1370 return BN_num_bytes(e->prime);
1371}
1372
1373
1374size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1375{
1376 return BN_num_bits(e->prime);
1377}
1378
1379
1380const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1381{
1382 return (const struct crypto_bignum *) e->prime;
1383}
1384
1385
1386const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1387{
1388 return (const struct crypto_bignum *) e->order;
1389}
1390
1391
1392void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1393{
1394 if (clear)
1395 EC_POINT_clear_free((EC_POINT *) p);
1396 else
1397 EC_POINT_free((EC_POINT *) p);
1398}
1399
1400
1401int crypto_ec_point_to_bin(struct crypto_ec *e,
1402 const struct crypto_ec_point *point, u8 *x, u8 *y)
1403{
1404 BIGNUM *x_bn, *y_bn;
1405 int ret = -1;
1406 int len = BN_num_bytes(e->prime);
1407
1408 x_bn = BN_new();
1409 y_bn = BN_new();
1410
1411 if (x_bn && y_bn &&
1412 EC_POINT_get_affine_coordinates_GFp(e->group, (EC_POINT *) point,
1413 x_bn, y_bn, e->bnctx)) {
1414 if (x) {
1415 crypto_bignum_to_bin((struct crypto_bignum *) x_bn,
1416 x, len, len);
1417 }
1418 if (y) {
1419 crypto_bignum_to_bin((struct crypto_bignum *) y_bn,
1420 y, len, len);
1421 }
1422 ret = 0;
1423 }
1424
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001425 BN_clear_free(x_bn);
1426 BN_clear_free(y_bn);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001427 return ret;
1428}
1429
1430
1431struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1432 const u8 *val)
1433{
1434 BIGNUM *x, *y;
1435 EC_POINT *elem;
1436 int len = BN_num_bytes(e->prime);
1437
1438 x = BN_bin2bn(val, len, NULL);
1439 y = BN_bin2bn(val + len, len, NULL);
1440 elem = EC_POINT_new(e->group);
1441 if (x == NULL || y == NULL || elem == NULL) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001442 BN_clear_free(x);
1443 BN_clear_free(y);
1444 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001445 return NULL;
1446 }
1447
1448 if (!EC_POINT_set_affine_coordinates_GFp(e->group, elem, x, y,
1449 e->bnctx)) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001450 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001451 elem = NULL;
1452 }
1453
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001454 BN_clear_free(x);
1455 BN_clear_free(y);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001456
1457 return (struct crypto_ec_point *) elem;
1458}
1459
1460
1461int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1462 const struct crypto_ec_point *b,
1463 struct crypto_ec_point *c)
1464{
1465 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
1466 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
1467}
1468
1469
1470int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1471 const struct crypto_bignum *b,
1472 struct crypto_ec_point *res)
1473{
1474 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
1475 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
1476 ? 0 : -1;
1477}
1478
1479
1480int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1481{
1482 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
1483}
1484
1485
1486int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
1487 struct crypto_ec_point *p,
1488 const struct crypto_bignum *x, int y_bit)
1489{
1490 if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
1491 (const BIGNUM *) x, y_bit,
1492 e->bnctx) ||
1493 !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx))
1494 return -1;
1495 return 0;
1496}
1497
1498
Dmitry Shmidt41712582015-06-29 11:02:15 -07001499struct crypto_bignum *
1500crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1501 const struct crypto_bignum *x)
1502{
1503 BIGNUM *tmp, *tmp2, *y_sqr = NULL;
1504
1505 tmp = BN_new();
1506 tmp2 = BN_new();
1507
1508 /* y^2 = x^3 + ax + b */
1509 if (tmp && tmp2 &&
1510 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1511 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1512 BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
1513 BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
1514 BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
1515 y_sqr = tmp2;
1516 tmp2 = NULL;
1517 }
1518
1519 BN_clear_free(tmp);
1520 BN_clear_free(tmp2);
1521
1522 return (struct crypto_bignum *) y_sqr;
1523}
1524
1525
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001526int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1527 const struct crypto_ec_point *p)
1528{
1529 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
1530}
1531
1532
1533int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1534 const struct crypto_ec_point *p)
1535{
Dmitry Shmidt41712582015-06-29 11:02:15 -07001536 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
1537 e->bnctx) == 1;
1538}
1539
1540
1541int crypto_ec_point_cmp(const struct crypto_ec *e,
1542 const struct crypto_ec_point *a,
1543 const struct crypto_ec_point *b)
1544{
1545 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
1546 (const EC_POINT *) b, e->bnctx);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001547}
1548
1549#endif /* CONFIG_ECC */