wolfSSL: Implement crypto_ec_key wrappers
These are needed to support SAEK-PK with the wolfSSL backend. Signed-off-by: Juliusz Sosinowicz <juliusz@wolfssl.com>
This commit is contained in:
parent
1f7e10177a
commit
8f36e6c0f4
1 changed files with 258 additions and 0 deletions
|
@ -26,6 +26,7 @@
|
||||||
#include <wolfssl/wolfcrypt/dh.h>
|
#include <wolfssl/wolfcrypt/dh.h>
|
||||||
#include <wolfssl/wolfcrypt/cmac.h>
|
#include <wolfssl/wolfcrypt/cmac.h>
|
||||||
#include <wolfssl/wolfcrypt/ecc.h>
|
#include <wolfssl/wolfcrypt/ecc.h>
|
||||||
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||||
#include <wolfssl/openssl/bn.h>
|
#include <wolfssl/openssl/bn.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1835,6 +1836,263 @@ size_t crypto_ecdh_prime_len(struct crypto_ecdh *ecdh)
|
||||||
return crypto_ec_prime_len(ecdh->ec);
|
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;
|
||||||
|
|
||||||
|
key = os_zalloc(sizeof(struct crypto_ec_key));
|
||||||
|
if (key) {
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
key->eckey = os_zalloc(sizeof(ecc_key));
|
||||||
|
#else /* CONFIG_FIPS */
|
||||||
|
key->eckey = wc_ecc_key_new(NULL);
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
else if (wc_ecc_init_ex(key->eckey, NULL, INVALID_DEVID) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_init_ex failed");
|
||||||
|
crypto_ec_key_deinit(key);
|
||||||
|
key = NULL;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void crypto_ec_key_deinit(struct crypto_ec_key *key)
|
||||||
|
{
|
||||||
|
if (key) {
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
os_free(key->rng);
|
||||||
|
os_free(key->eckey);
|
||||||
|
#else /* CONFIG_FIPS */
|
||||||
|
wc_rng_free(key->rng);
|
||||||
|
wc_ecc_key_free(key->eckey);
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
os_free(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct crypto_ec_key * crypto_ec_key_parse_priv(const u8 *der, size_t der_len)
|
||||||
|
{
|
||||||
|
struct crypto_ec_key *ret;
|
||||||
|
word32 idx = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
fail:
|
||||||
|
if (ret)
|
||||||
|
crypto_ec_key_deinit(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int crypto_ec_key_group(struct crypto_ec_key *key)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!key || !key->eckey || !key->eckey->dp) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
|
||||||
|
__func__);
|
||||||
|
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 der_len;
|
||||||
|
struct wpabuf *ret = NULL;
|
||||||
|
|
||||||
|
if (!key || !key->eckey) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
|
||||||
|
__func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
der_len = wc_EccPublicKeyDerSize(key->eckey, 1);
|
||||||
|
if (der_len <= 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyDerSize failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
der = os_malloc(der_len);
|
||||||
|
if (!der)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
der_len = wc_EccPublicKeyToDer(key->eckey, der, der_len, 1);
|
||||||
|
if (der_len <= 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_EccPublicKeyToDer failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wpabuf_alloc_copy(der, der_len);
|
||||||
|
os_free(der);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
fail:
|
||||||
|
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 der_len;
|
||||||
|
word32 w32_der_len;
|
||||||
|
struct wpabuf *ret = NULL;
|
||||||
|
|
||||||
|
if (!key || !key->eckey || !data || len == 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
|
||||||
|
__func__);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key->rng) {
|
||||||
|
/* Lazy init key->rng */
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
key->rng = os_zalloc(sizeof(WC_RNG));
|
||||||
|
#else /* CONFIG_FIPS */
|
||||||
|
key->rng = wc_rng_new(NULL, 0, NULL);
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
if (!key->rng) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_rng_new failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_FIPS
|
||||||
|
if (wc_InitRng(key->rng) != 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_InitRng failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_FIPS */
|
||||||
|
}
|
||||||
|
|
||||||
|
der_len = wc_ecc_sig_size(key->eckey);
|
||||||
|
if (der_len <= 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sig_size failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
der = os_malloc(der_len);
|
||||||
|
if (!der)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
w32_der_len = (word32) der_len;
|
||||||
|
if (wc_ecc_sign_hash(data, len, der, &w32_der_len, key->rng, key->eckey)
|
||||||
|
!= 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_sign_hash failed");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = wpabuf_alloc_copy(der, der_len);
|
||||||
|
os_free(der);
|
||||||
|
if (!ret)
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: wpabuf_alloc_copy failed");
|
||||||
|
return ret;
|
||||||
|
fail:
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!key || !key->eckey || !data || len == 0 || !sig || sig_len == 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "wolfSSL: %s: invalid input parameters",
|
||||||
|
__func__);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res != 1)
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"wolfSSL: crypto_ec_key_verify_signature failed");
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_ECC */
|
#endif /* CONFIG_ECC */
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue