From: Andreas Steffen Date: Sun, 8 Dec 2024 19:24:06 +0000 (+0100) Subject: wolfssl: Add ML-DSA support X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=f923c4c3f8f17529d8addb8d019d41a776df2b75;p=thirdparty%2Fstrongswan.git wolfssl: Add ML-DSA support --- diff --git a/scripts/test.sh b/scripts/test.sh index b8627456a2..7910221251 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -55,7 +55,8 @@ build_wolfssl() --enable-curve25519 --enable-curve448 --enable-des3 --enable-ecccustcurves --enable-ed25519 --enable-ed448 --enable-keygen --enable-mlkem --with-max-rsa-bits=8192 - --enable-md4 --enable-rsapss --enable-sha3 --enable-shake256" + --enable-md4 --enable-rsapss --enable-sha3 --enable-shake256 + --enable-dilithium" git clone https://github.com/wolfSSL/wolfssl.git $WOLFSSL_DIR && cd $WOLFSSL_DIR && diff --git a/src/libstrongswan/plugins/wolfssl/Makefile.am b/src/libstrongswan/plugins/wolfssl/Makefile.am index a0fee2b491..56d350808d 100644 --- a/src/libstrongswan/plugins/wolfssl/Makefile.am +++ b/src/libstrongswan/plugins/wolfssl/Makefile.am @@ -22,6 +22,8 @@ libstrongswan_wolfssl_la_SOURCES = \ wolfssl_ec_public_key.h wolfssl_ec_public_key.c \ wolfssl_ed_private_key.h wolfssl_ed_private_key.c \ wolfssl_ed_public_key.h wolfssl_ed_public_key.c \ + wolfssl_ml_dsa_private_key.h wolfssl_ml_dsa_private_key.c \ + wolfssl_ml_dsa_public_key.h wolfssl_ml_dsa_public_key.c \ wolfssl_hasher.h wolfssl_hasher.c \ wolfssl_hmac.h wolfssl_hmac.c \ wolfssl_kdf.h wolfssl_kdf.c \ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.c new file mode 100644 index 0000000000..6bd72e884b --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.c @@ -0,0 +1,399 @@ +/* + * Copyright (C) 2024-2025 Andreas Steffen, strongSec GmbH + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "wolfssl_common.h" + +#if defined(HAVE_DILITHIUM) + +#include "wolfssl_ml_dsa_private_key.h" + +#include +#include +#include +#include +#include + +#include +#include + +typedef struct private_private_key_t private_private_key_t; + +/** + * Private data + */ +struct private_private_key_t { + + /** + * Public interface + */ + private_key_t public; + + /** + * Key object + */ + dilithium_key key; + + /** + * Key type + */ + key_type_t type; + + /** + * Secret key seed + */ + chunk_t keyseed; + + /** + * Reference count + */ + refcount_t ref; +}; + +/* from wolfss_ml_dsa_public_key.c */ +bool wolfssl_ml_dsa_enabled(key_type_t type, uint8_t *level); +bool wolfssl_ml_dsa_fingerprint(dilithium_key *key, key_type_t type, + cred_encoding_type_t enc_type, chunk_t *fp); + +METHOD(private_key_t, sign, bool, + private_private_key_t *this, signature_scheme_t scheme, + void *params, chunk_t data, chunk_t *signature) +{ + pqc_params_t pqc_params; + u_int sig_len; + int ret; + + if (key_type_from_signature_scheme(scheme) != this->type) + { + DBG1(DBG_LIB, "signature scheme %N not supported", + signature_scheme_names, scheme); + return FALSE; + } + + /* set PQC signature params */ + if (!pqc_params_create(params, &pqc_params)) + { + return FALSE; + } + + sig_len = wc_dilithium_sig_size(&this->key); + *signature = chunk_alloc(sig_len); + + /* deterministic or randomized signature? */ + if (pqc_params.deterministic) + { + uint8_t seed[DILITHIUM_RND_SZ]; + + memset(seed, 0x00, DILITHIUM_RND_SZ); + ret = wc_dilithium_sign_ctx_msg_with_seed(pqc_params.ctx.ptr, + pqc_params.ctx.len, data.ptr, data.len, + signature->ptr, &sig_len, &this->key, seed); + } + else + { + WC_RNG rng; + + if (wc_InitRng(&rng) != 0) + { + DBG1(DBG_LIB, "initializing random generator failed"); + pqc_params_free(&pqc_params); + return NULL; + } + ret = wc_dilithium_sign_ctx_msg(pqc_params.ctx.ptr, + pqc_params.ctx.len, data.ptr, data.len, + signature->ptr, &sig_len, &this->key, &rng); + wc_FreeRng(&rng); + } + pqc_params_free(&pqc_params); + + if (ret != 0) + { + chunk_free(signature); + return FALSE; + } + return TRUE; +} + +METHOD(private_key_t, decrypt, bool, + private_private_key_t *this, encryption_scheme_t scheme, + void *params, chunk_t crypto, chunk_t *plain) +{ + DBG1(DBG_LIB, "ML-DSA private key decryption not implemented"); + return FALSE; +} + +METHOD(private_key_t, get_keysize, int, + private_private_key_t *this) +{ + return BITS_PER_BYTE * get_public_key_size(this->type); +} + +METHOD(private_key_t, get_type, key_type_t, + private_private_key_t *this) +{ + return this->type; +} + +METHOD(private_key_t, get_public_key, public_key_t*, + private_private_key_t *this) +{ + public_key_t *public_key; + chunk_t pubkey; + int len; + + len = get_public_key_size(this->type); + pubkey = chunk_alloc(len); + + if (wc_dilithium_export_public(&this->key, pubkey.ptr, &len) != 0) + { + chunk_free(&pubkey); + return NULL; + } + + public_key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, this->type, + BUILD_BLOB, pubkey, BUILD_END); + chunk_free(&pubkey); + + return public_key; +} + +METHOD(private_key_t, get_fingerprint, bool, + private_private_key_t *this, cred_encoding_type_t type, chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + + success = wolfssl_ml_dsa_fingerprint(&this->key, this->type, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, fp); + } + + return success; +} + +METHOD(private_key_t, get_encoding, bool, + private_private_key_t *this, cred_encoding_type_t type, chunk_t *encoding) +{ + switch (type) + { + case PRIVKEY_ASN1_DER: + case PRIVKEY_PEM: + { + bool success = TRUE; + int oid = key_type_to_oid(this->type); + + *encoding = asn1_wrap(ASN1_SEQUENCE, "cmm", + ASN1_INTEGER_0, + asn1_algorithmIdentifier(oid), + asn1_wrap(ASN1_OCTET_STRING, "m", + asn1_simple_object(ASN1_CONTEXT_S_0, + this->keyseed)) + ); + if (type == PRIVKEY_PEM) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM, + NULL, encoding, CRED_PART_PRIV_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + + return success; + } + default: + return FALSE; + } +} + +METHOD(private_key_t, get_ref, private_key_t*, + private_private_key_t *this) +{ + ref_get(&this->ref); + return &this->public; +} + +METHOD(private_key_t, destroy, void, + private_private_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + wc_dilithium_free(&this->key); + chunk_clear(&this->keyseed); + free(this); + } +} + +/** + * Generic private constructor + */ +static private_private_key_t *create_instance(key_type_t type, uint8_t level, + chunk_t keyseed) +{ + private_private_key_t *this; + + INIT(this, + .public = { + .get_type = _get_type, + .sign = _sign, + .decrypt = _decrypt, + .get_keysize = _get_keysize, + .get_public_key = _get_public_key, + .equals = private_key_equals, + .belongs_to = private_key_belongs_to, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = private_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .type = type, + .keyseed = keyseed, + .ref = 1, + ); + + if (wc_dilithium_init(&this->key) != 0 || + wc_dilithium_set_level(&this->key, level) != 0) + { + destroy(this); + return NULL; + } + + /* derive private and public key from seed */ + if (wc_dilithium_make_key_from_seed(&this->key, keyseed.ptr) != 0) + { + DBG1(DBG_LIB, "deriving %N from seed failed", key_type_names, type); + destroy(this); + return NULL; + } + + return this; +} + +/* + * Described in header + */ +private_key_t *wolfssl_ml_dsa_private_key_gen(key_type_t type, va_list args) +{ + private_private_key_t *this; + WC_RNG rng; + chunk_t seed; + uint8_t level = 0; + int ret; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_KEY_SIZE: + /* just ignore the key size */ + va_arg(args, u_int); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (!wolfssl_ml_dsa_enabled(type, &level)) + { + return NULL; + } + + if (wc_InitRng(&rng) != 0) + { + DBG1(DBG_LIB, "initializing random generator failed"); + return NULL; + } + + seed = chunk_alloc(DILITHIUM_SEED_SZ); + ret = wc_RNG_GenerateBlock(&rng, seed.ptr, seed.len); + wc_FreeRng(&rng); + + if (ret != 0) + { + DBG1(DBG_LIB, "generating random seed failed"); + chunk_free(&seed); + return NULL; + } + + this = create_instance(type, level, seed); + if (!this) + { + return NULL; + } + + return &this->public; +} + +/* + * Described in header + */ +private_key_t *wolfssl_ml_dsa_private_key_load(key_type_t type, va_list args) +{ + private_private_key_t *this; + chunk_t priv = chunk_empty; + uint8_t level = 0; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB: + priv = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (priv.len == 0 || !wolfssl_ml_dsa_enabled(type, &level)) + { + return NULL; + } + + if (priv.len == DILITHIUM_SEED_SZ + 2 && + priv.ptr[0] == 0x80 && priv.ptr[1] == DILITHIUM_SEED_SZ) + { + priv = chunk_skip(priv, 2); + } +if (priv.len != DILITHIUM_SEED_SZ) + { + DBG1(DBG_LIB, "error: the size of the loaded ML-DSA private key seed " + "is %u bytes instead of %d bytes", priv.len, DILITHIUM_SEED_SZ); + + return NULL; + } + + this = create_instance(type, level, chunk_clone(priv)); + if (!this) + { + return NULL; + } + + return &this->public; +} +#endif /* HAVE_DILITHIUM */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.h new file mode 100644 index 0000000000..6f9ab1f069 --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_private_key.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 Andreas Steffen, strongSec GmbH + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup wolfssl_ml_dsa_private_key wolfssl_ml_dsa_private_key + * @{ @ingroup wolfssl_p + */ + +#ifndef WOLFSSL_PLUGIN_ML_DSA_PRIVATE_KEY_H_ +#define WOLFSSL_PLUGIN_ML_DSA_PRIVATE_KEY_H_ + +#include +#include + +/** + * Generate an ML-DSA private key using wolfSSL. + * + * @param type key type, must be KEY_ML_DSA_44, KEY_ML_DSA_65 or KEY_ML_DSA_87 + * @param args builder_part_t argument list + * @return generated key, NULL on failure + */ +private_key_t *wolfssl_ml_dsa_private_key_gen(key_type_t type, va_list args); + +/** + * Load an ML-DSA private key using wolfSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. + * + * @param type key type, must be KEY_ML_DSA_44, KEY_ML_DSA_65 or KEY_ML_DSA_87 + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +private_key_t *wolfssl_ml_dsa_private_key_load(key_type_t type, va_list args); + +#endif /** WOLFSSL_PLUGIN_ML_DSA_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c new file mode 100644 index 0000000000..dacdea0bf3 --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.c @@ -0,0 +1,341 @@ +/* + * Copyright (C) 2024 Andreas Steffen, strongSec GmbH + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "wolfssl_common.h" + +#if defined(HAVE_DILITHIUM) + +#include "wolfssl_ml_dsa_public_key.h" + +#include +#include +#include + +#include +#include + +typedef struct private_public_key_t private_public_key_t; + +/** + * Private data + */ +struct private_public_key_t { + + /** + * Public interface + */ + public_key_t public; + + /** + * Key object + */ + dilithium_key key; + + /** + * Key type + */ + key_type_t type; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(public_key_t, get_type, key_type_t, + private_public_key_t *this) +{ + return this->type; +} + +METHOD(public_key_t, verify, bool, + private_public_key_t *this, signature_scheme_t scheme, + void *params, chunk_t data, chunk_t signature) +{ + pqc_params_t pqc_params; + int ret, result; + + if (key_type_from_signature_scheme(scheme) != this->type) + { + DBG1(DBG_LIB, "signature scheme %N not supported", + signature_scheme_names, scheme); + return FALSE; + } + + /* set PQC signature params */ + if (!pqc_params_create(params, &pqc_params)) + { + return FALSE; + } + + ret = wc_dilithium_verify_ctx_msg(signature.ptr, signature.len, + pqc_params.ctx.ptr, pqc_params.ctx.len, + data.ptr, data.len, &result, &this->key); + pqc_params_free(&pqc_params); + + return (ret == 0) && (result == 1); +} + +METHOD(public_key_t, encrypt_, bool, + private_public_key_t *this, encryption_scheme_t scheme, + void *params, chunk_t crypto, chunk_t *plain) +{ + DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names, + scheme); + return FALSE; +} + +METHOD(public_key_t, get_keysize, int, + private_public_key_t *this) +{ + return BITS_PER_BYTE * get_public_key_size(this->type); +} + +/** + * Generate two types of ML-DSA fingerprints + */ +bool wolfssl_ml_dsa_fingerprint(dilithium_key *key, key_type_t type, + cred_encoding_type_t enc_type, chunk_t *fp) +{ + chunk_t pubkey = chunk_empty, encoding = chunk_empty; + hasher_t *hasher; + int len; + bool success = FALSE; + + *fp = chunk_empty; + len = get_public_key_size(type); + pubkey = chunk_alloc(len); + + if (wc_dilithium_export_public(key, pubkey.ptr, &len) != 0) + { + goto end; + } + + switch (enc_type) + { + case KEYID_PUBKEY_SHA1: + encoding = chunk_clone(pubkey); + break; + case KEYID_PUBKEY_INFO_SHA1: + encoding = public_key_info_encode(pubkey, key_type_to_oid(type)); + break; + default: + goto end; + } + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !hasher->allocate_hash(hasher, encoding, fp)) + { + DBG1(DBG_LIB, "SHA1 hash algorithm not supported"); + DESTROY_IF(hasher); + goto end; + } + hasher->destroy(hasher); + success = TRUE; + +end: + chunk_free(&pubkey); + chunk_free(&encoding); + + return success; +} + +METHOD(public_key_t, get_fingerprint, bool, + private_public_key_t *this, cred_encoding_type_t type, chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + + success = wolfssl_ml_dsa_fingerprint(&this->key, this->type, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, fp); + } + + return success; +} + + +METHOD(public_key_t, get_encoding, bool, + private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding) +{ + bool success = FALSE; + chunk_t pubkey; + int len, oid; + + len = get_public_key_size(this->type); + pubkey = chunk_alloc(len); + + if (wc_dilithium_export_public(&this->key, pubkey.ptr, &len) != 0) + { + *encoding = chunk_empty; + goto end; + } + + oid = key_type_to_oid(this->type); + *encoding = public_key_info_encode(pubkey, oid); + success = TRUE; + + if (type != PUBKEY_SPKI_ASN1_DER) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, type, + NULL, encoding, CRED_PART_PUB_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + +end: + chunk_free(&pubkey); + + return success; +} + +METHOD(public_key_t, get_ref, public_key_t*, + private_public_key_t *this) +{ + ref_get(&this->ref); + return &this->public; +} + +METHOD(public_key_t, destroy, void, + private_public_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + wc_dilithium_free(&this->key); + free(this); + } +} + +/** + * Checks if a given ML-DSA type is enabled and sets some parameters + */ +bool wolfssl_ml_dsa_enabled(key_type_t type, uint8_t *level) +{ + *level = 0; + + if (type == KEY_ML_DSA_44) + { +#ifndef WOLFSSL_NO_ML_DSA_44 + *level = WC_ML_DSA_44; +#endif + } + else if (type == KEY_ML_DSA_65) + { +#ifndef WOLFSSL_NO_ML_DSA_65 + *level = WC_ML_DSA_65; +#endif + } + else if (type == KEY_ML_DSA_87) + { +#ifndef WOLFSSL_NO_ML_DSA_87 + *level = WC_ML_DSA_87; +#endif + } + + return *level != 0; +} + +/** + * Generic private constructor + */ +static private_public_key_t *create_empty(key_type_t type, uint8_t level) +{ + private_public_key_t *this; + + INIT(this, + .public = { + .get_type = _get_type, + .verify = _verify, + .encrypt = _encrypt_, + .get_keysize = _get_keysize, + .equals = public_key_equals, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = public_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .type = type, + .ref = 1, + ); + + if (wc_dilithium_init(&this->key) != 0 || + (level && wc_dilithium_set_level(&this->key, level) != 0)) + { + free(this); + return NULL; + } + + return this; +} + +/* + * Described in header + */ +public_key_t *wolfssl_ml_dsa_public_key_load(key_type_t type, va_list args) +{ + private_public_key_t *this; + chunk_t pkcs1, blob = chunk_empty; + uint8_t level = 0; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB: + blob = va_arg(args, chunk_t); + continue; + case BUILD_BLOB_ASN1_DER: + pkcs1 = va_arg(args, chunk_t); + type = public_key_info_decode(pkcs1, &blob); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (!wolfssl_ml_dsa_enabled(type, &level) || blob.len == 0) + { + return NULL; + } + + this = create_empty(type, level); + if (!this) + { + return NULL; + } + + if (wc_dilithium_import_public(blob.ptr, blob.len, &this->key) != 0) + { + DBG1(DBG_LIB, "importing ML-DSA public key failed"); + destroy(this); + return NULL; + } + + return &this->public; +} +#endif /* HAVE_DILITHIUM */ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.h b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.h new file mode 100644 index 0000000000..c3f34dad5f --- /dev/null +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_ml_dsa_public_key.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2024 Andreas Steffen, strongSec GmbH + * + * Copyright (C) secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup wolfssl_ml_dsa_public_key wolfssl_ml_dsa_public_key + * @{ @ingroup wolfssl_p + */ + +#ifndef WOLFSSL_PLUGIN_ML_DSA_PUBLIC_KEY_H_ +#define WOLFSSL_PLUGIN_ML_DSA_PUBLIC_KEY_H_ + +#include +#include + +/** + * Load an ML-DSA public key using wolfSSL. + * + * Accepts a BUILD_BLOB_ASN1_DER argument. + * + * @param type key type, must be KEY_ML_DSA_44, KEY_ML_DSA_65 or KEY_ML_DSA_87 + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +public_key_t *wolfssl_ml_dsa_public_key_load(key_type_t type, va_list args); + +#endif /** WOLFSSL_PLUGIN_ML_DSA_PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c index c22ae36580..3d7948d676 100644 --- a/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c +++ b/src/libstrongswan/plugins/wolfssl/wolfssl_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Andreas Steffen, strongSec GmbH + * Copyright (C) 2021-2024 Andreas Steffen, strongSec GmbH * Copyright (C) 2019-2024 Tobias Brunner, codelabs GmbH * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc. * @@ -36,6 +36,8 @@ #include "wolfssl_ec_public_key.h" #include "wolfssl_ed_private_key.h" #include "wolfssl_ed_public_key.h" +#include "wolfssl_ml_dsa_private_key.h" +#include "wolfssl_ml_dsa_public_key.h" #include "wolfssl_hasher.h" #include "wolfssl_hmac.h" #include "wolfssl_kdf.h" @@ -507,6 +509,62 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(HASHER, return_null), PLUGIN_PROVIDE(HASHER, HASH_IDENTITY), #endif /* HAVE_ED25519 || HAVE_ED448 */ +#if defined(HAVE_DILITHIUM) + /* ML-DSA public key loading */ + PLUGIN_REGISTER(PUBKEY, wolfssl_ml_dsa_public_key_load, TRUE), + #ifndef WOLFSSL_NO_ML_DSA_44 + PLUGIN_PROVIDE(PUBKEY, KEY_ML_DSA_44), + #endif + #ifndef WOLFSSL_NO_ML_DSA_65 + PLUGIN_PROVIDE(PUBKEY, KEY_ML_DSA_65), + #endif + #ifndef WOLFSSL_NO_ML_DSA_87 + PLUGIN_PROVIDE(PUBKEY, KEY_ML_DSA_87), + #endif + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + /* ML-DSA private key loading */ + PLUGIN_REGISTER(PRIVKEY, wolfssl_ml_dsa_private_key_load, TRUE), + #ifndef WOLFSSL_NO_ML_DSA_44 + PLUGIN_PROVIDE(PRIVKEY, KEY_ML_DSA_44), + #endif + #ifndef WOLFSSL_NO_ML_DSA_65 + PLUGIN_PROVIDE(PRIVKEY, KEY_ML_DSA_65), + #endif + #ifndef WOLFSSL_NO_ML_DSA_87 + PLUGIN_PROVIDE(PRIVKEY, KEY_ML_DSA_87), + #endif + /* ML-DSA private key generation */ + PLUGIN_REGISTER(PRIVKEY_GEN, wolfssl_ml_dsa_private_key_gen, FALSE), + #ifndef WOLFSSL_NO_ML_DSA_44 + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ML_DSA_44), + #endif + #ifndef WOLFSSL_NO_ML_DSA_65 + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ML_DSA_65), + #endif + #ifndef WOLFSSL_NO_ML_DSA_87 + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ML_DSA_87), + #endif + /* ML-DSA signature schemes*/ + #ifndef WOLFSSL_NO_ML_DSA_44 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ML_DSA_44), + #endif + #ifndef WOLFSSL_NO_ML_DSA_65 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ML_DSA_65), + #endif + #ifndef WOLFSSL_NO_ML_DSA_87 + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ML_DSA_87), + #endif + /* ML-DSA signature verification schemes */ + #ifndef WOLFSSL_NO_ML_DSA_44 + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ML_DSA_44), + #endif + #ifndef WOLFSSL_NO_ML_DSA_65 + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ML_DSA_65), + #endif + #ifndef WOLFSSL_NO_ML_DSA_67 + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ML_DSA_87), + #endif +#endif /* HAVE_DILITHIUM */ #ifndef WC_NO_RNG /* generic key loader */ PLUGIN_REGISTER(RNG, wolfssl_rng_create),