diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipcpd/ipcp.c | 2 | ||||
| -rw-r--r-- | src/irmd/config.h.in | 3 | ||||
| -rw-r--r-- | src/irmd/oap/io.c | 2 | ||||
| -rw-r--r-- | src/irmd/oap/tests/CMakeLists.txt | 24 | ||||
| -rw-r--r-- | src/irmd/oap/tests/oap_test.c | 4 | ||||
| -rw-r--r-- | src/irmd/oap/tests/oap_test_ml_dsa.c (renamed from src/irmd/oap/tests/oap_test_pqc.c) | 10 | ||||
| -rw-r--r-- | src/lib/config.h.in | 4 | ||||
| -rw-r--r-- | src/lib/crypt.c | 2 | ||||
| -rw-r--r-- | src/lib/tests/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | src/lib/tests/auth_test.c | 2 | ||||
| -rw-r--r-- | src/lib/tests/auth_test_ml_dsa.c (renamed from src/lib/tests/auth_test_pqc.c) | 10 | ||||
| -rw-r--r-- | src/lib/tests/auth_test_slh_dsa.c | 367 | ||||
| -rw-r--r-- | src/lib/tests/kex_test.c | 6 | ||||
| -rw-r--r-- | src/lib/tests/kex_test_ml_kem.c (renamed from src/lib/tests/kex_test_pqc.c) | 6 |
14 files changed, 409 insertions, 38 deletions
diff --git a/src/ipcpd/ipcp.c b/src/ipcpd/ipcp.c index 3ea77da9..c5a5174d 100644 --- a/src/ipcpd/ipcp.c +++ b/src/ipcpd/ipcp.c @@ -208,7 +208,7 @@ static int ipcp_rib_read(const char * path, char * buf, size_t len) { - char * entry; + const char * entry; if (len < LAYER_NAME_SIZE + 2) /* trailing \n */ return 0; diff --git a/src/irmd/config.h.in b/src/irmd/config.h.in index e1072193..6cbfc11f 100644 --- a/src/irmd/config.h.in +++ b/src/irmd/config.h.in @@ -78,7 +78,8 @@ #cmakedefine HAVE_LIBGCRYPT #cmakedefine HAVE_OPENSSL #ifdef HAVE_OPENSSL -#cmakedefine HAVE_OPENSSL_PQC +#cmakedefine HAVE_OPENSSL_ML_KEM +#cmakedefine HAVE_OPENSSL_ML_DSA #endif #define IRMD_SECMEM_MAX @IRMD_SECMEM_MAX@ #ifdef CONFIG_OUROBOROS_DEBUG diff --git a/src/irmd/oap/io.c b/src/irmd/oap/io.c index 8f75a8d8..c8d26147 100644 --- a/src/irmd/oap/io.c +++ b/src/irmd/oap/io.c @@ -118,7 +118,7 @@ int load_kex_config(const char * name, log_info("Key exchange not configured for %s.", name); return 0; } -#ifndef HAVE_OPENSSL_PQC +#ifndef HAVE_OPENSSL_ML_KEM if (IS_KEM_ALGORITHM(cfg->x.str)) { log_err("PQC not available, can't use %s for %s.", cfg->x.str, name); diff --git a/src/irmd/oap/tests/CMakeLists.txt b/src/irmd/oap/tests/CMakeLists.txt index 2bf23821..b534cb72 100644 --- a/src/irmd/oap/tests/CMakeLists.txt +++ b/src/irmd/oap/tests/CMakeLists.txt @@ -13,9 +13,9 @@ create_test_sourcelist(${PARENT_DIR}_tests test_suite.c oap_test.c ) -create_test_sourcelist(${PARENT_DIR}_pqc_tests test_suite_pqc.c - # PQC-specific tests - oap_test_pqc.c +create_test_sourcelist(${PARENT_DIR}_ml_dsa_tests test_suite_ml_dsa.c + # ML-DSA-specific tests + oap_test_ml_dsa.c ) # OAP test needs io.c compiled with OAP_TEST_MODE @@ -41,24 +41,24 @@ target_include_directories(${PARENT_DIR}_test PRIVATE ${IRMD_BINARY_DIR} ) -# PQC test executable (ML-DSA) -add_executable(${PARENT_DIR}_pqc_test ${${PARENT_DIR}_pqc_tests} ${OAP_TEST_SOURCES}) +# ML-DSA test executable +add_executable(${PARENT_DIR}_ml_dsa_test ${${PARENT_DIR}_ml_dsa_tests} ${OAP_TEST_SOURCES}) set_source_files_properties(${OAP_TEST_SOURCES} - TARGET_DIRECTORY ${PARENT_DIR}_pqc_test + TARGET_DIRECTORY ${PARENT_DIR}_ml_dsa_test PROPERTIES COMPILE_DEFINITIONS "OAP_TEST_MODE" ) -disable_test_logging_for_target(${PARENT_DIR}_pqc_test) -target_link_libraries(${PARENT_DIR}_pqc_test ouroboros-irm) -target_include_directories(${PARENT_DIR}_pqc_test PRIVATE +disable_test_logging_for_target(${PARENT_DIR}_ml_dsa_test) +target_link_libraries(${PARENT_DIR}_ml_dsa_test ouroboros-irm) +target_include_directories(${PARENT_DIR}_ml_dsa_test PRIVATE ${IRMD_SOURCE_DIR} ${IRMD_BINARY_DIR} ) -add_dependencies(build_tests ${PARENT_DIR}_test ${PARENT_DIR}_pqc_test) +add_dependencies(build_tests ${PARENT_DIR}_test ${PARENT_DIR}_ml_dsa_test) # Regular tests ouroboros_register_tests(TARGET ${PARENT_DIR}_test TESTS ${${PARENT_DIR}_tests}) -# PQC tests -ouroboros_register_tests(TARGET ${PARENT_DIR}_pqc_test TESTS ${${PARENT_DIR}_pqc_tests}) +# ML-DSA tests +ouroboros_register_tests(TARGET ${PARENT_DIR}_ml_dsa_test TESTS ${${PARENT_DIR}_ml_dsa_tests}) diff --git a/src/irmd/oap/tests/oap_test.c b/src/irmd/oap/tests/oap_test.c index fc78ed9a..169cfc14 100644 --- a/src/irmd/oap/tests/oap_test.c +++ b/src/irmd/oap/tests/oap_test.c @@ -38,7 +38,7 @@ #include <ouroboros/time.h> #include <test/test.h> -#include <test/certs.h> +#include <test/certs/ecdsa.h> #include "oap.h" #include "common.h" @@ -526,7 +526,7 @@ static int test_oap_roundtrip_all(void) for (i = 0; kex_supported_nids[i] != NID_undef; i++) { const char * algo = kex_nid_to_str(kex_supported_nids[i]); - /* Skip KEM algorithms - they're tested in oap_test_pqc */ + /* Skip KEM algorithms - tested in oap_test_ml_dsa */ if (IS_KEM_ALGORITHM(algo)) continue; diff --git a/src/irmd/oap/tests/oap_test_pqc.c b/src/irmd/oap/tests/oap_test_ml_dsa.c index bbaf9f7b..f9e6bdb2 100644 --- a/src/irmd/oap/tests/oap_test_pqc.c +++ b/src/irmd/oap/tests/oap_test_ml_dsa.c @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2026 * - * Unit tests of OAP post-quantum key exchange + * Unit tests of OAP ML-KEM/ML-DSA key exchange * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -34,7 +34,7 @@ #include <ouroboros/random.h> #include <test/test.h> -#include <test/certs_pqc.h> +#include <test/certs/ml_dsa.h> #include "oap.h" #include "common.h" @@ -412,15 +412,15 @@ static int test_oap_kem_srv_uncfg_all(void) return ret; } -int oap_test_pqc(int argc, - char **argv) +int oap_test_ml_dsa(int argc, + char **argv) { int ret = 0; (void) argc; (void) argv; -#ifdef HAVE_OPENSSL_PQC +#ifdef HAVE_OPENSSL_ML_KEM ret |= test_oap_roundtrip_auth_only(); ret |= test_oap_roundtrip_kem_all(); diff --git a/src/lib/config.h.in b/src/lib/config.h.in index 6065ac41..2c3afc80 100644 --- a/src/lib/config.h.in +++ b/src/lib/config.h.in @@ -25,7 +25,9 @@ #cmakedefine HAVE_LIBGCRYPT #cmakedefine HAVE_OPENSSL #ifdef HAVE_OPENSSL -#cmakedefine HAVE_OPENSSL_PQC +#cmakedefine HAVE_OPENSSL_ML_KEM +#cmakedefine HAVE_OPENSSL_ML_DSA +#cmakedefine HAVE_OPENSSL_SLH_DSA #define HAVE_ENCRYPTION #define SECMEM_GUARD @SECMEM_GUARD@ #endif diff --git a/src/lib/crypt.c b/src/lib/crypt.c index 92da803d..a14fc46b 100644 --- a/src/lib/crypt.c +++ b/src/lib/crypt.c @@ -98,7 +98,7 @@ const uint16_t kex_supported_nids[] = { NID_ffdhe4096, NID_X448, NID_secp521r1, -#ifdef HAVE_OPENSSL_PQC +#ifdef HAVE_OPENSSL_ML_KEM NID_MLKEM512, NID_MLKEM768, NID_MLKEM1024, diff --git a/src/lib/tests/CMakeLists.txt b/src/lib/tests/CMakeLists.txt index 23d01f9b..5a2f2c52 100644 --- a/src/lib/tests/CMakeLists.txt +++ b/src/lib/tests/CMakeLists.txt @@ -6,14 +6,15 @@ compute_test_prefix() create_test_sourcelist(${PARENT_DIR}_tests test_suite.c # Add new tests here auth_test.c - auth_test_pqc.c + auth_test_ml_dsa.c + auth_test_slh_dsa.c bitmap_test.c btree_test.c crc32_test.c crypt_test.c hash_test.c kex_test.c - kex_test_pqc.c + kex_test_ml_kem.c md5_test.c sha3_test.c sockets_test.c diff --git a/src/lib/tests/auth_test.c b/src/lib/tests/auth_test.c index b3f09277..0ea955f7 100644 --- a/src/lib/tests/auth_test.c +++ b/src/lib/tests/auth_test.c @@ -27,7 +27,7 @@ #include <ouroboros/random.h> #include <ouroboros/utils.h> -#include <test/certs.h> +#include <test/certs/ecdsa.h> #define TEST_MSG_SIZE 1500 diff --git a/src/lib/tests/auth_test_pqc.c b/src/lib/tests/auth_test_ml_dsa.c index 349636d2..cc72e61b 100644 --- a/src/lib/tests/auth_test_pqc.c +++ b/src/lib/tests/auth_test_ml_dsa.c @@ -1,7 +1,7 @@ /* * Ouroboros - Copyright (C) 2016 - 2026 * - * Test of the PQC authentication functions (ML-DSA-65) + * Test of the ML-DSA-65 authentication functions * * Dimitri Staessens <dimitri@ouroboros.rocks> * Sander Vrijders <sander@ouroboros.rocks> @@ -27,7 +27,7 @@ #include <ouroboros/random.h> #include <ouroboros/utils.h> -#include <test/certs_pqc.h> +#include <test/certs/ml_dsa.h> #define TEST_MSG_SIZE 1500 @@ -325,15 +325,15 @@ static int test_auth_bad_signature(void) return TEST_RC_FAIL; } -int auth_test_pqc(int argc, - char ** argv) +int auth_test_ml_dsa(int argc, + char ** argv) { int ret = 0; (void) argc; (void) argv; -#ifdef HAVE_OPENSSL_PQC +#ifdef HAVE_OPENSSL_ML_DSA ret |= test_auth_create_destroy_ctx(); ret |= test_load_free_crt(); ret |= test_load_free_privkey(); diff --git a/src/lib/tests/auth_test_slh_dsa.c b/src/lib/tests/auth_test_slh_dsa.c new file mode 100644 index 00000000..511d20fe --- /dev/null +++ b/src/lib/tests/auth_test_slh_dsa.c @@ -0,0 +1,367 @@ +/* + * Ouroboros - Copyright (C) 2016 - 2026 + * + * Test of the SLH-DSA-SHA2-128s authentication functions + * + * Dimitri Staessens <dimitri@ouroboros.rocks> + * Sander Vrijders <sander@ouroboros.rocks> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., http://www.fsf.org/about/contact/. + */ + +#include "config.h" + +#include <test/test.h> +#include <ouroboros/crypt.h> +#include <ouroboros/random.h> +#include <ouroboros/utils.h> + +#include <test/certs/slh_dsa.h> + +#define TEST_MSG_SIZE 1500 + +static int test_auth_create_destroy_ctx(void) +{ + struct auth_ctx * ctx; + + TEST_START(); + + ctx = auth_create_ctx(); + if (ctx == NULL) { + printf("Failed to create auth context.\n"); + goto fail_create; + } + + auth_destroy_ctx(ctx); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_create: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_load_free_crt(void) +{ + void * crt; + + TEST_START(); + + if (crypt_load_crt_str(root_ca_crt_slh, &crt) < 0) { + printf("Failed to load root crt.\n"); + goto fail_load; + } + + crypt_free_crt(crt); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_load: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_load_free_privkey(void) +{ + void * key; + + TEST_START(); + + if (crypt_load_privkey_str(server_pkp_slh, &key) < 0) { + printf("Failed to load server key pair.\n"); + goto fail_load; + } + + crypt_free_key(key); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_load: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_load_free_pubkey(void) +{ + void * key; + + TEST_START(); + + if (crypt_load_pubkey_str(server_pk_slh, &key) < 0) { + printf("Failed to load server public key.\n"); + goto fail_load; + } + + crypt_free_key(key); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_load: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_verify_crt(void) +{ + struct auth_ctx * auth; + void * _server_crt; + void * _signed_server_crt; + void * _root_ca_crt; + void * _im_ca_crt; + + TEST_START(); + + auth = auth_create_ctx(); + if (auth == NULL) { + printf("Failed to create auth context.\n"); + goto fail_create_ctx; + } + + if (crypt_load_crt_str(server_crt_slh, + &_server_crt) < 0) { + printf("Failed to load self-signed crt.\n"); + goto fail_load_server_crt; + } + + if (crypt_load_crt_str(signed_server_crt_slh, + &_signed_server_crt) < 0) { + printf("Failed to load signed crt.\n"); + goto fail_load_signed_server_crt; + } + + if (crypt_load_crt_str(root_ca_crt_slh, + &_root_ca_crt) < 0) { + printf("Failed to load root crt.\n"); + goto fail_load_root_ca_crt; + } + + if (crypt_load_crt_str(im_ca_crt_slh, + &_im_ca_crt) < 0) { + printf("Failed to load im crt.\n"); + goto fail_load_im_ca_crt; + } + + if (auth_add_crt_to_store(auth, _root_ca_crt) < 0) { + printf("Failed to add root ca crt.\n"); + goto fail_verify; + } + + if (auth_add_crt_to_store(auth, _im_ca_crt) < 0) { + printf("Failed to add im ca crt.\n"); + goto fail_verify; + } + + if (auth_verify_crt(auth, _signed_server_crt) < 0) { + printf("Failed to verify signed crt.\n"); + goto fail_verify; + } + + if (auth_verify_crt(auth, _server_crt) == 0) { + printf("Failed to detect untrusted crt.\n"); + goto fail_verify; + } + + crypt_free_crt(_im_ca_crt); + crypt_free_crt(_root_ca_crt); + crypt_free_crt(_signed_server_crt); + crypt_free_crt(_server_crt); + + auth_destroy_ctx(auth); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_verify: + crypt_free_crt(_im_ca_crt); + fail_load_im_ca_crt: + crypt_free_crt(_root_ca_crt); + fail_load_root_ca_crt: + crypt_free_crt(_signed_server_crt); + fail_load_signed_server_crt: + crypt_free_crt(_server_crt); + fail_load_server_crt: + auth_destroy_ctx(auth); + fail_create_ctx: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_auth_sign(void) +{ + uint8_t buf[TEST_MSG_SIZE]; + void * pkp; + void * pk; + buffer_t msg; + buffer_t sig; + + TEST_START(); + + msg.data = buf; + msg.len = sizeof(buf); + + if (random_buffer(msg.data, msg.len) < 0) { + printf("Failed to gen random message.\n"); + goto fail_init; + } + + if (crypt_load_privkey_str(server_pkp_slh, + &pkp) < 0) { + printf("Failed to load server key pair.\n"); + goto fail_init; + } + + if (crypt_load_pubkey_str(server_pk_slh, + &pk) < 0) { + printf("Failed to load public key.\n"); + goto fail_pubkey; + } + + if (auth_sign(pkp, 0, msg, &sig) < 0) { + printf("Failed to sign message.\n"); + goto fail_sign; + } + + if (auth_verify_sig(pk, 0, msg, sig) < 0) { + printf("Failed to verify signature.\n"); + goto fail_verify; + } + + freebuf(sig); + + crypt_free_key(pk); + crypt_free_key(pkp); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_verify: + freebuf(sig); + fail_sign: + crypt_free_key(pk); + fail_pubkey: + crypt_free_key(pkp); + fail_init: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +static int test_auth_bad_signature(void) +{ + uint8_t buf[TEST_MSG_SIZE]; + void * pkp; + void * pk; + buffer_t msg; + buffer_t sig; + buffer_t fake_sig; + + TEST_START(); + + msg.data = buf; + msg.len = sizeof(buf); + + if (random_buffer(msg.data, msg.len) < 0) { + printf("Failed to gen random message.\n"); + goto fail_init; + } + + if (crypt_load_privkey_str(server_pkp_slh, + &pkp) < 0) { + printf("Failed to load server key pair.\n"); + goto fail_init; + } + + if (crypt_load_pubkey_str(server_pk_slh, + &pk) < 0) { + printf("Failed to load public key.\n"); + goto fail_pubkey; + } + + if (auth_sign(pkp, 0, msg, &sig) < 0) { + printf("Failed to sign message.\n"); + goto fail_sign; + } + + fake_sig.data = malloc(sig.len); + if (fake_sig.data == NULL) { + printf("Failed to alloc fake sig buf.\n"); + goto fail_malloc; + } + + fake_sig.len = sig.len; + if (random_buffer(fake_sig.data, + fake_sig.len) < 0) { + printf("Failed to gen random fake sig.\n"); + goto fail_malloc; + } + + if (auth_verify_sig(pk, 0, msg, fake_sig) == 0) { + printf("Failed to detect bad sig.\n"); + goto fail_verify; + } + + freebuf(fake_sig); + freebuf(sig); + + crypt_free_key(pk); + crypt_free_key(pkp); + + TEST_SUCCESS(); + + return TEST_RC_SUCCESS; + fail_verify: + freebuf(fake_sig); + fail_malloc: + freebuf(sig); + fail_sign: + crypt_free_key(pk); + fail_pubkey: + crypt_free_key(pkp); + fail_init: + TEST_FAIL(); + return TEST_RC_FAIL; +} + +int auth_test_slh_dsa(int argc, + char ** argv) +{ + int ret = 0; + + (void) argc; + (void) argv; + +#ifdef HAVE_OPENSSL_SLH_DSA + ret |= test_auth_create_destroy_ctx(); + ret |= test_load_free_crt(); + ret |= test_load_free_privkey(); + ret |= test_load_free_pubkey(); + ret |= test_verify_crt(); + ret |= test_auth_sign(); + ret |= test_auth_bad_signature(); +#else + (void) test_auth_create_destroy_ctx; + (void) test_load_free_crt; + (void) test_load_free_privkey; + (void) test_load_free_pubkey; + (void) test_verify_crt; + (void) test_auth_sign; + (void) test_auth_bad_signature; + + ret = TEST_RC_SKIP; +#endif + return ret; +} diff --git a/src/lib/tests/kex_test.c b/src/lib/tests/kex_test.c index 0a588550..04200679 100644 --- a/src/lib/tests/kex_test.c +++ b/src/lib/tests/kex_test.c @@ -276,7 +276,7 @@ static int test_kex_validate_algo(void) goto fail; } -#ifdef HAVE_OPENSSL_PQC +#ifdef HAVE_OPENSSL_ML_KEM if (kex_validate_algo("ML-KEM-768") != 0) { printf("ML-KEM-768 should be valid.\n"); goto fail; @@ -536,7 +536,7 @@ static int test_kex_all(void) for (i = 0; kex_supported_nids[i] != NID_undef; i++) { const char * algo = kex_nid_to_str(kex_supported_nids[i]); - /* KEM tests are in kex_test_pqc.c */ + /* KEM tests are in kex_test_ml_kem.c */ if (IS_KEM_ALGORITHM(algo)) continue; @@ -552,7 +552,7 @@ static int test_kex_dhe_corrupted_pubkey_all(void) int i; /* Test corruption for all DHE algorithms */ - /* KEM error injection tests are in kex_test_pqc.c */ + /* KEM error injection tests are in kex_test_ml_kem.c */ for (i = 0; kex_supported_nids[i] != NID_undef; i++) { const char * algo = kex_nid_to_str(kex_supported_nids[i]); diff --git a/src/lib/tests/kex_test_pqc.c b/src/lib/tests/kex_test_ml_kem.c index d4579eca..3bb9ae7c 100644 --- a/src/lib/tests/kex_test_pqc.c +++ b/src/lib/tests/kex_test_ml_kem.c @@ -520,15 +520,15 @@ static int test_kex_kem_truncated_ciphertext_all(void) return ret; } -int kex_test_pqc(int argc, - char ** argv) +int kex_test_ml_kem(int argc, + char ** argv) { int ret = 0; (void) argc; (void) argv; -#ifdef HAVE_OPENSSL_PQC +#ifdef HAVE_OPENSSL_ML_KEM ret |= test_kex_load_kem_privkey(); ret |= test_kex_load_kem_pubkey(); ret |= test_kex_kem_all(); |
