blob: 73b547db0bb28c761c411b776c1f864f273a8458 [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
Dmitry Shmidt04949592012-07-19 12:16:46 -0700775 if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800776 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700777 return NULL;
778 }
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800779#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700780
781 return ctx;
782}
783
784
785void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
786{
787 if (ctx == NULL)
788 return;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800789#if OPENSSL_VERSION_NUMBER >= 0x10100000L
790 HMAC_Update(ctx->ctx, data, len);
791#else
Dmitry Shmidt04949592012-07-19 12:16:46 -0700792 HMAC_Update(&ctx->ctx, data, len);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800793#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700794}
795
796
797int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
798{
799 unsigned int mdlen;
800 int res;
801
802 if (ctx == NULL)
803 return -2;
804
805 if (mac == NULL || len == NULL) {
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800806#if OPENSSL_VERSION_NUMBER >= 0x10100000L
807 HMAC_CTX_free(ctx->ctx);
808#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800809 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700810 return 0;
811 }
812
813 mdlen = *len;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800814#if OPENSSL_VERSION_NUMBER >= 0x10100000L
815 res = HMAC_Final(ctx->ctx, mac, &mdlen);
816 HMAC_CTX_free(ctx->ctx);
817#else
Dmitry Shmidt04949592012-07-19 12:16:46 -0700818 res = HMAC_Final(&ctx->ctx, mac, &mdlen);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700819 HMAC_CTX_cleanup(&ctx->ctx);
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800820#endif
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800821 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700822
823 if (res == 1) {
824 *len = mdlen;
825 return 0;
826 }
827
828 return -1;
829}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700830
831
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800832static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
833 size_t key_len, size_t num_elem,
834 const u8 *addr[], const size_t *len, u8 *mac,
835 unsigned int mdlen)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700836{
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800837#if OPENSSL_VERSION_NUMBER >= 0x10100000L
838 HMAC_CTX *ctx;
839 size_t i;
840 int res;
841
842 if (TEST_FAIL())
843 return -1;
844
845 ctx = HMAC_CTX_new();
846 if (!ctx)
847 return -1;
848 res = HMAC_Init_ex(ctx, key, key_len, type, NULL);
849 if (res != 1)
850 goto done;
851
852 for (i = 0; i < num_elem; i++)
853 HMAC_Update(ctx, addr[i], len[i]);
854
855 res = HMAC_Final(ctx, mac, &mdlen);
856done:
857 HMAC_CTX_free(ctx);
858
859 return res == 1 ? 0 : -1;
860#else
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700861 HMAC_CTX ctx;
862 size_t i;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700863 int res;
864
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800865 if (TEST_FAIL())
866 return -1;
867
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700868 HMAC_CTX_init(&ctx);
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800869 if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700870 return -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700871
872 for (i = 0; i < num_elem; i++)
873 HMAC_Update(&ctx, addr[i], len[i]);
874
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700875 res = HMAC_Final(&ctx, mac, &mdlen);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700876 HMAC_CTX_cleanup(&ctx);
877
878 return res == 1 ? 0 : -1;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800879#endif
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700880}
881
882
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800883#ifndef CONFIG_FIPS
884
885int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
886 const u8 *addr[], const size_t *len, u8 *mac)
887{
888 return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
889 mac, 16);
890}
891
892
893int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
894 u8 *mac)
895{
896 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
897}
898
899#endif /* CONFIG_FIPS */
900
901
902int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
903 int iterations, u8 *buf, size_t buflen)
904{
905 if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
906 ssid_len, iterations, buflen, buf) != 1)
907 return -1;
908 return 0;
909}
910
911
912int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
913 const u8 *addr[], const size_t *len, u8 *mac)
914{
915 return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
916 len, mac, 20);
917}
918
919
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700920int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
921 u8 *mac)
922{
923 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
924}
925
926
927#ifdef CONFIG_SHA256
928
929int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
930 const u8 *addr[], const size_t *len, u8 *mac)
931{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800932 return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
933 len, mac, 32);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700934}
935
936
937int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
938 size_t data_len, u8 *mac)
939{
940 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
941}
942
943#endif /* CONFIG_SHA256 */
944
945
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800946#ifdef CONFIG_SHA384
947
948int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
949 const u8 *addr[], const size_t *len, u8 *mac)
950{
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800951 return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
952 len, mac, 32);
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800953}
954
955
956int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
957 size_t data_len, u8 *mac)
958{
959 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
960}
961
962#endif /* CONFIG_SHA384 */
963
964
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700965int crypto_get_random(void *buf, size_t len)
966{
967 if (RAND_bytes(buf, len) != 1)
968 return -1;
969 return 0;
970}
971
972
973#ifdef CONFIG_OPENSSL_CMAC
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800974int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
975 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700976{
977 CMAC_CTX *ctx;
978 int ret = -1;
979 size_t outlen, i;
980
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800981 if (TEST_FAIL())
982 return -1;
983
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700984 ctx = CMAC_CTX_new();
985 if (ctx == NULL)
986 return -1;
987
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800988 if (key_len == 32) {
989 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
990 goto fail;
991 } else if (key_len == 16) {
992 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
993 goto fail;
994 } else {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700995 goto fail;
Dmitry Shmidt807291d2015-01-27 13:40:23 -0800996 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700997 for (i = 0; i < num_elem; i++) {
998 if (!CMAC_Update(ctx, addr[i], len[i]))
999 goto fail;
1000 }
1001 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
1002 goto fail;
1003
1004 ret = 0;
1005fail:
1006 CMAC_CTX_free(ctx);
1007 return ret;
1008}
1009
1010
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001011int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1012 const u8 *addr[], const size_t *len, u8 *mac)
1013{
1014 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1015}
1016
1017
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001018int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1019{
1020 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1021}
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001022
1023
1024int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1025{
1026 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1027}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001028#endif /* CONFIG_OPENSSL_CMAC */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001029
1030
1031struct crypto_bignum * crypto_bignum_init(void)
1032{
1033 return (struct crypto_bignum *) BN_new();
1034}
1035
1036
1037struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1038{
1039 BIGNUM *bn = BN_bin2bn(buf, len, NULL);
1040 return (struct crypto_bignum *) bn;
1041}
1042
1043
1044void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1045{
1046 if (clear)
1047 BN_clear_free((BIGNUM *) n);
1048 else
1049 BN_free((BIGNUM *) n);
1050}
1051
1052
1053int crypto_bignum_to_bin(const struct crypto_bignum *a,
1054 u8 *buf, size_t buflen, size_t padlen)
1055{
1056 int num_bytes, offset;
1057
1058 if (padlen > buflen)
1059 return -1;
1060
1061 num_bytes = BN_num_bytes((const BIGNUM *) a);
1062 if ((size_t) num_bytes > buflen)
1063 return -1;
1064 if (padlen > (size_t) num_bytes)
1065 offset = padlen - num_bytes;
1066 else
1067 offset = 0;
1068
1069 os_memset(buf, 0, offset);
1070 BN_bn2bin((const BIGNUM *) a, buf + offset);
1071
1072 return num_bytes + offset;
1073}
1074
1075
1076int crypto_bignum_add(const struct crypto_bignum *a,
1077 const struct crypto_bignum *b,
1078 struct crypto_bignum *c)
1079{
1080 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1081 0 : -1;
1082}
1083
1084
1085int crypto_bignum_mod(const struct crypto_bignum *a,
1086 const struct crypto_bignum *b,
1087 struct crypto_bignum *c)
1088{
1089 int res;
1090 BN_CTX *bnctx;
1091
1092 bnctx = BN_CTX_new();
1093 if (bnctx == NULL)
1094 return -1;
1095 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
1096 bnctx);
1097 BN_CTX_free(bnctx);
1098
1099 return res ? 0 : -1;
1100}
1101
1102
1103int crypto_bignum_exptmod(const struct crypto_bignum *a,
1104 const struct crypto_bignum *b,
1105 const struct crypto_bignum *c,
1106 struct crypto_bignum *d)
1107{
1108 int res;
1109 BN_CTX *bnctx;
1110
1111 bnctx = BN_CTX_new();
1112 if (bnctx == NULL)
1113 return -1;
1114 res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1115 (const BIGNUM *) c, bnctx);
1116 BN_CTX_free(bnctx);
1117
1118 return res ? 0 : -1;
1119}
1120
1121
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001122int crypto_bignum_inverse(const struct crypto_bignum *a,
1123 const struct crypto_bignum *b,
1124 struct crypto_bignum *c)
1125{
1126 BIGNUM *res;
1127 BN_CTX *bnctx;
1128
1129 bnctx = BN_CTX_new();
1130 if (bnctx == NULL)
1131 return -1;
1132 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
1133 (const BIGNUM *) b, bnctx);
1134 BN_CTX_free(bnctx);
1135
1136 return res ? 0 : -1;
1137}
1138
1139
1140int crypto_bignum_sub(const struct crypto_bignum *a,
1141 const struct crypto_bignum *b,
1142 struct crypto_bignum *c)
1143{
1144 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1145 0 : -1;
1146}
1147
1148
1149int crypto_bignum_div(const struct crypto_bignum *a,
1150 const struct crypto_bignum *b,
1151 struct crypto_bignum *c)
1152{
1153 int res;
1154
1155 BN_CTX *bnctx;
1156
1157 bnctx = BN_CTX_new();
1158 if (bnctx == NULL)
1159 return -1;
1160 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
1161 (const BIGNUM *) b, bnctx);
1162 BN_CTX_free(bnctx);
1163
1164 return res ? 0 : -1;
1165}
1166
1167
1168int crypto_bignum_mulmod(const struct crypto_bignum *a,
1169 const struct crypto_bignum *b,
1170 const struct crypto_bignum *c,
1171 struct crypto_bignum *d)
1172{
1173 int res;
1174
1175 BN_CTX *bnctx;
1176
1177 bnctx = BN_CTX_new();
1178 if (bnctx == NULL)
1179 return -1;
1180 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1181 (const BIGNUM *) c, bnctx);
1182 BN_CTX_free(bnctx);
1183
1184 return res ? 0 : -1;
1185}
1186
1187
1188int crypto_bignum_cmp(const struct crypto_bignum *a,
1189 const struct crypto_bignum *b)
1190{
1191 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
1192}
1193
1194
1195int crypto_bignum_bits(const struct crypto_bignum *a)
1196{
1197 return BN_num_bits((const BIGNUM *) a);
1198}
1199
1200
1201int crypto_bignum_is_zero(const struct crypto_bignum *a)
1202{
1203 return BN_is_zero((const BIGNUM *) a);
1204}
1205
1206
1207int crypto_bignum_is_one(const struct crypto_bignum *a)
1208{
1209 return BN_is_one((const BIGNUM *) a);
1210}
1211
1212
Dmitry Shmidt41712582015-06-29 11:02:15 -07001213int crypto_bignum_legendre(const struct crypto_bignum *a,
1214 const struct crypto_bignum *p)
1215{
1216 BN_CTX *bnctx;
1217 BIGNUM *exp = NULL, *tmp = NULL;
1218 int res = -2;
1219
1220 bnctx = BN_CTX_new();
1221 if (bnctx == NULL)
1222 return -2;
1223
1224 exp = BN_new();
1225 tmp = BN_new();
1226 if (!exp || !tmp ||
1227 /* exp = (p-1) / 2 */
1228 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
1229 !BN_rshift1(exp, exp) ||
1230 !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
1231 bnctx))
1232 goto fail;
1233
1234 if (BN_is_word(tmp, 1))
1235 res = 1;
1236 else if (BN_is_zero(tmp))
1237 res = 0;
1238 else
1239 res = -1;
1240
1241fail:
1242 BN_clear_free(tmp);
1243 BN_clear_free(exp);
1244 BN_CTX_free(bnctx);
1245 return res;
1246}
1247
1248
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001249#ifdef CONFIG_ECC
1250
1251struct crypto_ec {
1252 EC_GROUP *group;
1253 BN_CTX *bnctx;
1254 BIGNUM *prime;
1255 BIGNUM *order;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001256 BIGNUM *a;
1257 BIGNUM *b;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001258};
1259
1260struct crypto_ec * crypto_ec_init(int group)
1261{
1262 struct crypto_ec *e;
1263 int nid;
1264
1265 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1266 switch (group) {
1267 case 19:
1268 nid = NID_X9_62_prime256v1;
1269 break;
1270 case 20:
1271 nid = NID_secp384r1;
1272 break;
1273 case 21:
1274 nid = NID_secp521r1;
1275 break;
1276 case 25:
1277 nid = NID_X9_62_prime192v1;
1278 break;
1279 case 26:
1280 nid = NID_secp224r1;
1281 break;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001282#ifdef NID_brainpoolP224r1
1283 case 27:
1284 nid = NID_brainpoolP224r1;
1285 break;
1286#endif /* NID_brainpoolP224r1 */
1287#ifdef NID_brainpoolP256r1
1288 case 28:
1289 nid = NID_brainpoolP256r1;
1290 break;
1291#endif /* NID_brainpoolP256r1 */
1292#ifdef NID_brainpoolP384r1
1293 case 29:
1294 nid = NID_brainpoolP384r1;
1295 break;
1296#endif /* NID_brainpoolP384r1 */
1297#ifdef NID_brainpoolP512r1
1298 case 30:
1299 nid = NID_brainpoolP512r1;
1300 break;
1301#endif /* NID_brainpoolP512r1 */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001302 default:
1303 return NULL;
1304 }
1305
1306 e = os_zalloc(sizeof(*e));
1307 if (e == NULL)
1308 return NULL;
1309
1310 e->bnctx = BN_CTX_new();
1311 e->group = EC_GROUP_new_by_curve_name(nid);
1312 e->prime = BN_new();
1313 e->order = BN_new();
Dmitry Shmidt41712582015-06-29 11:02:15 -07001314 e->a = BN_new();
1315 e->b = BN_new();
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001316 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
Dmitry Shmidt41712582015-06-29 11:02:15 -07001317 e->order == NULL || e->a == NULL || e->b == NULL ||
1318 !EC_GROUP_get_curve_GFp(e->group, e->prime, e->a, e->b, e->bnctx) ||
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001319 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
1320 crypto_ec_deinit(e);
1321 e = NULL;
1322 }
1323
1324 return e;
1325}
1326
1327
1328void crypto_ec_deinit(struct crypto_ec *e)
1329{
1330 if (e == NULL)
1331 return;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001332 BN_clear_free(e->b);
1333 BN_clear_free(e->a);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001334 BN_clear_free(e->order);
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001335 BN_clear_free(e->prime);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001336 EC_GROUP_free(e->group);
1337 BN_CTX_free(e->bnctx);
1338 os_free(e);
1339}
1340
1341
1342struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1343{
1344 if (e == NULL)
1345 return NULL;
1346 return (struct crypto_ec_point *) EC_POINT_new(e->group);
1347}
1348
1349
1350size_t crypto_ec_prime_len(struct crypto_ec *e)
1351{
1352 return BN_num_bytes(e->prime);
1353}
1354
1355
1356size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1357{
1358 return BN_num_bits(e->prime);
1359}
1360
1361
1362const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1363{
1364 return (const struct crypto_bignum *) e->prime;
1365}
1366
1367
1368const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1369{
1370 return (const struct crypto_bignum *) e->order;
1371}
1372
1373
1374void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1375{
1376 if (clear)
1377 EC_POINT_clear_free((EC_POINT *) p);
1378 else
1379 EC_POINT_free((EC_POINT *) p);
1380}
1381
1382
1383int crypto_ec_point_to_bin(struct crypto_ec *e,
1384 const struct crypto_ec_point *point, u8 *x, u8 *y)
1385{
1386 BIGNUM *x_bn, *y_bn;
1387 int ret = -1;
1388 int len = BN_num_bytes(e->prime);
1389
1390 x_bn = BN_new();
1391 y_bn = BN_new();
1392
1393 if (x_bn && y_bn &&
1394 EC_POINT_get_affine_coordinates_GFp(e->group, (EC_POINT *) point,
1395 x_bn, y_bn, e->bnctx)) {
1396 if (x) {
1397 crypto_bignum_to_bin((struct crypto_bignum *) x_bn,
1398 x, len, len);
1399 }
1400 if (y) {
1401 crypto_bignum_to_bin((struct crypto_bignum *) y_bn,
1402 y, len, len);
1403 }
1404 ret = 0;
1405 }
1406
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001407 BN_clear_free(x_bn);
1408 BN_clear_free(y_bn);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001409 return ret;
1410}
1411
1412
1413struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1414 const u8 *val)
1415{
1416 BIGNUM *x, *y;
1417 EC_POINT *elem;
1418 int len = BN_num_bytes(e->prime);
1419
1420 x = BN_bin2bn(val, len, NULL);
1421 y = BN_bin2bn(val + len, len, NULL);
1422 elem = EC_POINT_new(e->group);
1423 if (x == NULL || y == NULL || elem == NULL) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001424 BN_clear_free(x);
1425 BN_clear_free(y);
1426 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001427 return NULL;
1428 }
1429
1430 if (!EC_POINT_set_affine_coordinates_GFp(e->group, elem, x, y,
1431 e->bnctx)) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001432 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001433 elem = NULL;
1434 }
1435
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001436 BN_clear_free(x);
1437 BN_clear_free(y);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001438
1439 return (struct crypto_ec_point *) elem;
1440}
1441
1442
1443int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1444 const struct crypto_ec_point *b,
1445 struct crypto_ec_point *c)
1446{
1447 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
1448 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
1449}
1450
1451
1452int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1453 const struct crypto_bignum *b,
1454 struct crypto_ec_point *res)
1455{
1456 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
1457 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
1458 ? 0 : -1;
1459}
1460
1461
1462int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1463{
1464 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
1465}
1466
1467
1468int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
1469 struct crypto_ec_point *p,
1470 const struct crypto_bignum *x, int y_bit)
1471{
1472 if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
1473 (const BIGNUM *) x, y_bit,
1474 e->bnctx) ||
1475 !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx))
1476 return -1;
1477 return 0;
1478}
1479
1480
Dmitry Shmidt41712582015-06-29 11:02:15 -07001481struct crypto_bignum *
1482crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1483 const struct crypto_bignum *x)
1484{
1485 BIGNUM *tmp, *tmp2, *y_sqr = NULL;
1486
1487 tmp = BN_new();
1488 tmp2 = BN_new();
1489
1490 /* y^2 = x^3 + ax + b */
1491 if (tmp && tmp2 &&
1492 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1493 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1494 BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
1495 BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
1496 BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
1497 y_sqr = tmp2;
1498 tmp2 = NULL;
1499 }
1500
1501 BN_clear_free(tmp);
1502 BN_clear_free(tmp2);
1503
1504 return (struct crypto_bignum *) y_sqr;
1505}
1506
1507
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001508int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1509 const struct crypto_ec_point *p)
1510{
1511 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
1512}
1513
1514
1515int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1516 const struct crypto_ec_point *p)
1517{
Dmitry Shmidt41712582015-06-29 11:02:15 -07001518 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
1519 e->bnctx) == 1;
1520}
1521
1522
1523int crypto_ec_point_cmp(const struct crypto_ec *e,
1524 const struct crypto_ec_point *a,
1525 const struct crypto_ec_point *b)
1526{
1527 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
1528 (const EC_POINT *) b, e->bnctx);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001529}
1530
1531#endif /* CONFIG_ECC */