From: Tobias Brunner Date: Thu, 23 Apr 2020 08:39:55 +0000 (+0200) Subject: wolfssl: Add support for Ed448 X-Git-Tag: 5.9.0dr1~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=142b5e7944e67b4829ed7740ff89f610428d6ddd;p=thirdparty%2Fstrongswan.git wolfssl: Add support for Ed448 --- diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_common.h b/src/libstrongswan/plugins/wolfssl/wolfssl_common.h index ed4099d5a1..8145d152c7 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_common.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_common.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2020 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -60,6 +63,24 @@ #endif #include +/* Special type used to handle EdDSA keys depending on config options */ +#if defined(HAVE_ED25519) || defined(HAVE_ED448) +#ifdef HAVE_ED25519 +#include +#endif +#ifdef HAVE_ED448 +#include +#endif +typedef union { +#ifdef HAVE_ED25519 + ed25519_key ed25519; +#endif +#ifdef HAVE_ED448 + ed448_key ed448; +#endif +} wolfssl_ed_key; +#endif /* HAVE_ED25519 || HAVE_ED448 */ + #undef PARSE_ERROR #undef ASN1_BOOLEAN diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c index ed61b4b79b..2b6b743086 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2020 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,13 +25,12 @@ #include "wolfssl_common.h" -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) || defined(HAVE_ED448) #include "wolfssl_ed_private_key.h" #include -#include #include typedef struct private_private_key_t private_private_key_t; @@ -46,7 +48,12 @@ struct private_private_key_t { /** * Key object */ - ed25519_key key; + wolfssl_ed_key key; + + /** + * Key type + */ + key_type_t type; /** * Reference count @@ -55,8 +62,12 @@ struct private_private_key_t { }; /* from ed public key */ -bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type, - chunk_t *fp); +int wolfssl_ed_keysize(key_type_t type); +bool wolfssl_ed_create(wolfssl_ed_key *key, key_type_t type); +void wolfssl_ed_destroy(wolfssl_ed_key *key, key_type_t type); +bool wolfssl_ed_public_key(wolfssl_ed_key *key, key_type_t type, chunk_t *raw); +bool wolfssl_ed_fingerprint(wolfssl_ed_key *key, key_type_t key_type, + cred_encoding_type_t type, chunk_t *fp); METHOD(private_key_t, sign, bool, private_private_key_t *this, signature_scheme_t scheme, @@ -64,12 +75,13 @@ METHOD(private_key_t, sign, bool, { word32 len; byte dummy[1]; - int ret; + int ret = -1; - if (scheme != SIGN_ED25519) + if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) || + (this->type == KEY_ED448 && scheme != SIGN_ED448)) { DBG1(DBG_LIB, "signature scheme %N not supported by %N key", - signature_scheme_names, scheme, key_type_names, KEY_ED25519); + signature_scheme_names, scheme, key_type_names, this->type); return FALSE; } @@ -78,10 +90,24 @@ METHOD(private_key_t, sign, bool, data.ptr = dummy; } - len = ED25519_SIG_SIZE; - *signature = chunk_alloc(len); - ret = wc_ed25519_sign_msg(data.ptr, data.len, signature->ptr, &len, - &this->key); + if (this->type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + len = ED25519_SIG_SIZE; + *signature = chunk_alloc(len); + ret = wc_ed25519_sign_msg(data.ptr, data.len, signature->ptr, &len, + &this->key.ed25519); +#endif + } + else if (this->type == KEY_ED448) + { +#ifdef HAVE_ED448 + len = ED448_SIG_SIZE; + *signature = chunk_alloc(len); + ret = wc_ed448_sign_msg(data.ptr, data.len, signature->ptr, &len, + &this->key.ed448, NULL, 0); +#endif + } return ret == 0; } @@ -96,13 +122,13 @@ METHOD(private_key_t, decrypt, bool, METHOD(private_key_t, get_keysize, int, private_private_key_t *this) { - return ED25519_KEY_SIZE * 8; + return wolfssl_ed_keysize(this->type); } METHOD(private_key_t, get_type, key_type_t, private_private_key_t *this) { - return KEY_ED25519; + return this->type; } METHOD(private_key_t, get_public_key, public_key_t*, @@ -110,15 +136,14 @@ METHOD(private_key_t, get_public_key, public_key_t*, { public_key_t *public; chunk_t key; - word32 len = ED25519_PUB_KEY_SIZE; - key = chunk_alloca(len); - if (wc_ed25519_export_public(&this->key, key.ptr, &len) != 0) + if (!wolfssl_ed_public_key(&this->key, this->type, &key)) { return NULL; } - public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ED25519, + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type, BUILD_EDDSA_PUB, key, BUILD_END); + chunk_free(&key); return public; } @@ -126,13 +151,13 @@ METHOD(private_key_t, get_fingerprint, bool, private_private_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint) { - return wolfssl_ed_fingerprint(&this->key, type, fingerprint); + return wolfssl_ed_fingerprint(&this->key, this->type, type, fingerprint); } METHOD(private_key_t, get_encoding, bool, private_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) { - int ret; + int ret = -1; switch (type) { @@ -142,10 +167,25 @@ METHOD(private_key_t, get_encoding, bool, bool success = TRUE; /* +4 is for the two octet strings */ - *encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 2 * MAX_SEQ_SZ + - MAX_VERSION_SZ + MAX_ALGO_SZ + 4); - ret = wc_Ed25519PrivateKeyToDer(&this->key, encoding->ptr, - encoding->len); + *encoding = chunk_empty; + if (this->type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + *encoding = chunk_alloc(ED25519_PRV_KEY_SIZE + 2 * MAX_SEQ_SZ + + MAX_VERSION_SZ + MAX_ALGO_SZ + 4); + ret = wc_Ed25519PrivateKeyToDer(&this->key.ed25519, + encoding->ptr, encoding->len); +#endif + } + else if (this->type == KEY_ED448) + { +#ifdef HAVE_ED448 + *encoding = chunk_alloc(ED448_PRV_KEY_SIZE + 2 * MAX_SEQ_SZ + + MAX_VERSION_SZ + MAX_ALGO_SZ + 4); + ret = wc_Ed448PrivateKeyToDer(&this->key.ed448, encoding->ptr, + encoding->len); +#endif + } if (ret < 0) { chunk_free(encoding); @@ -182,7 +222,7 @@ METHOD(private_key_t, destroy, void, if (ref_put(&this->ref)) { lib->encoding->clear_cache(lib->encoding, &this->key); - wc_ed25519_free(&this->key); + wolfssl_ed_destroy(&this->key, this->type); free(this); } } @@ -190,7 +230,7 @@ METHOD(private_key_t, destroy, void, /** * Internal generic constructor */ -static private_private_key_t *create_internal() +static private_private_key_t *create_internal(key_type_t type) { private_private_key_t *this; @@ -209,10 +249,11 @@ static private_private_key_t *create_internal() .get_ref = _get_ref, .destroy = _destroy, }, + .type = type, .ref = 1, ); - if (wc_ed25519_init(&this->key) != 0) + if (!wolfssl_ed_create(&this->key, type)) { free(this); this = NULL; @@ -227,7 +268,7 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args) { private_private_key_t *this; WC_RNG rng; - int ret; + int ret = -1; while (TRUE) { @@ -245,7 +286,7 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args) break; } - this = create_internal(); + this = create_internal(type); if (!this) { return NULL; @@ -257,7 +298,19 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args) destroy(this); return NULL; } - ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &this->key); + + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &this->key.ed25519); +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &this->key.ed448); +#endif + } wc_FreeRng(&rng); if (ret < 0) @@ -276,17 +329,39 @@ static int set_public_key(private_private_key_t *this) { int ret = 0; - if (!this->key.pubKeySet) + if (this->type == KEY_ED25519) { - ret = wc_ed25519_make_public(&this->key, this->key.p, - ED25519_PUB_KEY_SIZE); - if (ret == 0) +#ifdef HAVE_ED25519 + if (!this->key.ed25519.pubKeySet) { - /* put public key after private key in the same buffer */ - memmove(this->key.k + ED25519_KEY_SIZE, this->key.p, - ED25519_PUB_KEY_SIZE); - this->key.pubKeySet = 1; + ret = wc_ed25519_make_public(&this->key.ed25519, + this->key.ed25519.p, ED25519_PUB_KEY_SIZE); + if (ret == 0) + { + /* put public key after private key in the same buffer */ + memmove(this->key.ed25519.k + ED25519_KEY_SIZE, + this->key.ed25519.p, ED25519_PUB_KEY_SIZE); + this->key.ed25519.pubKeySet = 1; + } + } +#endif + } + else if (this->type == KEY_ED448) + { +#ifdef HAVE_ED448 + if (!this->key.ed448.pubKeySet) + { + ret = wc_ed448_make_public(&this->key.ed448, this->key.ed448.p, + ED448_PUB_KEY_SIZE); + if (ret == 0) + { + /* put public key after private key in the same buffer */ + memmove(this->key.ed448.k + ED448_KEY_SIZE, + this->key.ed448.p, ED448_PUB_KEY_SIZE); + this->key.ed448.pubKeySet = 1; + } } +#endif } return ret; } @@ -318,27 +393,55 @@ private_key_t *wolfssl_ed_private_key_load(key_type_t type, va_list args) } break; } - this = create_internal(); + this = create_internal(type); if (!this) { return NULL; } - if (priv.len) + if (type == KEY_ED25519) { - /* check for ASN.1 wrapped key (Octet String == 0x04) */ - if (priv.len == ED25519_KEY_SIZE + 2 && priv.ptr[0] == 0x04 && - priv.ptr[1] == ED25519_KEY_SIZE) +#ifdef HAVE_ED25519 + if (priv.len) + { /* check for ASN.1 wrapped key (Octet String == 0x04) */ + if (priv.len == ED25519_KEY_SIZE + 2 && + priv.ptr[0] == 0x04 && priv.ptr[1] == ED25519_KEY_SIZE) + { + priv = chunk_skip(priv, 2); + } + ret = wc_ed25519_import_private_only(priv.ptr, priv.len, + &this->key.ed25519); + } + else if (blob.len) { - priv = chunk_skip(priv, 2); + idx = 0; + ret = wc_Ed25519PrivateKeyDecode(blob.ptr, &idx, &this->key.ed25519, + blob.len); } - ret = wc_ed25519_import_private_only(priv.ptr, priv.len, &this->key); +#endif } - else if (blob.len) + else if (type == KEY_ED448) { - idx = 0; - ret = wc_Ed25519PrivateKeyDecode(blob.ptr, &idx, &this->key, blob.len); +#ifdef HAVE_ED448 + if (priv.len) + { /* check for ASN.1 wrapped key (Octet String == 0x04) */ + if (priv.len == ED448_KEY_SIZE + 2 && + priv.ptr[0] == 0x04 && priv.ptr[1] == ED448_KEY_SIZE) + { + priv = chunk_skip(priv, 2); + } + ret = wc_ed448_import_private_only(priv.ptr, priv.len, + &this->key.ed448); + } + else if (blob.len) + { + idx = 0; + ret = wc_Ed448PrivateKeyDecode(blob.ptr, &idx, &this->key.ed448, + blob.len); + } +#endif } + if (ret == 0) { ret = set_public_key(this); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.h index 72802dcecb..f1fb622e63 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_private_key.h @@ -34,7 +34,7 @@ /** * Generate an EdDSA private key using wolfSSL. * - * @param type type of the key, must be KEY_ED25519 + * @param type type of the key, must be KEY_ED25519 or KEY_ED448 * @param args builder_part_t argument list * @return generated key, NULL on failure */ @@ -45,7 +45,7 @@ private_key_t *wolfssl_ed_private_key_gen(key_type_t type, va_list args); * * Accepts a BUILD_BLOB_ASN1_DER argument. * - * @param type type of the key, must be KEY_ED25519 + * @param type type of the key, must be KEY_ED25519 or KEY_ED448 * @param args builder_part_t argument list * @return loaded key, NULL on failure */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c index 879dfa73fb..9a5bec19e5 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2020 Tobias Brunner + * HSR Hochschule fuer Technik Rapperswil + * * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -22,14 +25,20 @@ #include "wolfssl_common.h" -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) || defined(HAVE_ED448) #include "wolfssl_ed_public_key.h" #include #include +#ifdef HAVE_ED25519 #include +#endif +#ifdef HAVE_ED448 +#include +#endif + #include typedef struct private_public_key_t private_public_key_t; @@ -47,7 +56,12 @@ struct private_public_key_t { /** * Key object */ - ed25519_key key; + wolfssl_ed_key key; + + /** + * Key type + */ + key_type_t type; /** * Reference count @@ -58,7 +72,7 @@ struct private_public_key_t { METHOD(public_key_t, get_type, key_type_t, private_public_key_t *this) { - return KEY_ED25519; + return this->type; } METHOD(public_key_t, verify, bool, @@ -66,12 +80,13 @@ METHOD(public_key_t, verify, bool, void *params, chunk_t data, chunk_t signature) { byte dummy[1]; - int ret, res; + int ret = -1, res = 0; - if (scheme != SIGN_ED25519) + if ((this->type == KEY_ED25519 && scheme != SIGN_ED25519) || + (this->type == KEY_ED448 && scheme != SIGN_ED448)) { DBG1(DBG_LIB, "signature scheme %N not supported by %N key", - signature_scheme_names, scheme, key_type_names, KEY_ED25519); + signature_scheme_names, scheme, key_type_names, this->type); return FALSE; } @@ -80,8 +95,20 @@ METHOD(public_key_t, verify, bool, data.ptr = dummy; } - ret = wc_ed25519_verify_msg(signature.ptr, signature.len, data.ptr, - data.len, &res, &this->key); + if (this->type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + ret = wc_ed25519_verify_msg(signature.ptr, signature.len, data.ptr, + data.len, &res, &this->key.ed25519); +#endif + } + else if (this->type == KEY_ED448) + { +#ifdef HAVE_ED448 + ret = wc_ed448_verify_msg(signature.ptr, signature.len, data.ptr, + data.len, &res, &this->key.ed448, NULL, 0); +#endif + } return ret == 0 && res == 1; } @@ -94,23 +121,59 @@ METHOD(public_key_t, encrypt, bool, return FALSE; } +/** + * Returns the key size in bytes for the given type, also used in private key. + */ +int wolfssl_ed_keysize(key_type_t type) +{ + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + return ED25519_KEY_SIZE * 8; +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + return ED448_KEY_SIZE * 8; +#endif + } + return 0; +} + METHOD(public_key_t, get_keysize, int, private_public_key_t *this) { - return ED25519_KEY_SIZE * 8; + return wolfssl_ed_keysize(this->type); } /** * Encode the given public key as ASN.1 DER with algorithm identifier */ -static bool encode_pubkey(ed25519_key *key, chunk_t *encoding) +static bool encode_pubkey(wolfssl_ed_key *key, key_type_t type, + chunk_t *encoding) { - int ret; + int ret = -1; /* account for algorithmIdentifier/bitString */ - *encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ + - MAX_ALGO_SZ + TRAILING_ZERO); - ret = wc_Ed25519PublicKeyToDer(key, encoding->ptr, encoding->len, 1); + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + *encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ + + MAX_ALGO_SZ + TRAILING_ZERO); + ret = wc_Ed25519PublicKeyToDer(&key->ed25519, encoding->ptr, + encoding->len, 1); +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + *encoding = chunk_alloc(ED448_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ + + MAX_ALGO_SZ + TRAILING_ZERO); + ret = wc_Ed448PublicKeyToDer(&key->ed448, encoding->ptr, + encoding->len, 1); +#endif + } if (ret < 0) { return FALSE; @@ -119,15 +182,49 @@ static bool encode_pubkey(ed25519_key *key, chunk_t *encoding) return TRUE; } +/** + * Export the raw public key of the given key, also used in ed private key. + */ +bool wolfssl_ed_public_key(wolfssl_ed_key *key, key_type_t type, chunk_t *raw) +{ + word32 len; + + *raw = chunk_empty; + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + len = ED25519_PUB_KEY_SIZE; + *raw = chunk_alloc(len); + if (wc_ed25519_export_public(&key->ed25519, raw->ptr, &len) != 0) + { + chunk_free(raw); + return FALSE; + } +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + len = ED448_PUB_KEY_SIZE; + *raw = chunk_alloc(len); + if (wc_ed448_export_public(&key->ed448, raw->ptr, &len) != 0) + { + chunk_free(raw); + return FALSE; + } +#endif + } + return TRUE; +} + /** * Calculate fingerprint from an EdDSA key, also used in ed private key. */ -bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type, - chunk_t *fp) +bool wolfssl_ed_fingerprint(wolfssl_ed_key *key, key_type_t key_type, + cred_encoding_type_t type, chunk_t *fp) { hasher_t *hasher; chunk_t blob; - word32 len; bool success = FALSE; if (lib->encoding->get_cache(lib->encoding, type, key, fp)) @@ -137,15 +234,13 @@ bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type, switch (type) { case KEYID_PUBKEY_SHA1: - len = ED25519_PUB_KEY_SIZE; - blob = chunk_alloc(len); - if (wc_ed25519_export_public(key, blob.ptr, &len) != 0) + if (!wolfssl_ed_public_key(key, key_type, &blob)) { return FALSE; } break; case KEYID_PUBKEY_INFO_SHA1: - if (!encode_pubkey(key, &blob)) + if (!encode_pubkey(key, key_type, &blob)) { return FALSE; } @@ -171,7 +266,7 @@ bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type, METHOD(public_key_t, get_fingerprint, bool, private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint) { - return wolfssl_ed_fingerprint(&this->key, type, fingerprint); + return wolfssl_ed_fingerprint(&this->key, this->type, type, fingerprint); } METHOD(public_key_t, get_encoding, bool, @@ -179,7 +274,7 @@ METHOD(public_key_t, get_encoding, bool, { bool success = TRUE; - if (!encode_pubkey(&this->key, encoding)) + if (!encode_pubkey(&this->key, this->type, encoding)) { return FALSE; } @@ -203,21 +298,70 @@ METHOD(public_key_t, get_ref, public_key_t*, return &this->public; } +/** + * Destroy an EdDSA key of the given type, also used by ed private key. + */ +void wolfssl_ed_destroy(wolfssl_ed_key *key, key_type_t type) +{ + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + wc_ed25519_free(&key->ed25519); +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + wc_ed448_free(&key->ed448); +#endif + } +} + METHOD(public_key_t, destroy, void, private_public_key_t *this) { if (ref_put(&this->ref)) { lib->encoding->clear_cache(lib->encoding, &this->key); - wc_ed25519_free(&this->key); + wolfssl_ed_destroy(&this->key, this->type); free(this); } } +/** + * Initialized an EdDSA key of the given type, also used by ed private key. + */ +bool wolfssl_ed_create(wolfssl_ed_key *key, key_type_t type) +{ + if (type == KEY_ED25519) + { +#ifdef HAVE_ED25519 + if (wc_ed25519_init(&key->ed25519) != 0) + { + return FALSE; + } +#endif + } + else if (type == KEY_ED448) + { +#ifdef HAVE_ED448 + if (wc_ed448_init(&key->ed448) != 0) + { + return FALSE; + } +#endif + } + else + { + return FALSE; + } + return TRUE; +} + /** * Generic private constructor */ -static private_public_key_t *create_empty() +static private_public_key_t *create_empty(key_type_t type) { private_public_key_t *this; @@ -234,13 +378,14 @@ static private_public_key_t *create_empty() .get_ref = _get_ref, .destroy = _destroy, }, + .type = type, .ref = 1, ); - if (wc_ed25519_init(&this->key) != 0) + if (!wolfssl_ed_create(&this->key, type)) { free(this); - return NULL; + this = NULL; } return this; } @@ -273,21 +418,44 @@ public_key_t *wolfssl_ed_public_key_load(key_type_t type, va_list args) break; } - this = create_empty(); + this = create_empty(type); if (!this) { return NULL; } - if (pub.len) + if (type == KEY_ED25519) { - ret = wc_ed25519_import_public(pub.ptr, pub.len, &this->key); +#ifdef HAVE_ED25519 + if (pub.len) + { + ret = wc_ed25519_import_public(pub.ptr, pub.len, + &this->key.ed25519); + } + else if (blob.len) + { + idx = 0; + ret = wc_Ed25519PublicKeyDecode(blob.ptr, &idx, &this->key.ed25519, + blob.len); + } +#endif } - else if (blob.len) + else if (type == KEY_ED448) { - idx = 0; - ret = wc_Ed25519PublicKeyDecode(blob.ptr, &idx, &this->key, blob.len); +#ifdef HAVE_ED448 + if (pub.len) + { + ret = wc_ed448_import_public(pub.ptr, pub.len, &this->key.ed448); + } + else if (blob.len) + { + idx = 0; + ret = wc_Ed448PublicKeyDecode(blob.ptr, &idx, &this->key.ed448, + blob.len); + } +#endif } + if (ret != 0) { destroy(this); diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.h index 4b3be1cf5f..c260b94a5b 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.h +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.h @@ -36,7 +36,7 @@ * * Accepts a BUILD_BLOB_ASN1_DER argument. * - * @param type type of the key, must be KEY_ED25519 + * @param type type of the key, must be KEY_ED25519 or KEY_ED448 * @param args builder_part_t argument list * @return loaded key, NULL on failure */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index d692136396..4de89e54c6 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -386,24 +386,45 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(DH, CURVE_448), #endif #endif /* HAVE_CURVE25519 || HAVE_CURVE448 */ -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) || defined(HAVE_ED448) /* EdDSA private/public key loading */ PLUGIN_REGISTER(PUBKEY, wolfssl_ed_public_key_load, TRUE), + #ifdef HAVE_ED25519 PLUGIN_PROVIDE(PUBKEY, KEY_ED25519), + #endif + #ifdef HAVE_ED448 + PLUGIN_PROVIDE(PUBKEY, KEY_ED448), + #endif PLUGIN_REGISTER(PRIVKEY, wolfssl_ed_private_key_load, TRUE), + #ifdef HAVE_ED25519 PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519), + #endif + #ifdef HAVE_ED448 + PLUGIN_PROVIDE(PRIVKEY, KEY_ED448), + #endif PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_ed_private_key_gen, FALSE), + #ifdef HAVE_ED25519 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519), + #endif + #ifdef HAVE_ED448 + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED448), + #endif #ifdef HAVE_ED25519_SIGN PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519), #endif #ifdef HAVE_ED25519_VERIFY PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519), + #endif + #ifdef HAVE_ED448_SIGN + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED448), + #endif + #ifdef HAVE_ED448_VERIFY + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED448), #endif /* register a pro forma identity hasher, never instantiated */ PLUGIN_REGISTER(HASHER, return_null), PLUGIN_PROVIDE(HASHER, HASH_IDENTITY), -#endif /* HAVE_ED25519 */ +#endif /* HAVE_ED25519 || HAVE_ED448 */ #ifndef WC_NO_RNG /* generic key loader */ PLUGIN_REGISTER(RNG, wolfssl_rng_create), diff --git a/src/libstrongswan/tests/suites/test_ed448.c b/src/libstrongswan/tests/suites/test_ed448.c index 288da19a06..6505731554 100644 --- a/src/libstrongswan/tests/suites/test_ed448.c +++ b/src/libstrongswan/tests/suites/test_ed448.c @@ -602,10 +602,11 @@ START_TEST(test_ed448_fail) "signatures"); } - /* malformed signature */ + /* malformed signature (most significant 10 bits should always be zero) */ sig = chunk_from_thing(sig1); memcpy(sig1, sig_tests[0].sig.ptr, sig_tests[0].sig.len); - sig1[113] |= 0xFF; + sig1[112] |= 0xc0; + sig1[113] |= 0xff; ck_assert(!pubkey->verify(pubkey, SIGN_ED448, NULL, sig_tests[0].msg, sig));