Proposed Patch: Support for wolfSSL

Sean Parkinson sean at wolfssl.com
Wed Mar 28 21:55:55 PDT 2018


Jouni,

(Excuse the previous email. This one in plaintext.)

I’ve looked into the failures and made changes as needed.
There were changes to wolfSSL as well.

To reproduce the setup I tested:
 - download wolfSSL latest from master (https://github.com/wolfssl/wolfssl)
 - configure wolfSSL with option -enable-wpas
 - build wolfSSL
 - in wpa_supplicant change .config
   - CONFIG_TLS=wolfssl
   - disable CONFIG_DPP

The proposed new patch is below.

Thanks,
Sean
—
Sean Parkinson
sean at wolfssl.com
wolfSSL Inc


From 80ba12c7fecdd650d7528211e68e6fd7ededd736 Mon Sep 17 00:00:00 2001
From: Sean Parkinson <sparki at wolfssl.com>
Date: Mon, 19 Mar 2018 13:19:08 +1000
Subject: [PATCH] Fixes for wolfSSL integration.

Use new digest namespace.
Changes for memory allocation failure testing.
Use same certificates as used for GnuTLS in tests.
Implement tls_connection_get_eap_fast_key using cryptographic primitives
as wolfSSL implements different spec.
Use a valid key exchange value in test.
Fix loading of client certificate to use 'chain' APIs.

Signed-off-by: Sean Parkinson <sean at wolfssl.com>
---
 hostapd/Makefile              |   2 +
 src/crypto/crypto_wolfssl.c   | 192 +++++++++++++++++++++++++++++++++---------
 src/crypto/fips_prf_wolfssl.c |   3 +-
 src/crypto/tls_wolfssl.c      | 109 ++++++++++++++----------
 tests/hwsim/test_ap_eap.py    |  10 +--
 tests/hwsim/test_eap_proto.py |   2 +-
 wpa_supplicant/Makefile       |   1 +
 7 files changed, 228 insertions(+), 91 deletions(-)

diff --git a/hostapd/Makefile b/hostapd/Makefile
index 98ce115..9f8c6cf 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -899,9 +899,11 @@ AESOBJS += ../src/crypto/aes-encblock.o
 endif
 ifdef NEED_AES_OMAC1
 ifneq ($(CONFIG_TLS), linux)
+ifneq ($(CONFIG_TLS), wolfssl)
 AESOBJS += ../src/crypto/aes-omac1.o
 endif
 endif
+endif
 ifdef NEED_AES_UNWRAP
 ifneq ($(CONFIG_TLS), openssl)
 ifneq ($(CONFIG_TLS), linux)
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 90163c4..7e68716 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -11,18 +11,8 @@
 #include "common.h"
 #include "crypto.h"
 
-#define WOLFSSL_AES_DIRECT
-#define HAVE_AESGCM
-#define HAVE_AES_KEYWRAP
-#define WOLFSSL_SHA384
-#define WOLFSSL_SHA512
-#define WOLFSSL_CMAC
-#define HAVE_ECC
-#define USE_FAST_MATH
-#define WOLFSSL_KEY_GEN
-
-#include <wolfssl/options.h>
 /* wolfSSL headers */
+#include <wolfssl/options.h>
 #include <wolfssl/wolfcrypt/md4.h>
 #include <wolfssl/wolfcrypt/md5.h>
 #include <wolfssl/wolfcrypt/sha.h>
@@ -62,7 +52,7 @@ int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-	Md5 md5;
+	wc_Md5 md5;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -83,7 +73,7 @@ int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 
 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 {
-	Sha sha;
+	wc_Sha sha;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -104,7 +94,7 @@ int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
 int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha256 sha256;
+	wc_Sha256 sha256;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -126,7 +116,7 @@ int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha384 sha384;
+	wc_Sha384 sha384;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -148,7 +138,7 @@ int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len,
 		  u8 *mac)
 {
-	Sha512 sha512;
+	wc_Sha512 sha512;
 	size_t i;
 
 	if (TEST_FAIL())
@@ -186,6 +176,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
 			return -1;
 	if (wc_HmacFinal(&hmac, mac) != 0)
 		return -1;
+
 	return 0;
 }
 
@@ -195,7 +186,7 @@ static int wolfssl_hmac_vector(int type, const u8 *key,
 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 wolfssl_hmac_vector(MD5, key, key_len, num_elem, addr, len, mac,
+	return wolfssl_hmac_vector(WC_MD5, key, key_len, num_elem, addr, len, mac,
 				   16);
 }
 
@@ -212,7 +203,7 @@ int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 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 wolfssl_hmac_vector(SHA, key, key_len, num_elem, addr, len, mac,
+	return wolfssl_hmac_vector(WC_SHA, key, key_len, num_elem, addr, len, mac,
 				   20);
 }
 
@@ -229,7 +220,7 @@ int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
 int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
 		       const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA256, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA256, key, key_len, num_elem, addr, len,
 				   mac, 32);
 }
 
