blob: 02cb391bcc700411ad76b19c8bf50c421cc04e32 [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 Shmidt4ae50e62016-06-27 13:48:39 -070032#include "md5.h"
33#include "aes_wrap.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070034#include "crypto.h"
35
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -080036#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
37/* Compatibility wrappers for older versions. */
38
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -080039static HMAC_CTX * HMAC_CTX_new(void)
40{
41 HMAC_CTX *ctx;
42
43 ctx = os_zalloc(sizeof(*ctx));
44 if (ctx)
45 HMAC_CTX_init(ctx);
46 return ctx;
47}
48
49
50static void HMAC_CTX_free(HMAC_CTX *ctx)
51{
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070052 if (!ctx)
53 return;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -080054 HMAC_CTX_cleanup(ctx);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -080055 bin_clear_free(ctx, sizeof(*ctx));
56}
57
58
59static EVP_MD_CTX * EVP_MD_CTX_new(void)
60{
61 EVP_MD_CTX *ctx;
62
63 ctx = os_zalloc(sizeof(*ctx));
64 if (ctx)
65 EVP_MD_CTX_init(ctx);
66 return ctx;
67}
68
69
70static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
71{
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070072 if (!ctx)
73 return;
74 EVP_MD_CTX_cleanup(ctx);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -080075 bin_clear_free(ctx, sizeof(*ctx));
76}
77
78#endif /* OpenSSL version < 1.1.0 */
79
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070080static BIGNUM * get_group5_prime(void)
81{
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070082#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
83 return BN_get_rfc3526_prime_1536(NULL);
84#elif !defined(OPENSSL_IS_BORINGSSL)
85 return get_rfc3526_prime_1536(NULL);
86#else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070087 static const unsigned char RFC3526_PRIME_1536[] = {
88 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
89 0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
90 0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,0x02,0x0B,0xBE,0xA6,
91 0x3B,0x13,0x9B,0x22,0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
92 0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,0x30,0x2B,0x0A,0x6D,
93 0xF2,0x5F,0x14,0x37,0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
94 0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,0xF4,0x4C,0x42,0xE9,
95 0xA6,0x37,0xED,0x6B,0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
96 0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,0xAE,0x9F,0x24,0x11,
97 0x7C,0x4B,0x1F,0xE6,0x49,0x28,0x66,0x51,0xEC,0xE4,0x5B,0x3D,
98 0xC2,0x00,0x7C,0xB8,0xA1,0x63,0xBF,0x05,0x98,0xDA,0x48,0x36,
99 0x1C,0x55,0xD3,0x9A,0x69,0x16,0x3F,0xA8,0xFD,0x24,0xCF,0x5F,
100 0x83,0x65,0x5D,0x23,0xDC,0xA3,0xAD,0x96,0x1C,0x62,0xF3,0x56,
101 0x20,0x85,0x52,0xBB,0x9E,0xD5,0x29,0x07,0x70,0x96,0x96,0x6D,
102 0x67,0x0C,0x35,0x4E,0x4A,0xBC,0x98,0x04,0xF1,0x74,0x6C,0x08,
103 0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
104 };
105 return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), NULL);
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700106#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700107}
108
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700109#ifdef OPENSSL_NO_SHA256
110#define NO_SHA256_WRAPPER
111#endif
Paul Stewart092955c2017-02-06 09:13:09 -0800112#ifdef OPENSSL_NO_SHA512
113#define NO_SHA384_WRAPPER
114#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700115
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700116static int openssl_digest_vector(const EVP_MD *type, size_t num_elem,
117 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700118{
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800119 EVP_MD_CTX *ctx;
120 size_t i;
121 unsigned int mac_len;
122
123 if (TEST_FAIL())
124 return -1;
125
126 ctx = EVP_MD_CTX_new();
127 if (!ctx)
128 return -1;
129 if (!EVP_DigestInit_ex(ctx, type, NULL)) {
130 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestInit_ex failed: %s",
131 ERR_error_string(ERR_get_error(), NULL));
132 EVP_MD_CTX_free(ctx);
133 return -1;
134 }
135 for (i = 0; i < num_elem; i++) {
136 if (!EVP_DigestUpdate(ctx, addr[i], len[i])) {
137 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestUpdate "
138 "failed: %s",
139 ERR_error_string(ERR_get_error(), NULL));
140 EVP_MD_CTX_free(ctx);
141 return -1;
142 }
143 }
144 if (!EVP_DigestFinal(ctx, mac, &mac_len)) {
145 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DigestFinal failed: %s",
146 ERR_error_string(ERR_get_error(), NULL));
147 EVP_MD_CTX_free(ctx);
148 return -1;
149 }
150 EVP_MD_CTX_free(ctx);
151
152 return 0;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700153}
154
155
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800156#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700157int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
158{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700159 return openssl_digest_vector(EVP_md4(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700160}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800161#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700162
163
164void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
165{
166 u8 pkey[8], next, tmp;
167 int i;
168 DES_key_schedule ks;
169
170 /* Add parity bits to the key */
171 next = 0;
172 for (i = 0; i < 7; i++) {
173 tmp = key[i];
174 pkey[i] = (tmp >> i) | next | 1;
175 next = tmp << (7 - i);
176 }
177 pkey[i] = next | 1;
178
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700179 DES_set_key((DES_cblock *) &pkey, &ks);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700180 DES_ecb_encrypt((DES_cblock *) clear, (DES_cblock *) cypher, &ks,
181 DES_ENCRYPT);
182}
183
184
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800185#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700186int rc4_skip(const u8 *key, size_t keylen, size_t skip,
187 u8 *data, size_t data_len)
188{
189#ifdef OPENSSL_NO_RC4
190 return -1;
191#else /* OPENSSL_NO_RC4 */
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800192 EVP_CIPHER_CTX *ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700193 int outl;
194 int res = -1;
195 unsigned char skip_buf[16];
196
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800197 ctx = EVP_CIPHER_CTX_new();
198 if (!ctx ||
199 !EVP_CIPHER_CTX_set_padding(ctx, 0) ||
200 !EVP_CipherInit_ex(ctx, EVP_rc4(), NULL, NULL, NULL, 1) ||
201 !EVP_CIPHER_CTX_set_key_length(ctx, keylen) ||
202 !EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, 1))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700203 goto out;
204
205 while (skip >= sizeof(skip_buf)) {
206 size_t len = skip;
207 if (len > sizeof(skip_buf))
208 len = sizeof(skip_buf);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800209 if (!EVP_CipherUpdate(ctx, skip_buf, &outl, skip_buf, len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700210 goto out;
211 skip -= len;
212 }
213
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800214 if (EVP_CipherUpdate(ctx, data, &outl, data, data_len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700215 res = 0;
216
217out:
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800218 if (ctx)
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800219 EVP_CIPHER_CTX_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700220 return res;
221#endif /* OPENSSL_NO_RC4 */
222}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800223#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700224
225
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800226#ifndef CONFIG_FIPS
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700227int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
228{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700229 return openssl_digest_vector(EVP_md5(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700230}
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800231#endif /* CONFIG_FIPS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700232
233
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700234int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
235{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700236 return openssl_digest_vector(EVP_sha1(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700237}
238
239
240#ifndef NO_SHA256_WRAPPER
241int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
242 u8 *mac)
243{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700244 return openssl_digest_vector(EVP_sha256(), num_elem, addr, len, mac);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700245}
246#endif /* NO_SHA256_WRAPPER */
247
Paul Stewart092955c2017-02-06 09:13:09 -0800248#ifndef NO_SHA384_WRAPPER
249int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
250 u8 *mac)
251{
252 return openssl_digest_vector(EVP_sha384(), num_elem, addr, len, mac);
253}
254#endif /* NO_SHA384_WRAPPER */
255
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700256
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700257static const EVP_CIPHER * aes_get_evp_cipher(size_t keylen)
258{
259 switch (keylen) {
260 case 16:
261 return EVP_aes_128_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700262#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700263 case 24:
264 return EVP_aes_192_ecb();
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700265#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700266 case 32:
267 return EVP_aes_256_ecb();
268 }
269
270 return NULL;
271}
272
273
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700274void * aes_encrypt_init(const u8 *key, size_t len)
275{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700276 EVP_CIPHER_CTX *ctx;
277 const EVP_CIPHER *type;
278
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800279 if (TEST_FAIL())
280 return NULL;
281
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700282 type = aes_get_evp_cipher(len);
283 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700284 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700285
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800286 ctx = EVP_CIPHER_CTX_new();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700287 if (ctx == NULL)
288 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700289 if (EVP_EncryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
290 os_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700291 return NULL;
292 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700293 EVP_CIPHER_CTX_set_padding(ctx, 0);
294 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700295}
296
297
298void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
299{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700300 EVP_CIPHER_CTX *c = ctx;
301 int clen = 16;
302 if (EVP_EncryptUpdate(c, crypt, &clen, plain, 16) != 1) {
303 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptUpdate failed: %s",
304 ERR_error_string(ERR_get_error(), NULL));
305 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700306}
307
308
309void aes_encrypt_deinit(void *ctx)
310{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700311 EVP_CIPHER_CTX *c = ctx;
312 u8 buf[16];
313 int len = sizeof(buf);
314 if (EVP_EncryptFinal_ex(c, buf, &len) != 1) {
315 wpa_printf(MSG_ERROR, "OpenSSL: EVP_EncryptFinal_ex failed: "
316 "%s", ERR_error_string(ERR_get_error(), NULL));
317 }
318 if (len != 0) {
319 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
320 "in AES encrypt", len);
321 }
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800322 EVP_CIPHER_CTX_free(c);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700323}
324
325
326void * aes_decrypt_init(const u8 *key, size_t len)
327{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700328 EVP_CIPHER_CTX *ctx;
329 const EVP_CIPHER *type;
330
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800331 if (TEST_FAIL())
332 return NULL;
333
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700334 type = aes_get_evp_cipher(len);
335 if (type == NULL)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700336 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700337
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800338 ctx = EVP_CIPHER_CTX_new();
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700339 if (ctx == NULL)
340 return NULL;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700341 if (EVP_DecryptInit_ex(ctx, type, NULL, key, NULL) != 1) {
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800342 EVP_CIPHER_CTX_free(ctx);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700343 return NULL;
344 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700345 EVP_CIPHER_CTX_set_padding(ctx, 0);
346 return ctx;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700347}
348
349
350void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
351{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700352 EVP_CIPHER_CTX *c = ctx;
353 int plen = 16;
354 if (EVP_DecryptUpdate(c, plain, &plen, crypt, 16) != 1) {
355 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptUpdate failed: %s",
356 ERR_error_string(ERR_get_error(), NULL));
357 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700358}
359
360
361void aes_decrypt_deinit(void *ctx)
362{
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700363 EVP_CIPHER_CTX *c = ctx;
364 u8 buf[16];
365 int len = sizeof(buf);
366 if (EVP_DecryptFinal_ex(c, buf, &len) != 1) {
367 wpa_printf(MSG_ERROR, "OpenSSL: EVP_DecryptFinal_ex failed: "
368 "%s", ERR_error_string(ERR_get_error(), NULL));
369 }
370 if (len != 0) {
371 wpa_printf(MSG_ERROR, "OpenSSL: Unexpected padding length %d "
372 "in AES decrypt", len);
373 }
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800374 EVP_CIPHER_CTX_free(c);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700375}
376
377
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800378#ifndef CONFIG_FIPS
379#ifndef CONFIG_OPENSSL_INTERNAL_AES_WRAP
380
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800381int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
382{
383 AES_KEY actx;
384 int res;
385
386 if (AES_set_encrypt_key(kek, kek_len << 3, &actx))
387 return -1;
388 res = AES_wrap_key(&actx, NULL, cipher, plain, n * 8);
389 OPENSSL_cleanse(&actx, sizeof(actx));
390 return res <= 0 ? -1 : 0;
391}
392
393
394int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
395 u8 *plain)
396{
397 AES_KEY actx;
398 int res;
399
400 if (AES_set_decrypt_key(kek, kek_len << 3, &actx))
401 return -1;
402 res = AES_unwrap_key(&actx, NULL, plain, cipher, (n + 1) * 8);
403 OPENSSL_cleanse(&actx, sizeof(actx));
404 return res <= 0 ? -1 : 0;
405}
406
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800407#endif /* CONFIG_OPENSSL_INTERNAL_AES_WRAP */
408#endif /* CONFIG_FIPS */
409
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800410
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700411int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
412{
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800413 EVP_CIPHER_CTX *ctx;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700414 int clen, len;
415 u8 buf[16];
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800416 int res = -1;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700417
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800418 if (TEST_FAIL())
419 return -1;
420
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800421 ctx = EVP_CIPHER_CTX_new();
422 if (!ctx)
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700423 return -1;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700424 clen = data_len;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700425 len = sizeof(buf);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800426 if (EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
427 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
428 EVP_EncryptUpdate(ctx, data, &clen, data, data_len) == 1 &&
429 clen == (int) data_len &&
430 EVP_EncryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
431 res = 0;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800432 EVP_CIPHER_CTX_free(ctx);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700433
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800434 return res;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700435}
436
437
438int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
439{
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800440 EVP_CIPHER_CTX *ctx;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700441 int plen, len;
442 u8 buf[16];
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800443 int res = -1;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700444
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800445 if (TEST_FAIL())
446 return -1;
447
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800448 ctx = EVP_CIPHER_CTX_new();
449 if (!ctx)
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700450 return -1;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700451 plen = data_len;
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700452 len = sizeof(buf);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800453 if (EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv) == 1 &&
454 EVP_CIPHER_CTX_set_padding(ctx, 0) == 1 &&
455 EVP_DecryptUpdate(ctx, data, &plen, data, data_len) == 1 &&
456 plen == (int) data_len &&
457 EVP_DecryptFinal_ex(ctx, buf, &len) == 1 && len == 0)
458 res = 0;
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800459 EVP_CIPHER_CTX_free(ctx);
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700460
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800461 return res;
462
Dmitry Shmidt912c6ec2015-03-30 13:16:51 -0700463}
464
465
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700466int crypto_mod_exp(const u8 *base, size_t base_len,
467 const u8 *power, size_t power_len,
468 const u8 *modulus, size_t modulus_len,
469 u8 *result, size_t *result_len)
470{
471 BIGNUM *bn_base, *bn_exp, *bn_modulus, *bn_result;
472 int ret = -1;
473 BN_CTX *ctx;
474
475 ctx = BN_CTX_new();
476 if (ctx == NULL)
477 return -1;
478
479 bn_base = BN_bin2bn(base, base_len, NULL);
480 bn_exp = BN_bin2bn(power, power_len, NULL);
481 bn_modulus = BN_bin2bn(modulus, modulus_len, NULL);
482 bn_result = BN_new();
483
484 if (bn_base == NULL || bn_exp == NULL || bn_modulus == NULL ||
485 bn_result == NULL)
486 goto error;
487
488 if (BN_mod_exp(bn_result, bn_base, bn_exp, bn_modulus, ctx) != 1)
489 goto error;
490
491 *result_len = BN_bn2bin(bn_result, result);
492 ret = 0;
493
494error:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700495 BN_clear_free(bn_base);
496 BN_clear_free(bn_exp);
497 BN_clear_free(bn_modulus);
498 BN_clear_free(bn_result);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700499 BN_CTX_free(ctx);
500 return ret;
501}
502
503
504struct crypto_cipher {
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800505 EVP_CIPHER_CTX *enc;
506 EVP_CIPHER_CTX *dec;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700507};
508
509
510struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
511 const u8 *iv, const u8 *key,
512 size_t key_len)
513{
514 struct crypto_cipher *ctx;
515 const EVP_CIPHER *cipher;
516
517 ctx = os_zalloc(sizeof(*ctx));
518 if (ctx == NULL)
519 return NULL;
520
521 switch (alg) {
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800522#ifndef CONFIG_NO_RC4
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700523#ifndef OPENSSL_NO_RC4
524 case CRYPTO_CIPHER_ALG_RC4:
525 cipher = EVP_rc4();
526 break;
527#endif /* OPENSSL_NO_RC4 */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800528#endif /* CONFIG_NO_RC4 */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700529#ifndef OPENSSL_NO_AES
530 case CRYPTO_CIPHER_ALG_AES:
531 switch (key_len) {
532 case 16:
533 cipher = EVP_aes_128_cbc();
534 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700535#ifndef OPENSSL_IS_BORINGSSL
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700536 case 24:
537 cipher = EVP_aes_192_cbc();
538 break;
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700539#endif /* OPENSSL_IS_BORINGSSL */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700540 case 32:
541 cipher = EVP_aes_256_cbc();
542 break;
543 default:
544 os_free(ctx);
545 return NULL;
546 }
547 break;
548#endif /* OPENSSL_NO_AES */
549#ifndef OPENSSL_NO_DES
550 case CRYPTO_CIPHER_ALG_3DES:
551 cipher = EVP_des_ede3_cbc();
552 break;
553 case CRYPTO_CIPHER_ALG_DES:
554 cipher = EVP_des_cbc();
555 break;
556#endif /* OPENSSL_NO_DES */
557#ifndef OPENSSL_NO_RC2
558 case CRYPTO_CIPHER_ALG_RC2:
559 cipher = EVP_rc2_ecb();
560 break;
561#endif /* OPENSSL_NO_RC2 */
562 default:
563 os_free(ctx);
564 return NULL;
565 }
566
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800567 if (!(ctx->enc = EVP_CIPHER_CTX_new()) ||
568 !EVP_CIPHER_CTX_set_padding(ctx->enc, 0) ||
569 !EVP_EncryptInit_ex(ctx->enc, cipher, NULL, NULL, NULL) ||
570 !EVP_CIPHER_CTX_set_key_length(ctx->enc, key_len) ||
571 !EVP_EncryptInit_ex(ctx->enc, NULL, NULL, key, iv)) {
572 if (ctx->enc)
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800573 EVP_CIPHER_CTX_free(ctx->enc);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700574 os_free(ctx);
575 return NULL;
576 }
577
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800578 if (!(ctx->dec = EVP_CIPHER_CTX_new()) ||
579 !EVP_CIPHER_CTX_set_padding(ctx->dec, 0) ||
580 !EVP_DecryptInit_ex(ctx->dec, cipher, NULL, NULL, NULL) ||
581 !EVP_CIPHER_CTX_set_key_length(ctx->dec, key_len) ||
582 !EVP_DecryptInit_ex(ctx->dec, NULL, NULL, key, iv)) {
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800583 EVP_CIPHER_CTX_free(ctx->enc);
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800584 if (ctx->dec)
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800585 EVP_CIPHER_CTX_free(ctx->dec);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700586 os_free(ctx);
587 return NULL;
588 }
589
590 return ctx;
591}
592
593
594int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
595 u8 *crypt, size_t len)
596{
597 int outl;
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800598 if (!EVP_EncryptUpdate(ctx->enc, crypt, &outl, plain, len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700599 return -1;
600 return 0;
601}
602
603
604int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
605 u8 *plain, size_t len)
606{
607 int outl;
608 outl = len;
Dmitry Shmidt1d6bf422016-01-19 15:51:35 -0800609 if (!EVP_DecryptUpdate(ctx->dec, plain, &outl, crypt, len))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700610 return -1;
611 return 0;
612}
613
614
615void crypto_cipher_deinit(struct crypto_cipher *ctx)
616{
Dmitry Shmidt57c2d392016-02-23 13:40:19 -0800617 EVP_CIPHER_CTX_free(ctx->enc);
618 EVP_CIPHER_CTX_free(ctx->dec);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700619 os_free(ctx);
620}
621
622
623void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
624{
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800625#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700626 DH *dh;
627 struct wpabuf *pubkey = NULL, *privkey = NULL;
628 size_t publen, privlen;
629
630 *priv = NULL;
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700631 wpabuf_free(*publ);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700632 *publ = NULL;
633
634 dh = DH_new();
635 if (dh == NULL)
636 return NULL;
637
638 dh->g = BN_new();
639 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
640 goto err;
641
642 dh->p = get_group5_prime();
643 if (dh->p == NULL)
644 goto err;
645
646 if (DH_generate_key(dh) != 1)
647 goto err;
648
649 publen = BN_num_bytes(dh->pub_key);
650 pubkey = wpabuf_alloc(publen);
651 if (pubkey == NULL)
652 goto err;
653 privlen = BN_num_bytes(dh->priv_key);
654 privkey = wpabuf_alloc(privlen);
655 if (privkey == NULL)
656 goto err;
657
658 BN_bn2bin(dh->pub_key, wpabuf_put(pubkey, publen));
659 BN_bn2bin(dh->priv_key, wpabuf_put(privkey, privlen));
660
661 *priv = privkey;
662 *publ = pubkey;
663 return dh;
664
665err:
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800666 wpabuf_clear_free(pubkey);
667 wpabuf_clear_free(privkey);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700668 DH_free(dh);
669 return NULL;
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700670#else
671 DH *dh;
672 struct wpabuf *pubkey = NULL, *privkey = NULL;
673 size_t publen, privlen;
Dmitry Shmidt4ae50e62016-06-27 13:48:39 -0700674 BIGNUM *p = NULL, *g;
675 const BIGNUM *priv_key = NULL, *pub_key = NULL;
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700676
677 *priv = NULL;
678 wpabuf_free(*publ);
679 *publ = NULL;
680
681 dh = DH_new();
682 if (dh == NULL)
683 return NULL;
684
685 g = BN_new();
686 p = get_group5_prime();
687 if (!g || BN_set_word(g, 2) != 1 || !p ||
688 DH_set0_pqg(dh, p, NULL, g) != 1)
689 goto err;
690 p = NULL;
691 g = NULL;
692
693 if (DH_generate_key(dh) != 1)
694 goto err;
695
696 DH_get0_key(dh, &pub_key, &priv_key);
697 publen = BN_num_bytes(pub_key);
698 pubkey = wpabuf_alloc(publen);
699 if (!pubkey)
700 goto err;
701 privlen = BN_num_bytes(priv_key);
702 privkey = wpabuf_alloc(privlen);
703 if (!privkey)
704 goto err;
705
706 BN_bn2bin(pub_key, wpabuf_put(pubkey, publen));
707 BN_bn2bin(priv_key, wpabuf_put(privkey, privlen));
708
709 *priv = privkey;
710 *publ = pubkey;
711 return dh;
712
713err:
714 BN_free(p);
715 BN_free(g);
716 wpabuf_clear_free(pubkey);
717 wpabuf_clear_free(privkey);
718 DH_free(dh);
719 return NULL;
720#endif
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700721}
722
723
Dmitry Shmidt04949592012-07-19 12:16:46 -0700724void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
725{
Dmitry Shmidt9839ecd2016-11-07 11:05:47 -0800726#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
Dmitry Shmidt04949592012-07-19 12:16:46 -0700727 DH *dh;
728
729 dh = DH_new();
730 if (dh == NULL)
731 return NULL;
732
733 dh->g = BN_new();
734 if (dh->g == NULL || BN_set_word(dh->g, 2) != 1)
735 goto err;
736
737 dh->p = get_group5_prime();
738 if (dh->p == NULL)
739 goto err;
740
741 dh->priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
742 if (dh->priv_key == NULL)
743 goto err;
744
745 dh->pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
746 if (dh->pub_key == NULL)
747 goto err;
748
749 if (DH_generate_key(dh) != 1)
750 goto err;
751
752 return dh;
753
754err:
755 DH_free(dh);
756 return NULL;
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700757#else
758 DH *dh;
759 BIGNUM *p = NULL, *g, *priv_key = NULL, *pub_key = NULL;
760
761 dh = DH_new();
762 if (dh == NULL)
763 return NULL;
764
765 g = BN_new();
766 p = get_group5_prime();
767 if (!g || BN_set_word(g, 2) != 1 || !p ||
768 DH_set0_pqg(dh, p, NULL, g) != 1)
769 goto err;
770 p = NULL;
771 g = NULL;
772
773 priv_key = BN_bin2bn(wpabuf_head(priv), wpabuf_len(priv), NULL);
774 pub_key = BN_bin2bn(wpabuf_head(publ), wpabuf_len(publ), NULL);
Dmitry Shmidt58d12ad2016-07-28 10:07:03 -0700775 if (!priv_key || !pub_key || DH_set0_key(dh, pub_key, priv_key) != 1)
Dmitry Shmidt849734c2016-05-27 09:59:01 -0700776 goto err;
777 pub_key = NULL;
778 priv_key = NULL;
779
780 if (DH_generate_key(dh) != 1)
781 goto err;
782
783 return dh;
784
785err:
786 BN_free(p);
787 BN_free(g);
788 BN_free(pub_key);
789 BN_clear_free(priv_key);
790 DH_free(dh);
791 return NULL;
792#endif
Dmitry Shmidt04949592012-07-19 12:16:46 -0700793}
794
795
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700796struct wpabuf * dh5_derive_shared(void *ctx, const struct wpabuf *peer_public,
797 const struct wpabuf *own_private)
798{
799 BIGNUM *pub_key;
800 struct wpabuf *res = NULL;
801 size_t rlen;
802 DH *dh = ctx;
803 int keylen;
804
805 if (ctx == NULL)
806 return NULL;
807
808 pub_key = BN_bin2bn(wpabuf_head(peer_public), wpabuf_len(peer_public),
809 NULL);
810 if (pub_key == NULL)
811 return NULL;
812
813 rlen = DH_size(dh);
814 res = wpabuf_alloc(rlen);
815 if (res == NULL)
816 goto err;
817
818 keylen = DH_compute_key(wpabuf_mhead(res), pub_key, dh);
819 if (keylen < 0)
820 goto err;
821 wpabuf_put(res, keylen);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700822 BN_clear_free(pub_key);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823
824 return res;
825
826err:
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -0700827 BN_clear_free(pub_key);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800828 wpabuf_clear_free(res);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700829 return NULL;
830}
831
832
833void dh5_free(void *ctx)
834{
835 DH *dh;
836 if (ctx == NULL)
837 return;
838 dh = ctx;
839 DH_free(dh);
840}
Dmitry Shmidt04949592012-07-19 12:16:46 -0700841
842
843struct crypto_hash {
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800844 HMAC_CTX *ctx;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700845};
846
847
848struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
849 size_t key_len)
850{
851 struct crypto_hash *ctx;
852 const EVP_MD *md;
853
854 switch (alg) {
855#ifndef OPENSSL_NO_MD5
856 case CRYPTO_HASH_ALG_HMAC_MD5:
857 md = EVP_md5();
858 break;
859#endif /* OPENSSL_NO_MD5 */
860#ifndef OPENSSL_NO_SHA
861 case CRYPTO_HASH_ALG_HMAC_SHA1:
862 md = EVP_sha1();
863 break;
864#endif /* OPENSSL_NO_SHA */
865#ifndef OPENSSL_NO_SHA256
866#ifdef CONFIG_SHA256
867 case CRYPTO_HASH_ALG_HMAC_SHA256:
868 md = EVP_sha256();
869 break;
870#endif /* CONFIG_SHA256 */
871#endif /* OPENSSL_NO_SHA256 */
872 default:
873 return NULL;
874 }
875
876 ctx = os_zalloc(sizeof(*ctx));
877 if (ctx == NULL)
878 return NULL;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800879 ctx->ctx = HMAC_CTX_new();
880 if (!ctx->ctx) {
881 os_free(ctx);
882 return NULL;
883 }
884
885 if (HMAC_Init_ex(ctx->ctx, key, key_len, md, NULL) != 1) {
886 HMAC_CTX_free(ctx->ctx);
887 bin_clear_free(ctx, sizeof(*ctx));
888 return NULL;
889 }
Dmitry Shmidt04949592012-07-19 12:16:46 -0700890
891 return ctx;
892}
893
894
895void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
896{
897 if (ctx == NULL)
898 return;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800899 HMAC_Update(ctx->ctx, data, len);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700900}
901
902
903int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
904{
905 unsigned int mdlen;
906 int res;
907
908 if (ctx == NULL)
909 return -2;
910
911 if (mac == NULL || len == NULL) {
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800912 HMAC_CTX_free(ctx->ctx);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800913 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700914 return 0;
915 }
916
917 mdlen = *len;
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800918 res = HMAC_Final(ctx->ctx, mac, &mdlen);
919 HMAC_CTX_free(ctx->ctx);
Dmitry Shmidtff787d52015-01-12 13:01:47 -0800920 bin_clear_free(ctx, sizeof(*ctx));
Dmitry Shmidt04949592012-07-19 12:16:46 -0700921
922 if (res == 1) {
923 *len = mdlen;
924 return 0;
925 }
926
927 return -1;
928}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700929
930
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800931static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
932 size_t key_len, size_t num_elem,
933 const u8 *addr[], const size_t *len, u8 *mac,
934 unsigned int mdlen)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700935{
Dmitry Shmidt55840ad2015-12-14 12:45:46 -0800936 HMAC_CTX *ctx;
937 size_t i;
938 int res;
939
940 if (TEST_FAIL())
941 return -1;
942
943 ctx = HMAC_CTX_new();
944 if (!ctx)
945 return -1;
946 res = HMAC_Init_ex(ctx, key, key_len, type, NULL);
947 if (res != 1)
948 goto done;
949
950 for (i = 0; i < num_elem; i++)
951 HMAC_Update(ctx, addr[i], len[i]);
952
953 res = HMAC_Final(ctx, mac, &mdlen);
954done:
955 HMAC_CTX_free(ctx);
956
957 return res == 1 ? 0 : -1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700958}
959
960
Dmitry Shmidt216983b2015-02-06 10:50:36 -0800961#ifndef CONFIG_FIPS
962
963int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
964 const u8 *addr[], const size_t *len, u8 *mac)
965{
966 return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
967 mac, 16);
968}
969
970
971int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
972 u8 *mac)
973{
974 return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
975}
976
977#endif /* CONFIG_FIPS */
978
979
980int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
981 int iterations, u8 *buf, size_t buflen)
982{
983 if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
984 ssid_len, iterations, buflen, buf) != 1)
985 return -1;
986 return 0;
987}
988
989
990int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
991 const u8 *addr[], const size_t *len, u8 *mac)
992{
993 return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
994 len, mac, 20);
995}
996
997
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700998int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
999 u8 *mac)
1000{
1001 return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
1002}
1003
1004
1005#ifdef CONFIG_SHA256
1006
1007int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
1008 const u8 *addr[], const size_t *len, u8 *mac)
1009{
Dmitry Shmidt216983b2015-02-06 10:50:36 -08001010 return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
1011 len, mac, 32);
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001012}
1013
1014
1015int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
1016 size_t data_len, u8 *mac)
1017{
1018 return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
1019}
1020
1021#endif /* CONFIG_SHA256 */
1022
1023
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001024#ifdef CONFIG_SHA384
1025
1026int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
1027 const u8 *addr[], const size_t *len, u8 *mac)
1028{
Dmitry Shmidt216983b2015-02-06 10:50:36 -08001029 return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
1030 len, mac, 32);
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001031}
1032
1033
1034int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
1035 size_t data_len, u8 *mac)
1036{
1037 return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
1038}
1039
1040#endif /* CONFIG_SHA384 */
1041
1042
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001043int crypto_get_random(void *buf, size_t len)
1044{
1045 if (RAND_bytes(buf, len) != 1)
1046 return -1;
1047 return 0;
1048}
1049
1050
1051#ifdef CONFIG_OPENSSL_CMAC
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001052int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
1053 const u8 *addr[], const size_t *len, u8 *mac)
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001054{
1055 CMAC_CTX *ctx;
1056 int ret = -1;
1057 size_t outlen, i;
1058
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001059 if (TEST_FAIL())
1060 return -1;
1061
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001062 ctx = CMAC_CTX_new();
1063 if (ctx == NULL)
1064 return -1;
1065
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001066 if (key_len == 32) {
1067 if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
1068 goto fail;
1069 } else if (key_len == 16) {
1070 if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
1071 goto fail;
1072 } else {
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001073 goto fail;
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001074 }
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001075 for (i = 0; i < num_elem; i++) {
1076 if (!CMAC_Update(ctx, addr[i], len[i]))
1077 goto fail;
1078 }
1079 if (!CMAC_Final(ctx, mac, &outlen) || outlen != 16)
1080 goto fail;
1081
1082 ret = 0;
1083fail:
1084 CMAC_CTX_free(ctx);
1085 return ret;
1086}
1087
1088
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001089int omac1_aes_128_vector(const u8 *key, size_t num_elem,
1090 const u8 *addr[], const size_t *len, u8 *mac)
1091{
1092 return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
1093}
1094
1095
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001096int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1097{
1098 return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
1099}
Dmitry Shmidt807291d2015-01-27 13:40:23 -08001100
1101
1102int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
1103{
1104 return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
1105}
Dmitry Shmidt61d9df32012-08-29 16:22:06 -07001106#endif /* CONFIG_OPENSSL_CMAC */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001107
1108
1109struct crypto_bignum * crypto_bignum_init(void)
1110{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001111 if (TEST_FAIL())
1112 return NULL;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001113 return (struct crypto_bignum *) BN_new();
1114}
1115
1116
1117struct crypto_bignum * crypto_bignum_init_set(const u8 *buf, size_t len)
1118{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001119 BIGNUM *bn;
1120
1121 if (TEST_FAIL())
1122 return NULL;
1123
1124 bn = BN_bin2bn(buf, len, NULL);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001125 return (struct crypto_bignum *) bn;
1126}
1127
1128
1129void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
1130{
1131 if (clear)
1132 BN_clear_free((BIGNUM *) n);
1133 else
1134 BN_free((BIGNUM *) n);
1135}
1136
1137
1138int crypto_bignum_to_bin(const struct crypto_bignum *a,
1139 u8 *buf, size_t buflen, size_t padlen)
1140{
1141 int num_bytes, offset;
1142
Dmitry Shmidte4663042016-04-04 10:07:49 -07001143 if (TEST_FAIL())
1144 return -1;
1145
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001146 if (padlen > buflen)
1147 return -1;
1148
1149 num_bytes = BN_num_bytes((const BIGNUM *) a);
1150 if ((size_t) num_bytes > buflen)
1151 return -1;
1152 if (padlen > (size_t) num_bytes)
1153 offset = padlen - num_bytes;
1154 else
1155 offset = 0;
1156
1157 os_memset(buf, 0, offset);
1158 BN_bn2bin((const BIGNUM *) a, buf + offset);
1159
1160 return num_bytes + offset;
1161}
1162
1163
1164int crypto_bignum_add(const struct crypto_bignum *a,
1165 const struct crypto_bignum *b,
1166 struct crypto_bignum *c)
1167{
1168 return BN_add((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1169 0 : -1;
1170}
1171
1172
1173int crypto_bignum_mod(const struct crypto_bignum *a,
1174 const struct crypto_bignum *b,
1175 struct crypto_bignum *c)
1176{
1177 int res;
1178 BN_CTX *bnctx;
1179
1180 bnctx = BN_CTX_new();
1181 if (bnctx == NULL)
1182 return -1;
1183 res = BN_mod((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b,
1184 bnctx);
1185 BN_CTX_free(bnctx);
1186
1187 return res ? 0 : -1;
1188}
1189
1190
1191int crypto_bignum_exptmod(const struct crypto_bignum *a,
1192 const struct crypto_bignum *b,
1193 const struct crypto_bignum *c,
1194 struct crypto_bignum *d)
1195{
1196 int res;
1197 BN_CTX *bnctx;
1198
Dmitry Shmidte4663042016-04-04 10:07:49 -07001199 if (TEST_FAIL())
1200 return -1;
1201
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001202 bnctx = BN_CTX_new();
1203 if (bnctx == NULL)
1204 return -1;
1205 res = BN_mod_exp((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1206 (const BIGNUM *) c, bnctx);
1207 BN_CTX_free(bnctx);
1208
1209 return res ? 0 : -1;
1210}
1211
1212
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001213int crypto_bignum_inverse(const struct crypto_bignum *a,
1214 const struct crypto_bignum *b,
1215 struct crypto_bignum *c)
1216{
1217 BIGNUM *res;
1218 BN_CTX *bnctx;
1219
Dmitry Shmidte4663042016-04-04 10:07:49 -07001220 if (TEST_FAIL())
1221 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001222 bnctx = BN_CTX_new();
1223 if (bnctx == NULL)
1224 return -1;
1225 res = BN_mod_inverse((BIGNUM *) c, (const BIGNUM *) a,
1226 (const BIGNUM *) b, bnctx);
1227 BN_CTX_free(bnctx);
1228
1229 return res ? 0 : -1;
1230}
1231
1232
1233int crypto_bignum_sub(const struct crypto_bignum *a,
1234 const struct crypto_bignum *b,
1235 struct crypto_bignum *c)
1236{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001237 if (TEST_FAIL())
1238 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001239 return BN_sub((BIGNUM *) c, (const BIGNUM *) a, (const BIGNUM *) b) ?
1240 0 : -1;
1241}
1242
1243
1244int crypto_bignum_div(const struct crypto_bignum *a,
1245 const struct crypto_bignum *b,
1246 struct crypto_bignum *c)
1247{
1248 int res;
1249
1250 BN_CTX *bnctx;
1251
Dmitry Shmidte4663042016-04-04 10:07:49 -07001252 if (TEST_FAIL())
1253 return -1;
1254
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001255 bnctx = BN_CTX_new();
1256 if (bnctx == NULL)
1257 return -1;
1258 res = BN_div((BIGNUM *) c, NULL, (const BIGNUM *) a,
1259 (const BIGNUM *) b, bnctx);
1260 BN_CTX_free(bnctx);
1261
1262 return res ? 0 : -1;
1263}
1264
1265
1266int crypto_bignum_mulmod(const struct crypto_bignum *a,
1267 const struct crypto_bignum *b,
1268 const struct crypto_bignum *c,
1269 struct crypto_bignum *d)
1270{
1271 int res;
1272
1273 BN_CTX *bnctx;
1274
Dmitry Shmidte4663042016-04-04 10:07:49 -07001275 if (TEST_FAIL())
1276 return -1;
1277
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001278 bnctx = BN_CTX_new();
1279 if (bnctx == NULL)
1280 return -1;
1281 res = BN_mod_mul((BIGNUM *) d, (const BIGNUM *) a, (const BIGNUM *) b,
1282 (const BIGNUM *) c, bnctx);
1283 BN_CTX_free(bnctx);
1284
1285 return res ? 0 : -1;
1286}
1287
1288
1289int crypto_bignum_cmp(const struct crypto_bignum *a,
1290 const struct crypto_bignum *b)
1291{
1292 return BN_cmp((const BIGNUM *) a, (const BIGNUM *) b);
1293}
1294
1295
1296int crypto_bignum_bits(const struct crypto_bignum *a)
1297{
1298 return BN_num_bits((const BIGNUM *) a);
1299}
1300
1301
1302int crypto_bignum_is_zero(const struct crypto_bignum *a)
1303{
1304 return BN_is_zero((const BIGNUM *) a);
1305}
1306
1307
1308int crypto_bignum_is_one(const struct crypto_bignum *a)
1309{
1310 return BN_is_one((const BIGNUM *) a);
1311}
1312
1313
Dmitry Shmidt41712582015-06-29 11:02:15 -07001314int crypto_bignum_legendre(const struct crypto_bignum *a,
1315 const struct crypto_bignum *p)
1316{
1317 BN_CTX *bnctx;
1318 BIGNUM *exp = NULL, *tmp = NULL;
1319 int res = -2;
1320
Dmitry Shmidte4663042016-04-04 10:07:49 -07001321 if (TEST_FAIL())
1322 return -2;
1323
Dmitry Shmidt41712582015-06-29 11:02:15 -07001324 bnctx = BN_CTX_new();
1325 if (bnctx == NULL)
1326 return -2;
1327
1328 exp = BN_new();
1329 tmp = BN_new();
1330 if (!exp || !tmp ||
1331 /* exp = (p-1) / 2 */
1332 !BN_sub(exp, (const BIGNUM *) p, BN_value_one()) ||
1333 !BN_rshift1(exp, exp) ||
1334 !BN_mod_exp(tmp, (const BIGNUM *) a, exp, (const BIGNUM *) p,
1335 bnctx))
1336 goto fail;
1337
1338 if (BN_is_word(tmp, 1))
1339 res = 1;
1340 else if (BN_is_zero(tmp))
1341 res = 0;
1342 else
1343 res = -1;
1344
1345fail:
1346 BN_clear_free(tmp);
1347 BN_clear_free(exp);
1348 BN_CTX_free(bnctx);
1349 return res;
1350}
1351
1352
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001353#ifdef CONFIG_ECC
1354
1355struct crypto_ec {
1356 EC_GROUP *group;
1357 BN_CTX *bnctx;
1358 BIGNUM *prime;
1359 BIGNUM *order;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001360 BIGNUM *a;
1361 BIGNUM *b;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001362};
1363
1364struct crypto_ec * crypto_ec_init(int group)
1365{
1366 struct crypto_ec *e;
1367 int nid;
1368
1369 /* Map from IANA registry for IKE D-H groups to OpenSSL NID */
1370 switch (group) {
1371 case 19:
1372 nid = NID_X9_62_prime256v1;
1373 break;
1374 case 20:
1375 nid = NID_secp384r1;
1376 break;
1377 case 21:
1378 nid = NID_secp521r1;
1379 break;
1380 case 25:
1381 nid = NID_X9_62_prime192v1;
1382 break;
1383 case 26:
1384 nid = NID_secp224r1;
1385 break;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001386#ifdef NID_brainpoolP224r1
1387 case 27:
1388 nid = NID_brainpoolP224r1;
1389 break;
1390#endif /* NID_brainpoolP224r1 */
1391#ifdef NID_brainpoolP256r1
1392 case 28:
1393 nid = NID_brainpoolP256r1;
1394 break;
1395#endif /* NID_brainpoolP256r1 */
1396#ifdef NID_brainpoolP384r1
1397 case 29:
1398 nid = NID_brainpoolP384r1;
1399 break;
1400#endif /* NID_brainpoolP384r1 */
1401#ifdef NID_brainpoolP512r1
1402 case 30:
1403 nid = NID_brainpoolP512r1;
1404 break;
1405#endif /* NID_brainpoolP512r1 */
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001406 default:
1407 return NULL;
1408 }
1409
1410 e = os_zalloc(sizeof(*e));
1411 if (e == NULL)
1412 return NULL;
1413
1414 e->bnctx = BN_CTX_new();
1415 e->group = EC_GROUP_new_by_curve_name(nid);
1416 e->prime = BN_new();
1417 e->order = BN_new();
Dmitry Shmidt41712582015-06-29 11:02:15 -07001418 e->a = BN_new();
1419 e->b = BN_new();
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001420 if (e->group == NULL || e->bnctx == NULL || e->prime == NULL ||
Dmitry Shmidt41712582015-06-29 11:02:15 -07001421 e->order == NULL || e->a == NULL || e->b == NULL ||
1422 !EC_GROUP_get_curve_GFp(e->group, e->prime, e->a, e->b, e->bnctx) ||
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001423 !EC_GROUP_get_order(e->group, e->order, e->bnctx)) {
1424 crypto_ec_deinit(e);
1425 e = NULL;
1426 }
1427
1428 return e;
1429}
1430
1431
1432void crypto_ec_deinit(struct crypto_ec *e)
1433{
1434 if (e == NULL)
1435 return;
Dmitry Shmidt41712582015-06-29 11:02:15 -07001436 BN_clear_free(e->b);
1437 BN_clear_free(e->a);
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001438 BN_clear_free(e->order);
Dmitry Shmidt661b4f72014-09-29 14:58:27 -07001439 BN_clear_free(e->prime);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001440 EC_GROUP_free(e->group);
1441 BN_CTX_free(e->bnctx);
1442 os_free(e);
1443}
1444
1445
1446struct crypto_ec_point * crypto_ec_point_init(struct crypto_ec *e)
1447{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001448 if (TEST_FAIL())
1449 return NULL;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001450 if (e == NULL)
1451 return NULL;
1452 return (struct crypto_ec_point *) EC_POINT_new(e->group);
1453}
1454
1455
1456size_t crypto_ec_prime_len(struct crypto_ec *e)
1457{
1458 return BN_num_bytes(e->prime);
1459}
1460
1461
1462size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
1463{
1464 return BN_num_bits(e->prime);
1465}
1466
1467
1468const struct crypto_bignum * crypto_ec_get_prime(struct crypto_ec *e)
1469{
1470 return (const struct crypto_bignum *) e->prime;
1471}
1472
1473
1474const struct crypto_bignum * crypto_ec_get_order(struct crypto_ec *e)
1475{
1476 return (const struct crypto_bignum *) e->order;
1477}
1478
1479
1480void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
1481{
1482 if (clear)
1483 EC_POINT_clear_free((EC_POINT *) p);
1484 else
1485 EC_POINT_free((EC_POINT *) p);
1486}
1487
1488
1489int crypto_ec_point_to_bin(struct crypto_ec *e,
1490 const struct crypto_ec_point *point, u8 *x, u8 *y)
1491{
1492 BIGNUM *x_bn, *y_bn;
1493 int ret = -1;
1494 int len = BN_num_bytes(e->prime);
1495
Dmitry Shmidte4663042016-04-04 10:07:49 -07001496 if (TEST_FAIL())
1497 return -1;
1498
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001499 x_bn = BN_new();
1500 y_bn = BN_new();
1501
1502 if (x_bn && y_bn &&
1503 EC_POINT_get_affine_coordinates_GFp(e->group, (EC_POINT *) point,
1504 x_bn, y_bn, e->bnctx)) {
1505 if (x) {
1506 crypto_bignum_to_bin((struct crypto_bignum *) x_bn,
1507 x, len, len);
1508 }
1509 if (y) {
1510 crypto_bignum_to_bin((struct crypto_bignum *) y_bn,
1511 y, len, len);
1512 }
1513 ret = 0;
1514 }
1515
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001516 BN_clear_free(x_bn);
1517 BN_clear_free(y_bn);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001518 return ret;
1519}
1520
1521
1522struct crypto_ec_point * crypto_ec_point_from_bin(struct crypto_ec *e,
1523 const u8 *val)
1524{
1525 BIGNUM *x, *y;
1526 EC_POINT *elem;
1527 int len = BN_num_bytes(e->prime);
1528
Dmitry Shmidte4663042016-04-04 10:07:49 -07001529 if (TEST_FAIL())
1530 return NULL;
1531
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001532 x = BN_bin2bn(val, len, NULL);
1533 y = BN_bin2bn(val + len, len, NULL);
1534 elem = EC_POINT_new(e->group);
1535 if (x == NULL || y == NULL || elem == NULL) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001536 BN_clear_free(x);
1537 BN_clear_free(y);
1538 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001539 return NULL;
1540 }
1541
1542 if (!EC_POINT_set_affine_coordinates_GFp(e->group, elem, x, y,
1543 e->bnctx)) {
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001544 EC_POINT_clear_free(elem);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001545 elem = NULL;
1546 }
1547
Dmitry Shmidt7f0b69e2014-07-28 10:35:20 -07001548 BN_clear_free(x);
1549 BN_clear_free(y);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001550
1551 return (struct crypto_ec_point *) elem;
1552}
1553
1554
1555int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
1556 const struct crypto_ec_point *b,
1557 struct crypto_ec_point *c)
1558{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001559 if (TEST_FAIL())
1560 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001561 return EC_POINT_add(e->group, (EC_POINT *) c, (const EC_POINT *) a,
1562 (const EC_POINT *) b, e->bnctx) ? 0 : -1;
1563}
1564
1565
1566int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
1567 const struct crypto_bignum *b,
1568 struct crypto_ec_point *res)
1569{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001570 if (TEST_FAIL())
1571 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001572 return EC_POINT_mul(e->group, (EC_POINT *) res, NULL,
1573 (const EC_POINT *) p, (const BIGNUM *) b, e->bnctx)
1574 ? 0 : -1;
1575}
1576
1577
1578int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
1579{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001580 if (TEST_FAIL())
1581 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001582 return EC_POINT_invert(e->group, (EC_POINT *) p, e->bnctx) ? 0 : -1;
1583}
1584
1585
1586int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
1587 struct crypto_ec_point *p,
1588 const struct crypto_bignum *x, int y_bit)
1589{
Dmitry Shmidte4663042016-04-04 10:07:49 -07001590 if (TEST_FAIL())
1591 return -1;
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001592 if (!EC_POINT_set_compressed_coordinates_GFp(e->group, (EC_POINT *) p,
1593 (const BIGNUM *) x, y_bit,
1594 e->bnctx) ||
1595 !EC_POINT_is_on_curve(e->group, (EC_POINT *) p, e->bnctx))
1596 return -1;
1597 return 0;
1598}
1599
1600
Dmitry Shmidt41712582015-06-29 11:02:15 -07001601struct crypto_bignum *
1602crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
1603 const struct crypto_bignum *x)
1604{
1605 BIGNUM *tmp, *tmp2, *y_sqr = NULL;
1606
Dmitry Shmidte4663042016-04-04 10:07:49 -07001607 if (TEST_FAIL())
1608 return NULL;
1609
Dmitry Shmidt41712582015-06-29 11:02:15 -07001610 tmp = BN_new();
1611 tmp2 = BN_new();
1612
1613 /* y^2 = x^3 + ax + b */
1614 if (tmp && tmp2 &&
1615 BN_mod_sqr(tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1616 BN_mod_mul(tmp, tmp, (const BIGNUM *) x, e->prime, e->bnctx) &&
1617 BN_mod_mul(tmp2, e->a, (const BIGNUM *) x, e->prime, e->bnctx) &&
1618 BN_mod_add_quick(tmp2, tmp2, tmp, e->prime) &&
1619 BN_mod_add_quick(tmp2, tmp2, e->b, e->prime)) {
1620 y_sqr = tmp2;
1621 tmp2 = NULL;
1622 }
1623
1624 BN_clear_free(tmp);
1625 BN_clear_free(tmp2);
1626
1627 return (struct crypto_bignum *) y_sqr;
1628}
1629
1630
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001631int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
1632 const struct crypto_ec_point *p)
1633{
1634 return EC_POINT_is_at_infinity(e->group, (const EC_POINT *) p);
1635}
1636
1637
1638int crypto_ec_point_is_on_curve(struct crypto_ec *e,
1639 const struct crypto_ec_point *p)
1640{
Dmitry Shmidt41712582015-06-29 11:02:15 -07001641 return EC_POINT_is_on_curve(e->group, (const EC_POINT *) p,
1642 e->bnctx) == 1;
1643}
1644
1645
1646int crypto_ec_point_cmp(const struct crypto_ec *e,
1647 const struct crypto_ec_point *a,
1648 const struct crypto_ec_point *b)
1649{
1650 return EC_POINT_cmp(e->group, (const EC_POINT *) a,
1651 (const EC_POINT *) b, e->bnctx);
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -08001652}
1653
1654#endif /* CONFIG_ECC */