From patchwork Mon Apr 25 14:18:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Juliusz Sosinowicz X-Patchwork-Id: 1621984 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=mHSLKUjw; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Kn6b71JYyz9s0B for ; Tue, 26 Apr 2022 00:19:31 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=rPF29uCHaifrFOEcSRduNS0jclitAG995TUyCkNqK9c=; b=mHSLKUjwOKlRMv jMFt4sMA7PPYC/O7v0AT47R2JuuFFajsLuss+L3rD2E6ETrrsqTG/gS/prXRb1KquHmYPT16MRiYj hTR5MlRV/Q52bH7g1E6iKaT7BlAYFBo4fgi5fuDgK+bcZAC/DEbX6p1gob5OOQP+6nfWsr5+EfgYb 9ZOmwvu3Hn2HiWHN0IUsHKogxZoJ8kOQ0pu1qac2S700Q3ru5euoi51i0n39XL3ZRI0ZHapNoFgBr s+LW0b9W3pjRhp8zO85YaEvCxanFWS+CFD7fKa47/T+T8BUscFM7XnBMMzIz9Nbf8usC9qqYh1+v9 hSK4pHcxvHF0vdueZh2Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nizY3-009ssT-P6; Mon, 25 Apr 2022 14:18:43 +0000 Received: from p3plsmtpa07-04.prod.phx3.secureserver.net ([173.201.192.233]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1nizXo-009smx-2k for hostap@lists.infradead.org; Mon, 25 Apr 2022 14:18:32 +0000 Received: from localhost.localdomain ([188.212.135.202]) by :SMTPAUTH: with ESMTPSA id izXjnkS9GMZxqizXkn6Gnm; Mon, 25 Apr 2022 07:18:25 -0700 X-CMAE-Analysis: v=2.4 cv=eMzWMFl1 c=1 sm=1 tr=0 ts=6266adb1 a=J8IhgmmtOvetfMqpEEuyKg==:117 a=J8IhgmmtOvetfMqpEEuyKg==:17 a=VTTltBjBAAAA:8 a=2V6DY6BgAAAA:8 a=dkWkREnVKoSK0fsbPoIA:9 a=on_vo79ac8RWgsiwd8Ea:22 a=ldqKKs2zR4t-S6fqr-1n:22 X-SECURESERVER-ACCT: juliusz@wolfssl.com From: Juliusz Sosinowicz To: hostap@lists.infradead.org Cc: Juliusz Sosinowicz Subject: [PATCH] SAE-PK support with wolfSSL Date: Mon, 25 Apr 2022 16:18:15 +0200 Message-Id: <20220425141814.79927-1-juliusz@wolfssl.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CMAE-Envelope: MS4xfAtW5JVWQrlU81yhyYa1KB8cK4b6XhTqo5fhCNe0p4xnfBxWMZf1p/1CB9oXFUPGV4bB1FPS+DUyh7/Ce8X6nsc2cZ+CPhrx2ZCDK77BaiqAyLWzANN6 KcAFy3tFTWtAu729SkfEZ4MThgeRsVExqEZU4XjtMROdQAXQA0n8GLbomaFzl0xMD7PX6DMiTaOePkDH4T6sCNohU5mMNKOVA85DEZUqdNLnHxPcAC3fi7t3 T7tRzmZDTzYkrKJtWMF0vA== X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220425_071828_202089_B9C4BE81 X-CRM114-Status: GOOD ( 13.43 ) X-Spam-Score: 0.0 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Implement SAE-PK with the using the wolfSSL backend Signed-off-by: Juliusz Sosinowicz --- src/crypto/crypto_wolfssl.c | 255 ++++++++++++++++++++++++++++++++++++ tests/hwsim/test_sae.py | 2 + 2 files changed, 257 insertions(+) Content analysis details: (0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [173.201.192.233 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [173.201.192.233 listed in wl.mailspike.net] 0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Implement SAE-PK with the using the wolfSSL backend Signed-off-by: Juliusz Sosinowicz --- src/crypto/crypto_wolfssl.c | 255 ++++++++++++++++++++++++++++++++++++ tests/hwsim/test_sae.py | 2 + 2 files changed, 257 insertions(+) diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c index 9d470ab92f..6014cfb940 100644 --- a/src/crypto/crypto_wolfssl.c +++ b/src/crypto/crypto_wolfssl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #ifdef ANDROID @@ -1847,6 +1848,260 @@ size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh) return crypto_ec_prime_len(ecdh->ec); } +struct crypto_ec_key { + ecc_key* eckey; + WC_RNG* rng; /* Needs to be initialized before use. + * *NOT* initialized in crypto_ec_key_init */ +}; + +static struct crypto_ec_key* crypto_ec_key_init(void) +{ + struct crypto_ec_key* key; + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_init starting"); + key = os_zalloc(sizeof(struct crypto_ec_key)); + if (key) { + key->eckey = wc_ecc_key_new(NULL); + /* Omit key->rng initialization because it seeds itself and thus + * consumes entropy that may never be used. Lazy initialize when + * necessary. */ + if (!key->eckey) { + wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed"); + crypto_ec_key_deinit(key); + key = NULL; + } + } + return key; +} + +void crypto_ec_key_deinit(struct crypto_ec_key *key) +{ + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_deinit starting"); + if (key) { + wc_rng_free(key->rng); + wc_ecc_key_free(key->eckey); + os_free(key); + } +} + +struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len) +{ + struct crypto_ec_key *ret = NULL; + word32 idx = 0; + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_parse_priv starting"); + + if (!der && der_len == 0) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + goto fail; + } + + ret = crypto_ec_key_init(); + if (!ret) { + wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed"); + goto fail; + } + + if (wc_EccPrivateKeyDecode(der, &idx, ret->eckey, (word32)der_len) != 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPrivateKeyDecode failed"); + goto fail; + } + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_parse_priv success"); + + return ret; +fail: + if (ret) + crypto_ec_key_deinit(ret); + return NULL; +} + +int crypto_ec_key_group(struct crypto_ec_key *key) +{ + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_group starting"); + + if (!key || !key->eckey || !key->eckey->dp) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + return -1; + } + + switch (key->eckey->dp->id) { + case ECC_SECP256R1: + return 19; + case ECC_SECP384R1: + return 20; + case ECC_SECP521R1: + return 21; + case ECC_BRAINPOOLP256R1: + return 28; + case ECC_BRAINPOOLP384R1: + return 29; + case ECC_BRAINPOOLP512R1: + return 30; + } + wpa_printf(MSG_ERROR, "wolfSSL: Unsupported curve (id=%d) in EC key", + key->eckey->dp->id); + return -1; +} + +struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) +{ + byte *der = NULL; + int derLen; + struct wpabuf *ret = NULL; + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_group starting"); + + if (!key || !key->eckey) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + goto fail; + } + + derLen = wc_EccPublicKeyDerSize(key->eckey, 1); + if (derLen <= 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDerSize failed"); + goto fail; + } + + der = os_malloc(derLen); + if (!der) { + wpa_printf(MSG_ERROR, "wolfSSL: os_malloc failed"); + goto fail; + } + + derLen = wc_EccPublicKeyToDer(key->eckey, der, derLen, 1); + if (derLen <= 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyToDer failed"); + goto fail; + } + + ret = wpabuf_alloc_copy(der, derLen); + os_free(der); + if (ret) + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_group success"); + else + wpa_printf(MSG_ERROR, "wolfSSL: wpabuf_alloc_copy failed"); + return ret; + +fail: + if (der) + os_free(der); + return NULL; +} + +struct crypto_ec_key * crypto_ec_key_parse_pub(const u8 *der, size_t der_len) +{ + word32 idx = 0; + struct crypto_ec_key *ret = NULL; + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_parse_pub starting"); + + if (!der || der_len == 0) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + goto fail; + } + + ret = crypto_ec_key_init(); + if (!ret) { + wpa_printf(MSG_ERROR, "wolfSSL: crypto_ec_key_init failed"); + goto fail; + } + + if (wc_EccPublicKeyDecode(der, &idx, ret->eckey, (word32)der_len) != 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDecode failed"); + goto fail; + } + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_parse_pub success"); + + return ret; +fail: + if (ret) + crypto_ec_key_deinit(ret); + return NULL; +} + + +struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, + size_t len) +{ + byte *der = NULL; + int derLen; + word32 w32DerLen; + struct wpabuf *ret = NULL; + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_sign starting"); + + if (!key || !key->eckey || !data || len == 0) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + goto fail; + } + + if (!key->rng) { + /* Lazy init key->rng */ + key->rng = wc_rng_new(NULL, 0, NULL); + if (!key->rng) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_rng_new failed"); + goto fail; + } + } + + derLen = wc_ecc_sig_size(key->eckey); + if (derLen <= 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sig_size failed"); + goto fail; + } + + der = os_malloc(derLen); + if (!der) { + wpa_printf(MSG_ERROR, "wolfSSL: os_malloc failed"); + goto fail; + } + + w32DerLen = (word32)derLen; + if (wc_ecc_sign_hash(data, len, der, &w32DerLen, key->rng, key->eckey) + != 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sign_hash failed"); + goto fail; + } + + ret = wpabuf_alloc_copy(der, derLen); + os_free(der); + if (ret) + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_sign success"); + else + wpa_printf(MSG_ERROR, "wolfSSL: wpabuf_alloc_copy failed"); + return ret; +fail: + if (der) + os_free(der); + return NULL; +} + + +int crypto_ec_key_verify_signature(struct crypto_ec_key *key, const u8 *data, + size_t len, const u8 *sig, size_t sig_len) +{ + int res = 0; + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_verify_signature starting"); + + if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) { + wpa_printf(MSG_ERROR, "wolfSSL: invalid input parameters"); + return -1; + } + + if (wc_ecc_verify_hash(sig, sig_len, data, len, &res, key->eckey) != 0) { + wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_verify_hash failed"); + return -1; + } + + wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_verify_signature %s", + res == 1 ? "success" : "failed"); + + return res; +} + #endif /* CONFIG_ECC */ diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py index 276a484436..c3061b43f4 100644 --- a/tests/hwsim/test_sae.py +++ b/tests/hwsim/test_sae.py @@ -2119,6 +2119,8 @@ def run_sae_pwe_group(dev, apdev, group): if group in [27, 28, 29, 30]: if tls.startswith("OpenSSL") and ("run=OpenSSL 1." in tls or "run=OpenSSL 3." in tls): logger.info("Add Brainpool EC groups since OpenSSL is new enough") + elif tls.startswith("wolfSSL"): + logger.info("Make sure Brainpool EC groups were enabled when compiling wolfSSL") else: raise HwsimSkip("Brainpool curve not supported") start_sae_pwe_ap(apdev[0], group, 2)