@@ -248,7 +239,7 @@ int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
 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 wolfssl_hmac_vector(SHA384, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA384, key, key_len, num_elem, addr, len,
 				   mac, 48);
 }
 
@@ -267,7 +258,7 @@ int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
 int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
 		       const u8 *addr[], const size_t *len, u8 *mac)
 {
-	return wolfssl_hmac_vector(SHA512, key, key_len, num_elem, addr, len,
+	return wolfssl_hmac_vector(WC_SHA512, key, key_len, num_elem, addr, len,
 				   mac, 64);
 }
 
@@ -285,7 +276,7 @@ int pbkdf2_sha1(const char *passphrase, const u8 *ssid, size_t ssid_len,
 		int iterations, u8 *buf, size_t buflen)
 {
 	if (wc_PBKDF2(buf, (const byte*)passphrase, os_strlen(passphrase), ssid,
-		      ssid_len, iterations, buflen, SHA) != 0)
+		      ssid_len, iterations, buflen, WC_SHA) != 0)
 		return -1;
 	return 0;
 }
@@ -423,6 +414,9 @@ int aes_wrap(const u8 *kek, size_t kek_len, int n, const u8 *plain, u8 *cipher)
 {
 	int ret;
 
+	if (TEST_FAIL())
+		return -1;
+
 	ret = wc_AesKeyWrap(kek, kek_len, plain, n * 8, cipher, (n + 1) * 8,
 			    NULL);
 	return ret != (n + 1) * 8 ? -1 : 0;
@@ -434,6 +428,9 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
 {
 	int ret;
 
+	if (TEST_FAIL())
+		return -1;
+
 	ret = wc_AesKeyUnWrap(kek, kek_len, cipher, (n + 1) * 8, plain, n * 8,
 			      NULL);
 	return ret != n * 8 ? -1 : 0;
@@ -654,13 +651,13 @@ void * dh5_init(struct wpabuf **priv, struct wpabuf **publ)
 	wpabuf_free(*publ);
 	*publ = NULL;
 
-	dh = os_malloc(sizeof(DhKey));
+	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!dh)
 		return NULL;
 	wc_InitDhKey(dh);
 
 	if (wc_InitRng(&rng) != 0) {
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 		return NULL;
 	}
 
@@ -692,7 +689,7 @@ done:
 	wpabuf_clear_free(privkey);
 	if (dh) {
 		wc_FreeDhKey(dh);
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	}
 	wc_FreeRng(&rng);
 	return ret;
@@ -706,12 +703,12 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 	byte *secret;
 	word32 secret_sz;
 
-	dh = os_malloc(sizeof(DhKey));
+	dh = XMALLOC(sizeof(DhKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!dh)
 		return NULL;
 	wc_InitDhKey(dh);
 
-	secret = os_malloc(RFC3526_LEN);
+	secret = XMALLOC(RFC3526_LEN, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	if (!secret)
 		goto done;
 
@@ -734,9 +731,9 @@ void * dh5_init_fixed(const struct wpabuf *priv, const struct wpabuf *publ)
 done:
 	if (dh) {
 		wc_FreeDhKey(dh);
-		os_free(dh);
+		XFREE(dh, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	}
-	os_free(secret);
+	XFREE(secret, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 	return ret;
 }
 
@@ -773,7 +770,7 @@ void dh5_free(void *ctx)
 		return;
 
 	wc_FreeDhKey(ctx);
-	os_free(ctx);
+	XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
 }
 
 #endif /* CONFIG_WPS_NFC */
@@ -787,9 +784,6 @@ int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
 	DhKey *dh = NULL;
 	word32 priv_sz, pub_sz;
 
-	if (TEST_FAIL())
-		return -1;
-
 	dh = os_malloc(sizeof(DhKey));
 	if (!dh)
 		return -1;
@@ -889,7 +883,7 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 	struct crypto_hash *hash;
 	int type;
 
-	hash = os_malloc(sizeof(*hash));
+	hash = os_zalloc(sizeof(*hash));
 	if (!hash)
 		goto done;
 
@@ -897,19 +891,19 @@ struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
 #ifndef NO_MD5
 	case CRYPTO_HASH_ALG_HMAC_MD5:
 		hash->size = 16;
-		type = MD5;
+		type = WC_MD5;
 		break;
 #endif /* NO_MD5 */
 #ifndef NO_SHA
 	case CRYPTO_HASH_ALG_HMAC_SHA1:
-		type = SHA;
+		type = WC_SHA;
 		hash->size = 20;
 		break;
 #endif /* NO_SHA */
 #ifdef CONFIG_SHA256
 #ifndef NO_SHA256
 	case CRYPTO_HASH_ALG_HMAC_SHA256:
-		type = SHA256;
+		type = WC_SHA256;
 		hash->size = 32;
 		break;
 #endif /* NO_SHA256 */
@@ -1597,7 +1591,7 @@ int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
 	ret = crypto_bignum_to_bin(x, buf + 1, prime_len, prime_len);
 	if (ret <= 0)
 		return -1;
-	ret = wc_ecc_import_point_der(buf, ret + 1, e->key.idx,
+	ret = wc_ecc_import_point_der(buf, ret * 2 + 1, e->key.idx,
 				      (ecc_point *) p);
 	if (ret != 0)
 		return -1;
@@ -1625,7 +1619,7 @@ crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
 		goto done;
 
 	if (mp_sqrmod((mp_int *) x, &e->prime, y2) != 0 ||
-	    mp_mulmod((mp_int *) x, &t, &e->prime, y2) != 0 ||
+	    mp_mulmod((mp_int *) x, y2, &e->prime, y2) != 0 ||
 	    mp_mulmod((mp_int *) x, &e->a, &e->prime, &t) != 0 ||
 	    mp_addmod(y2, &t, &e->prime, y2) != 0 ||
 	    mp_addmod(y2, &e->b, &e->prime, y2) != 0)
@@ -1667,4 +1661,124 @@ int crypto_ec_point_cmp(const struct crypto_ec *e,
 	return wc_ecc_cmp_point((ecc_point *) a, (ecc_point *) b);
 }
 
+struct crypto_ecdh {
+	struct crypto_ec *ec;
+};
+
+struct crypto_ecdh * crypto_ecdh_init(int group)
+{
+	struct crypto_ecdh *ecdh = NULL;
+	WC_RNG rng;
+	int ret;
+
+	if (wc_InitRng(&rng) != 0)
+		goto fail;
+
+	ecdh = os_zalloc(sizeof(*ecdh));
+	if (!ecdh)
+		goto fail;
+
+	ecdh->ec = crypto_ec_init(group);
+	if (!ecdh->ec)
+		goto fail;
+
+	ret = wc_ecc_make_key_ex(&rng, ecdh->ec->key.dp->size, &ecdh->ec->key,
+				 ecdh->ec->key.dp->id);
+	if (ret < 0)
+		goto fail;
+
+done:
+	wc_FreeRng(&rng);
+
+	return ecdh;
+fail:
+	crypto_ecdh_deinit(ecdh);
+	ecdh = NULL;
+	goto done;
+}
+
+void crypto_ecdh_deinit(struct crypto_ecdh *ecdh)
+{
+	if (ecdh) {
+		crypto_ec_deinit(ecdh->ec);
+		os_free(ecdh);
+	}
+}
+
+struct wpabuf * crypto_ecdh_get_pubkey(struct crypto_ecdh *ecdh, int inc_y)
+{
+	struct wpabuf *buf = NULL;
+	int ret;
+	int len = ecdh->ec->key.dp->size;
+
+	buf = wpabuf_alloc(inc_y ? 2 * len : len);
+	if (!buf)
+		goto fail;
+
+	ret = crypto_bignum_to_bin((struct crypto_bignum *)
+				   ecdh->ec->key.pubkey.x, wpabuf_put(buf, len),
+				   len, len);
+	if (ret < 0)
+		goto fail;
+	if (inc_y) {
+		ret = crypto_bignum_to_bin((struct crypto_bignum *)
+					   ecdh->ec->key.pubkey.y,
+					   wpabuf_put(buf, len), len, len);
+		if (ret < 0)
+			goto fail;
+	}
+
+done:
+	return buf;
+fail:
+	wpabuf_free(buf);
+	buf = NULL;
+	goto done;
+}
+
+struct wpabuf * crypto_ecdh_set_peerkey(struct crypto_ecdh *ecdh, int inc_y,
+					const u8 *key, size_t len)
+{
+	int ret;
+	struct wpabuf *pubkey = NULL;
+	struct wpabuf *secret = NULL;
+	word32 key_len = ecdh->ec->key.dp->size;
+	ecc_point *point = NULL;
+
+	pubkey = wpabuf_alloc(key_len + 1);
+	if (!pubkey)
+		goto fail;
+	wpabuf_put_u8(pubkey, inc_y ? 0x04 : 0x02);
+	wpabuf_put_data(pubkey, key, key_len);
+
+	point = wc_ecc_new_point();
+	if (!point)
+		goto fail;
+
+	ret = wc_ecc_import_point_der(wpabuf_put(pubkey, key_len + 1), key_len,
+				      ecdh->ec->key.dp->id, point);
+	if (ret != MP_OKAY)
+		goto fail;
+
+	secret = wpabuf_alloc(key_len);
+	if (!secret)
+		goto fail;
+
+	ret = wc_ecc_shared_secret_ex(&ecdh->ec->key, point,
+				      (byte*)wpabuf_put(secret, key_len),
+				      &key_len);
+	if (ret != MP_OKAY)
+		goto fail;
+
+done:
+	wc_ecc_del_point(point);
+	wpabuf_free(pubkey);
+	return secret;
+fail:
+	wpabuf_free(secret);
+	secret = NULL;
+	goto done;
+}
+
+
 #endif /* CONFIG_ECC */
diff --git a/src/crypto/fips_prf_wolfssl.c b/src/crypto/fips_prf_wolfssl.c
index 1709932..feb39db 100644
--- a/src/crypto/fips_prf_wolfssl.c
+++ b/src/crypto/fips_prf_wolfssl.c
@@ -7,6 +7,7 @@
  */
 
 #include "includes.h"
+#include <wolfssl/options.h>
 #include <wolfssl/wolfcrypt/sha.h>
 
 #include "common.h"
@@ -15,7 +16,7 @@
 
 static void sha1_transform(u32 *state, const u8 data[64])
 {
-	Sha sha;
+	wc_Sha sha;
 
 	os_memset(&sha, 0, sizeof(sha));
 	sha.digest[0] = state[0];
diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
index b7c452e..82ced39 100644
--- a/src/crypto/tls_wolfssl.c
+++ b/src/crypto/tls_wolfssl.c
@@ -10,24 +10,16 @@
 
 #include "common.h"
 #include "crypto.h"
+#include "sha1.h"
 #include "tls.h"
 
-#define OPENSSL_EXTRA
-#define HAVE_STUNNEL
-#define HAVE_SECRET_CALLBACK
-#define HAVE_SESSION_TICKET
-#define HAVE_OCSP
-#define HAVE_CERTIFICATE_STATUS_REQUEST
-#define HAVE_CERTIFICATE_STATUS_REQUEST_V2
-#ifndef WOLFSSL_DER_LOAD
-#define WOLFSSL_DER_LOAD
-#endif
-#if 0
-/* Enable if a debug build of wolfSSL is installed. */
-#define DEBUG_WOLFSSL
-#endif
+/* sha256.h is a wolfSSL header file. */
+extern void tls_prf_sha256(const u8 *secret, size_t secret_len,
+			   const char *label, const u8 *seed, size_t seed_len,
+			   u8 *out, size_t outlen);
 
 /* wolfSSL includes */
+#include <wolfssl/options.h>
 #include <wolfssl/ssl.h>
 #include <wolfssl/error-ssl.h>
 #include <wolfssl/wolfcrypt/asn.h>
@@ -470,9 +462,9 @@ static int tls_connection_client_cert(struct tls_connection *conn,
 		return 0;
 
 	if (client_cert_blob) {
-		if (wolfSSL_use_certificate_buffer(conn->ssl, client_cert_blob,
-						   blob_len,
-						   SSL_FILETYPE_ASN1) < 0) {
+		if (wolfSSL_use_certificate_chain_buffer_format(conn->ssl,
+			    client_cert_blob, blob_len,
+			    SSL_FILETYPE_ASN1) < 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert DER blob failed");
 			return -1;
@@ -482,11 +474,11 @@ static int tls_connection_client_cert(struct tls_connection *conn,
 	}
 
 	if (client_cert) {
-		if (wolfSSL_use_certificate_file(conn->ssl, client_cert,
-						 SSL_FILETYPE_PEM) < 0) {
+		if (wolfSSL_use_certificate_chain_file(conn->ssl,
+						       client_cert) < 0) {
 			wpa_printf(MSG_INFO,
 				   "SSL: use client cert PEM file failed");
-			if (wolfSSL_use_certificate_file(
+			if (wolfSSL_use_certificate_chain_file_format(
 				    conn->ssl, client_cert,
 				    SSL_FILETYPE_ASN1) < 0) {
 				wpa_printf(MSG_INFO,
@@ -577,10 +569,6 @@ static int tls_connection_private_key(void *tls_ctx,
 }
 
 
-#define GEN_EMAIL	1
-#define GEN_DNS		ALT_NAMES_OID
-#define GEN_URI		6
-
 static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
 					   const char *value, size_t len)
 {
@@ -590,7 +578,6 @@ static int tls_match_alt_subject_component(WOLFSSL_X509 *cert, int type,
 	int i;
 
 	ext = wolfSSL_X509_get_ext_d2i(cert, ALT_NAMES_OID, NULL, NULL);
-
 	for (i = 0; ext && i < wolfSSL_sk_num(ext); i++) {
 		gen = wolfSSL_sk_value(ext, i);
 		if (gen->type != type)
@@ -893,19 +880,16 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
 		if (num_alt_subject == TLS_MAX_ALT_SUBJECT)
 			break;
 		gen = wolfSSL_sk_value((void *) ext, i);
-#if 0
 		if (gen->type != GEN_EMAIL &&
 		    gen->type != GEN_DNS &&
 		    gen->type != GEN_URI)
 			continue;
-#endif
 
 		pos = os_malloc(10 + os_strlen((char *) gen->obj) + 1);
 		if (!pos)
 			break;
 		alt_subject[num_alt_subject++] = pos;
 
-#if 0
 		switch (gen->type) {
 		case GEN_EMAIL:
 			os_memcpy(pos, "EMAIL:", 6);
@@ -920,10 +904,6 @@ static void wolfssl_tls_cert_event(struct tls_connection *conn,
 			pos += 4;
 			break;
 		}
-#else
-		os_memcpy(pos, "DNS:", 4);
-		pos += 4;
-#endif
 
 		os_memcpy(pos, gen->obj, os_strlen((char *)gen->obj));
 		pos += os_strlen((char *)gen->obj);
@@ -1099,7 +1079,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
 				       TLS_FAIL_SERVER_CHAIN_PROBE);
 	}
 
-#ifdef HAVE_OCSP_OPENSSL
+#ifdef HAVE_OCSP_WOLFSSL
 	if (depth == 0 && (conn->flags & TLS_CONN_REQUEST_OCSP) &&
 	    preverify_ok) {
 		enum ocsp_result res;
@@ -1123,7 +1103,7 @@ static int tls_verify_cb(int preverify_ok, WOLFSSL_X509_STORE_CTX *x509_ctx)
 					       TLS_FAIL_UNSPECIFIED);
 		}
 	}
-#endif /* HAVE_OCSP */
+#endif /* HAVE_OCSP_WOLFSSL */
 	if (depth == 0 && preverify_ok && context->event_cb != NULL)
 		context->event_cb(context->cb_ctx,
 				  TLS_CERT_CHAIN_SUCCESS, NULL);
@@ -1204,7 +1184,6 @@ static int tls_connection_ca_cert(void *tls_ctx, struct tls_connection *conn,
 			return -1;
 		}
 		wolfSSL_CTX_set_cert_store(ctx, cm);
-		XFREE(cm, NULL, DYNAMIC_TYPE_X509_STORE);
 
 		if (wolfSSL_CTX_load_verify_locations(ctx, ca_cert, ca_path) !=
 		    SSL_SUCCESS) {
@@ -1370,11 +1349,11 @@ static int tls_global_client_cert(void *ssl_ctx, const char *client_cert)
 	if (!client_cert)
 		return 0;
 
-	if (wolfSSL_CTX_use_certificate_file(ctx, client_cert,
-					     SSL_FILETYPE_ASN1) !=
+	if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, client_cert,
+							  SSL_FILETYPE_ASN1) !=
 	    SSL_SUCCESS &&
-	    wolfSSL_CTX_use_certificate_file(ctx, client_cert,
-					     SSL_FILETYPE_PEM) != SSL_SUCCESS) {
+	    wolfSSL_CTX_use_certificate_chain_file(ctx, client_cert) !=
+	    SSL_SUCCESS) {
 		wpa_printf(MSG_INFO, "Failed to load client certificate");
 		return -1;
 	}
@@ -1988,18 +1967,58 @@ int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
 }
 
 
+#define SEED_LEN	(RAN_LEN + RAN_LEN)
+
 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
 				    u8 *out, size_t out_len)
 {
-	int ret;
+	byte seed[SEED_LEN];
+	int ret = -1;
+	WOLFSSL *ssl;
+	byte *tmp_out = NULL;
+	byte *_out;
+	int skip = 0;
+	byte *master_key;
+	unsigned int master_key_len;
+	byte *server_random;
+	unsigned int server_len;
+	byte *client_random;
+	unsigned int client_len;
 
 	if (!conn || !conn->ssl)
 		return -1;
+	ssl = conn->ssl;
 
-	ret = wolfSSL_make_eap_keys(conn->ssl, out, out_len, "key expansion");
-	if (ret != 0)
+	skip = 2 * (wolfSSL_GetKeySize(ssl) + wolfSSL_GetHmacSize(ssl) +
+		    wolfSSL_GetIVSize(ssl));
+
+	tmp_out = os_malloc(skip + out_len);
+	if (!tmp_out)
 		return -1;
-	return 0;
+	_out = tmp_out;
+
+	wolfSSL_get_keys(ssl, &master_key, &master_key_len, &server_random,
+			 &server_len, &client_random, &client_len);
+	XMEMCPY(seed          , server_random, RAN_LEN);
+	XMEMCPY(seed + RAN_LEN, client_random, RAN_LEN);
+
+	if (wolfSSL_GetVersion(ssl) == WOLFSSL_TLSV1_2) {
+		tls_prf_sha256(master_key, master_key_len,
+			       "key expansion", seed, sizeof(seed),
+			       _out, skip + out_len);
+		ret = 0;
+	} else if (tls_prf_sha1_md5(master_key, master_key_len,
+				    "key expansion", seed, sizeof(seed),
+				    _out, skip + out_len) == 0) {
+		ret = 0;
+	}
+
+	os_memset(master_key, 0, master_key_len);
+	if (ret == 0)
+		os_memcpy(out, _out + skip, out_len);
+	bin_clear_free(tmp_out, skip);
+
+	return ret;
 }
 
 
@@ -2037,14 +2056,14 @@ static int tls_sess_sec_cb(WOLFSSL *s, void *secret, int *secret_len, void *arg)
 				      sizeof(client_random)) == 0 ||
 	    wolfSSL_get_server_random(s, server_random,
 				      sizeof(server_random)) == 0 ||
-	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticketLen) != 1)
+	    wolfSSL_get_SessionTicket(s, conn->session_ticket, &ticket_len) != 1)
 		return 1;
 
 	if (ticket_len == 0)
 		return 0;
 
 	ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
-				      conn->session_ticket, ticketLen,
+				      conn->session_ticket, ticket_len,
 				      client_random, server_random, secret);
 	if (ret <= 0)
 		return 1;
diff --git a/tests/hwsim/test_ap_eap.py b/tests/hwsim/test_ap_eap.py
index 88041ca..804cbca 100644
--- a/tests/hwsim/test_ap_eap.py
+++ b/tests/hwsim/test_ap_eap.py
@@ -4115,7 +4115,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca(dev, apdev, params):
     params["private_key"] = "auth_serv/iCA-server/server.key"
     hostapd.add_ap(apdev[0], params)
     tls = dev[0].request("GET tls_library")
-    if "GnuTLS" in tls:
+    if "GnuTLS" in tls or "wolfSSL" in tls:
         ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
         client_cert = "auth_serv/iCA-user/user_and_ica.pem"
     else:
@@ -4223,7 +4223,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp(dev, apdev, params, md):
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4258,7 +4258,7 @@ def run_ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked(dev, apdev, params, md):
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4308,7 +4308,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi_missing_resp(dev, apdev, par
     try:
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
@@ -4375,7 +4375,7 @@ def test_ap_wpa2_eap_tls_intermediate_ca_ocsp_multi(dev, apdev, params):
 
         hostapd.add_ap(apdev[0], params)
         tls = dev[0].request("GET tls_library")
-        if "GnuTLS" in tls:
+        if "GnuTLS" in tls or "wolfSSL" in tls:
             ca_cert = "auth_serv/iCA-user/ca-and-root.pem"
             client_cert = "auth_serv/iCA-user/user_and_ica.pem"
         else:
diff --git a/tests/hwsim/test_eap_proto.py b/tests/hwsim/test_eap_proto.py
index d97a6f1..2ff6743 100644
--- a/tests/hwsim/test_eap_proto.py
+++ b/tests/hwsim/test_eap_proto.py
@@ -5124,7 +5124,7 @@ def test_eap_proto_ikev2(dev, apdev):
 
         def build_ke(next=0):
             ke = struct.pack(">BBHHH", next, 0, 4 + 4 + 192, 5, 0)
-            ke += 192*'\x00'
+            ke += 191*'\x00'+'\x02'
             return ke
 
         idx += 1
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
index c761c22..eca20a9 100644
--- a/wpa_supplicant/Makefile
+++ b/wpa_supplicant/Makefile
@@ -1067,6 +1067,7 @@ OBJS_p += ../src/crypto/crypto_wolfssl.o
 ifdef NEED_FIPS186_2_PRF
 OBJS += ../src/crypto/fips_prf_wolfssl.o
 endif
+NEED_TLS_PRF_SHA256=y
 LIBS += -lwolfssl -lm
 LIBS_p += -lwolfssl -lm
 endif
-- 
1.9.1
> On 4 Mar 2018, at 5:19 am, Jouni Malinen <j at w1.fi> wrote:
> 
> On Thu, Jan 18, 2018 at 12:26:39PM +1000, Sean Parkinson wrote:
>> I’ve prepared a new patch with the changes as asked for by Jouni.
>> 
>> This patch was written to allow hostap to be compiled with the wolfSSL cryptography and TLS library.
> 
> Thanks! I'm seeing number of errors in the hwsim test cases, but it
> looks like it is easiest to move ahead with this if I push in the
> cleaned up version that I've been testing with some fixes to avoid
> breaking non-wolfSSL builds. I'd welcome any incremental changes on top
> of the current hostap.git master branch snapshot to address things that
> I list below or maybe a recommendation on how to configure the wolfSSL
> build properly to avoid the issues. I ran my tests with wolfSSL 3.13.0
> and ended up adding various configure options until the build went
> through cleanly. This ended up with following options:
> 
> ./configure --prefix=/home/jm/wolfssl/3.13.0 --enable-des3 --enable-md4 --enable-harden --enable-pwdbased --enable-tlsv10 --enable-oldtls --enable-cmac --enable-aeskeywrap --enable-keygen --enable-crl --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 --enable-pkcallbacks --enable-tls13 --enable-fortress --enable-wpas --enable-static=yes --enable-shared=no
> 
> 
> These are the notes from my hwsim test runs:
> 
> SAE:
> - SAE: Could not solve y
> - SAE: Could not pick PWE
> --> check crypto_ec_point_solve_y_coord() implementation
>   (wc_ecc_import_point_der() returns -1)
> sae
> sae_anti_clogging
> sae_anti_clogging_proto
> sae_bignum_failure
> sae_forced_anti_clogging
> sae_group_nego
> sae_groups
> sae_invalid_anti_clogging_token_req
> sae_key_lifetime_in_memory
> sae_mixed
> sae_mixed_mfp
> sae_no_random
> sae_oom_wpas
> sae_password
> sae_password_ecc
> sae_password_long
> sae_password_short
> sae_pmksa_caching
> sae_pmksa_caching_disabled
> sae_proto_confirm_replay
> sae_proto_ecc
> sae_pwe_failure
> ap_ft_sae
> ap_ft_sae_over_ds
> sigma_dut_ap_psk_sae
> sigma_dut_ap_sae
> sigma_dut_ap_sae_group
> sigma_dut_ap_sae_password
> sigma_dut_sae
> sigma_dut_sae_password
> wpas_mesh_password_mismatch
> mesh_forwarding_secure
> ap_mixed_security
> 
> 
> TLS interop(?) issue with OpenSSL server:
> - OpenSSL server:
>  * SSL: SSL3 alert: write (local SSL3 detected an error):fatal:bad record mac
>  * SSL: SSL_accept:error in SSLv3 read finished A
>  * OpenSSL: openssl_handshake - SSL_connect error:1408F119:SSL routines:SSL3_GET_RECORD:decryption failed or bad record mac
> ap_hs20_remediation_sql
> eap_tls_no_session_resumption_radius
> authsrv_testing_options
> ap_wpa2_eap_tls_versions
> 
> 
> OpenSSL authentication server:
> - OpenSSL: openssl_handshake - SSL_connect error:1408A0C1:SSL routines:ssl3_get_client_hello:no shared cipher
> ap_wpa2_eap_ttls_dh_params
> ap_wpa2_eap_ttls_dh_params_blob
> ap_wpa2_eap_ttls_dh_params_dsa
> 
> 
> OpenSSL authentication server:
> - TLS: Certificate verification failed, error 20 (unable to get local issuer certificate) depth 0 for '/C=FI/O=w1.fi/CN=user.w1.fi'
> - SSL: SSL3 alert: write (local SSL3 detected an error):fatal:unknown CA
> - OpenSSL: openssl_handshake - SSL_connect error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed
> ap_wpa2_eap_tls_intermediate_ca
> ap_wpa2_eap_tls_intermediate_ca_ocsp_sha1
> ap_wpa2_eap_tls_intermediate_ca_ocsp
> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked
> ap_wpa2_eap_tls_intermediate_ca_ocsp_revoked_sha1
> 
> 
> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
> TLS: altSubjectName match 'EMAIL:noone at example.com;DNS:server.w1.fi;URI:http://example.com/' not found
> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
> ap_wpa2_eap_ttls_pap_subject_match
> 
> 
> TLS: tls_verify_cb - preverify_ok=1 err=0 (unknown error number) ca_cert_verify=1 depth=0 buf='/C=FI/O=w1.fi/CN=server.w1.fi'
> TLS: altSubjectName match 'EMAIL:noone at example.com;URI:http://example.com/;DNS:server.w1.fi' not found
> wlan0: CTRL-EVENT-EAP-TLS-CERT-ERROR reason=6 depth=0 subject='/C=FI/O=w1.fi/CN=server.w1.fi' err='AltSubject mismatch'
> ap_wpa2_eap_ttls_chap_altsubject_match
> 
> 
> TLS: Certificate verification failed, error -407 (Invalid OCSP Status Error) depth 2 for '/C=FI/O=w1.fi/CN=server.w1.fi'
> ap_wpa2_eap_ttls_ocsp_revoked
> ap_wpa2_eap_ttls_ocsp_unknown
> ap_wpa2_eap_ttls_optional_ocsp_unknown
> 
> 
> Missing altsubject in D-Bus output?!
> dbus_connect_eap
> 
> 
> DH: crypto_dh_derive_secret failed
> eap_proto_ikev2
> 
> 
> TLS: Certificate verification failed, error -238 (ASN CA path length larger than signer error) depth 2 for '/C=FI/O=w1.fi/CN=sha384.server.w1.fi'
> eap_tls_sha384
> eap_tls_sha512
> 
> 
> 
> GET_FAIL/GET_ALLOC_FAIL failure did not trigger:
> radius_mppe_failure
> authsrv_oom
> 
> 
> -- 
> Jouni Malinen                                            PGP id EFC895FA
> 
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap




More information about the Hostap mailing list