/*
* Wrapper functions for OpenSSL libcrypto
- * Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
#include "dh_group5.h"
#include "sha1.h"
#include "sha256.h"
+#include "sha384.h"
#include "crypto.h"
-#if OPENSSL_VERSION_NUMBER < 0x00907000
-#define DES_key_schedule des_key_schedule
-#define DES_cblock des_cblock
-#define DES_set_key(key, schedule) des_set_key((key), *(schedule))
-#define DES_ecb_encrypt(input, output, ks, enc) \
- des_ecb_encrypt((input), (output), *(ks), (enc))
-#endif /* openssl < 0.9.7 */
-
static BIGNUM * get_group5_prime(void)
{
-#if OPENSSL_VERSION_NUMBER < 0x00908000 || defined(OPENSSL_IS_BORINGSSL)
+#ifdef OPENSSL_IS_BORINGSSL
static const unsigned char RFC3526_PRIME_1536[] = {
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC9,0x0F,0xDA,0xA2,
0x21,0x68,0xC2,0x34,0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
0xCA,0x23,0x73,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), NULL);
-#else /* openssl < 0.9.8 */
+#else /* OPENSSL_IS_BORINGSSL */
return get_rfc3526_prime_1536(NULL);
-#endif /* openssl < 0.9.8 */
+#endif /* OPENSSL_IS_BORINGSSL */
}
-#if OPENSSL_VERSION_NUMBER < 0x00908000
-#ifndef OPENSSL_NO_SHA256
-#ifndef OPENSSL_FIPS
-#define NO_SHA256_WRAPPER
-#endif
-#endif
-
-#endif /* openssl < 0.9.8 */
-
#ifdef OPENSSL_NO_SHA256
#define NO_SHA256_WRAPPER
#endif
"in AES encrypt", len);
}
EVP_CIPHER_CTX_cleanup(c);
- os_free(c);
+ bin_clear_free(c, sizeof(*c));
}
"in AES decrypt", len);
}
EVP_CIPHER_CTX_cleanup(c);
- os_free(ctx);
+ bin_clear_free(c, sizeof(*c));
+}
+
+
+int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
+{
+ AES_KEY actx;
+ int res;
+
+ if (AES_set_encrypt_key(kek, kek_len << 3, &actx))
+ return -1;
+ res = AES_wrap_key(&actx, NULL, cipher, plain, n * 8);
+ OPENSSL_cleanse(&actx, sizeof(actx));
+ return res <= 0 ? -1 : 0;
+}
+
+
+int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
+ u8 *plain)
+{
+ AES_KEY actx;
+ int res;
+
+ if (AES_set_decrypt_key(kek, kek_len << 3, &actx))
+ return -1;
+ res = AES_unwrap_key(&actx, NULL, plain, cipher, (n + 1) * 8);
+ OPENSSL_cleanse(&actx, sizeof(actx));
+ return res <= 0 ? -1 : 0;
}
return dh;
err:
- wpabuf_free(pubkey);
- wpabuf_free(privkey);
+ wpabuf_clear_free(pubkey);
+ wpabuf_clear_free(privkey);
DH_free(dh);
return NULL;
}
err:
BN_clear_free(pub_key);
- wpabuf_free(res);
+ wpabuf_clear_free(res);
return NULL;
}
HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL);
#else /* openssl < 0.9.9 */
if (HMAC_Init_ex(&ctx->ctx, key, key_len, md, NULL) != 1) {
- os_free(ctx);
+ bin_clear_free(ctx, sizeof(*ctx));
return NULL;
}
#endif /* openssl < 0.9.9 */
return -2;
if (mac == NULL || len == NULL) {
- os_free(ctx);
+ bin_clear_free(ctx, sizeof(*ctx));
return 0;
}
res = HMAC_Final(&ctx->ctx, mac, &mdlen);
#endif /* openssl < 0.9.9 */
HMAC_CTX_cleanup(&ctx->ctx);
- os_free(ctx);
+ bin_clear_free(ctx, sizeof(*ctx));
if (res == 1) {
*len = mdlen;
}
-int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
- int iterations, u8 *buf, size_t buflen)
-{
-#if OPENSSL_VERSION_NUMBER < 0x00908000
- if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase),
- (unsigned char *) ssid,
- ssid_len, 4096, buflen, buf) != 1)
- return -1;
-#else /* openssl < 0.9.8 */
- if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
- ssid_len, 4096, buflen, buf) != 1)
- return -1;
-#endif /* openssl < 0.9.8 */
- return 0;
-}
-
-
-int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
- const u8 *addr[], const size_t *len, u8 *mac)
+static int openssl_hmac_vector(const EVP_MD *type, const u8 *key,
+ size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac,
+ unsigned int mdlen)
{
HMAC_CTX ctx;
size_t i;
- unsigned int mdlen;
int res;
HMAC_CTX_init(&ctx);
#if OPENSSL_VERSION_NUMBER < 0x00909000
- HMAC_Init_ex(&ctx, key, key_len, EVP_sha1(), NULL);
+ HMAC_Init_ex(&ctx, key, key_len, type, NULL);
#else /* openssl < 0.9.9 */
- if (HMAC_Init_ex(&ctx, key, key_len, EVP_sha1(), NULL) != 1)
+ if (HMAC_Init_ex(&ctx, key, key_len, type, NULL) != 1)
return -1;
#endif /* openssl < 0.9.9 */
for (i = 0; i < num_elem; i++)
HMAC_Update(&ctx, addr[i], len[i]);
- mdlen = 20;
#if OPENSSL_VERSION_NUMBER < 0x00909000
HMAC_Final(&ctx, mac, &mdlen);
res = 1;
}
+#ifndef CONFIG_FIPS
+
+int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ return openssl_hmac_vector(EVP_md5(), key ,key_len, num_elem, addr, len,
+ mac, 16);
+}
+
+
+int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
+ u8 *mac)
+{
+ return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
+}
+
+#endif /* CONFIG_FIPS */
+
+
+int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
+ int iterations, u8 *buf, size_t buflen)
+{
+ if (PKCS5_PBKDF2_HMAC_SHA1(passphrase, os_strlen(passphrase), ssid,
+ ssid_len, iterations, buflen, buf) != 1)
+ return -1;
+ return 0;
+}
+
+
+int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ return openssl_hmac_vector(EVP_sha1(), key, key_len, num_elem, addr,
+ len, mac, 20);
+}
+
+
int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
u8 *mac)
{
int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
const u8 *addr[], const size_t *len, u8 *mac)
{
- HMAC_CTX ctx;
- size_t i;
- unsigned int mdlen;
- int res;
+ return openssl_hmac_vector(EVP_sha256(), key, key_len, num_elem, addr,
+ len, mac, 32);
+}
- HMAC_CTX_init(&ctx);
-#if OPENSSL_VERSION_NUMBER < 0x00909000
- HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), NULL);
-#else /* openssl < 0.9.9 */
- if (HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), NULL) != 1)
- return -1;
-#endif /* openssl < 0.9.9 */
- for (i = 0; i < num_elem; i++)
- HMAC_Update(&ctx, addr[i], len[i]);
+int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
+ size_t data_len, u8 *mac)
+{
+ return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
+}
- mdlen = 32;
-#if OPENSSL_VERSION_NUMBER < 0x00909000
- HMAC_Final(&ctx, mac, &mdlen);
- res = 1;
-#else /* openssl < 0.9.9 */
- res = HMAC_Final(&ctx, mac, &mdlen);
-#endif /* openssl < 0.9.9 */
- HMAC_CTX_cleanup(&ctx);
+#endif /* CONFIG_SHA256 */
- return res == 1 ? 0 : -1;
+
+#ifdef CONFIG_SHA384
+
+int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ return openssl_hmac_vector(EVP_sha384(), key, key_len, num_elem, addr,
+ len, mac, 32);
}
-int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
+int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
size_t data_len, u8 *mac)
{
- return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
+ return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
}
-#endif /* CONFIG_SHA256 */
+#endif /* CONFIG_SHA384 */
int crypto_get_random(void *buf, size_t len)
#ifdef CONFIG_OPENSSL_CMAC
-int omac1_aes_128_vector(const u8 *key, size_t num_elem,
- const u8 *addr[], const size_t *len, u8 *mac)
+int omac1_aes_vector(const u8 *key, size_t key_len, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
{
CMAC_CTX *ctx;
int ret = -1;
if (ctx == NULL)
return -1;
- if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
+ if (key_len == 32) {
+ if (!CMAC_Init(ctx, key, 32, EVP_aes_256_cbc(), NULL))
+ goto fail;
+ } else if (key_len == 16) {
+ if (!CMAC_Init(ctx, key, 16, EVP_aes_128_cbc(), NULL))
+ goto fail;
+ } else {
goto fail;
+ }
for (i = 0; i < num_elem; i++) {
if (!CMAC_Update(ctx, addr[i], len[i]))
goto fail;
}
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
+{
+ return omac1_aes_vector(key, 16, num_elem, addr, len, mac);
+}
+
+
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
}
+
+
+int omac1_aes_256(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+{
+ return omac1_aes_vector(key, 32, 1, &data, &data_len, mac);
+}
#endif /* CONFIG_OPENSSL_CMAC */