From ad5478cdf49960bce9ea24e70a9e7e878b5f3de1 Mon Sep 17 00:00:00 2001 From: Andreas Hatziiliou Date: Sun, 4 Jan 2026 18:56:51 -0500 Subject: [PATCH 1/3] API: add failure mode support for randombytes() Change randombytes() to return int (0 on success, non-zero on failure) instead of void, allowing callers to detect and handle RNG failures. This commit: * Updates function signatures. * All call sites to check return values. * Changes test files to use CHECK macro. * Adds documentation of the new failure mode to sign.h and mlkem_native.h * Adds a new error code MLK_ERR_RNG_FAIL. * Declares src/randombytes with MLK_MUST_CHECK_RETURN_VALUE. Signed-off-by: Andreas Hatziiliou --- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 6 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- .../mlkem_native/mlkem_native_config.h | 5 +- integration/aws-lc/post_import.patch | 28 +++++++++ integration/liboqs/config_aarch64.h | 5 +- integration/liboqs/config_c.h | 5 +- integration/liboqs/config_x86_64.h | 5 +- mlkem/mlkem_native.S | 2 + mlkem/mlkem_native.c | 2 + mlkem/mlkem_native.h | 5 ++ mlkem/mlkem_native_config.h | 5 +- mlkem/src/common.h | 3 + mlkem/src/indcpa.h | 3 +- mlkem/src/kem.c | 17 +++++- mlkem/src/kem.h | 19 ++++--- mlkem/src/randombytes.h | 6 +- proofs/cbmc/mlkem_native_config_cbmc.h | 5 +- scripts/lint | 6 +- test/bench/bench_components_mlkem.c | 57 ++++++++++++------- test/bench/bench_mlkem.c | 4 +- test/configs/break_pct_config.h | 5 +- test/configs/configs.yml | 8 +-- test/configs/custom_heap_alloc_config.h | 5 +- test/configs/custom_memcpy_config.h | 5 +- test/configs/custom_memset_config.h | 5 +- .../custom_native_capability_config_0.h | 5 +- .../custom_native_capability_config_1.h | 5 +- ...stom_native_capability_config_CPUID_AVX2.h | 5 +- ...native_capability_config_ID_AA64PFR1_EL1.h | 5 +- test/configs/custom_randombytes_config.h | 6 +- test/configs/custom_stdlib_config.h | 5 +- test/configs/custom_zeroize_config.h | 5 +- test/configs/no_asm_config.h | 5 +- test/configs/serial_fips202_config.h | 5 +- test/configs/test_alloc_config.h | 5 +- test/notrandombytes/notrandombytes.c | 3 +- test/notrandombytes/notrandombytes.h | 2 +- test/src/test_mlkem.c | 8 +-- 45 files changed, 209 insertions(+), 111 deletions(-) create mode 100644 integration/aws-lc/post_import.patch diff --git a/examples/basic_deterministic/mlkem_native/mlkem_native_config.h b/examples/basic_deterministic/mlkem_native/mlkem_native_config.h index 4a35b7c675..a6ac73e00b 100644 --- a/examples/basic_deterministic/mlkem_native/mlkem_native_config.h +++ b/examples/basic_deterministic/mlkem_native/mlkem_native_config.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/bring_your_own_fips202/mlkem_native/mlkem_native_config.h b/examples/bring_your_own_fips202/mlkem_native/mlkem_native_config.h index cdfb1182f3..c2d777f006 100644 --- a/examples/bring_your_own_fips202/mlkem_native/mlkem_native_config.h +++ b/examples/bring_your_own_fips202/mlkem_native/mlkem_native_config.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/bring_your_own_fips202_static/mlkem_native/mlkem_native_config.h b/examples/bring_your_own_fips202_static/mlkem_native/mlkem_native_config.h index 90097d6b65..6228c5a29b 100644 --- a/examples/bring_your_own_fips202_static/mlkem_native/mlkem_native_config.h +++ b/examples/bring_your_own_fips202_static/mlkem_native/mlkem_native_config.h @@ -410,7 +410,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -421,9 +421,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/custom_backend/mlkem_native/mlkem_native_config.h b/examples/custom_backend/mlkem_native/mlkem_native_config.h index b51cdc5998..56e668847f 100644 --- a/examples/custom_backend/mlkem_native/mlkem_native_config.h +++ b/examples/custom_backend/mlkem_native/mlkem_native_config.h @@ -405,7 +405,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -416,9 +416,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/monolithic_build/mlkem_native/mlkem_native_config.h b/examples/monolithic_build/mlkem_native/mlkem_native_config.h index ff5e4a9b48..13ac85adb3 100644 --- a/examples/monolithic_build/mlkem_native/mlkem_native_config.h +++ b/examples/monolithic_build/mlkem_native/mlkem_native_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/monolithic_build_multilevel/mlkem_native/mlkem_native_config.h b/examples/monolithic_build_multilevel/mlkem_native/mlkem_native_config.h index 6e6393c131..5b99f63920 100644 --- a/examples/monolithic_build_multilevel/mlkem_native/mlkem_native_config.h +++ b/examples/monolithic_build_multilevel/mlkem_native/mlkem_native_config.h @@ -410,7 +410,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -421,9 +421,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/monolithic_build_multilevel_native/mlkem_native/mlkem_native_config.h b/examples/monolithic_build_multilevel_native/mlkem_native/mlkem_native_config.h index ce5ddcf111..9432513665 100644 --- a/examples/monolithic_build_multilevel_native/mlkem_native/mlkem_native_config.h +++ b/examples/monolithic_build_multilevel_native/mlkem_native/mlkem_native_config.h @@ -410,7 +410,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -428,9 +428,9 @@ #include #include "src/sys.h" #include "test_only_rng/notrandombytes.h" -static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) +static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { - randombytes(ptr, len); + return randombytes(ptr, len); } #endif /* !__ASSEMBLER__ */ diff --git a/examples/monolithic_build_native/mlkem_native/mlkem_native_config.h b/examples/monolithic_build_native/mlkem_native/mlkem_native_config.h index 82f10f87f1..ce801f3144 100644 --- a/examples/monolithic_build_native/mlkem_native/mlkem_native_config.h +++ b/examples/monolithic_build_native/mlkem_native/mlkem_native_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/multilevel_build/mlkem_native/mlkem_native_config.h b/examples/multilevel_build/mlkem_native/mlkem_native_config.h index 0d6d959a82..45e104ceaa 100644 --- a/examples/multilevel_build/mlkem_native/mlkem_native_config.h +++ b/examples/multilevel_build/mlkem_native/mlkem_native_config.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/examples/multilevel_build_native/mlkem_native/mlkem_native_config.h b/examples/multilevel_build_native/mlkem_native/mlkem_native_config.h index 88fbc4cf61..b4d6aa953d 100644 --- a/examples/multilevel_build_native/mlkem_native/mlkem_native_config.h +++ b/examples/multilevel_build_native/mlkem_native/mlkem_native_config.h @@ -407,7 +407,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -418,9 +418,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/integration/aws-lc/post_import.patch b/integration/aws-lc/post_import.patch new file mode 100644 index 0000000000..a38331b440 --- /dev/null +++ b/integration/aws-lc/post_import.patch @@ -0,0 +1,28 @@ +From dc1fb278d8d15bf931a805faf1298403c9c49c99 Mon Sep 17 00:00:00 2001 +From: Andreas Hatziiliou +Date: Mon, 12 Jan 2026 09:51:43 -0500 +Subject: [PATCH] post_import + +--- + crypto/fipsmodule/ml_kem/mlkem_native_config.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/crypto/fipsmodule/ml_kem/mlkem_native_config.h b/crypto/fipsmodule/ml_kem/mlkem_native_config.h +index 76df78c3b..7b5a2228a 100644 +--- a/crypto/fipsmodule/ml_kem/mlkem_native_config.h ++++ b/crypto/fipsmodule/ml_kem/mlkem_native_config.h +@@ -78,8 +78,9 @@ static MLK_INLINE void mlk_zeroize(void *ptr, size_t len) { + #include + #include "mlkem/sys.h" + #include +-static MLK_INLINE void mlk_randombytes(void *ptr, size_t len) { +- RAND_bytes(ptr, len); ++static MLK_INLINE int mlk_randombytes(void *ptr, size_t len) { ++ RAND_bytes(ptr, len); ++ return 0; + } + #endif // !__ASSEMBLER__ + +-- +2.52.0 + diff --git a/integration/liboqs/config_aarch64.h b/integration/liboqs/config_aarch64.h index e59c24187b..29f27388a9 100644 --- a/integration/liboqs/config_aarch64.h +++ b/integration/liboqs/config_aarch64.h @@ -182,7 +182,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -194,9 +194,10 @@ #include #include #include "../../mlkem/src/sys.h" -static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) +static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { OQS_randombytes(ptr, len); + return 0; } #endif /* !__ASSEMBLER__ */ diff --git a/integration/liboqs/config_c.h b/integration/liboqs/config_c.h index 729dc86c3f..9b1eef321a 100644 --- a/integration/liboqs/config_c.h +++ b/integration/liboqs/config_c.h @@ -145,7 +145,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -157,9 +157,10 @@ #include #include #include "../../mlkem/src/sys.h" -static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) +static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { OQS_randombytes(ptr, len); + return 0; } #endif /* !__ASSEMBLER__ */ diff --git a/integration/liboqs/config_x86_64.h b/integration/liboqs/config_x86_64.h index 0673652455..b82f3dd434 100644 --- a/integration/liboqs/config_x86_64.h +++ b/integration/liboqs/config_x86_64.h @@ -182,7 +182,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -194,9 +194,10 @@ #include #include #include "../../mlkem/src/sys.h" -static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) +static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { OQS_randombytes(ptr, len); + return 0; } #endif /* !__ASSEMBLER__ */ diff --git a/mlkem/mlkem_native.S b/mlkem/mlkem_native.S index 4aea390401..d2fbe0fa64 100644 --- a/mlkem/mlkem_native.S +++ b/mlkem/mlkem_native.S @@ -167,6 +167,7 @@ #undef MLK_CONFIG_API_QUALIFIER #undef MLK_ERR_FAIL #undef MLK_ERR_OUT_OF_MEMORY +#undef MLK_ERR_RNG_FAIL #undef MLK_H #undef MLK_MAX3_ #undef MLK_TOTAL_ALLOC_1024 @@ -212,6 +213,7 @@ #undef MLK_EMPTY_CU #undef MLK_ERR_FAIL #undef MLK_ERR_OUT_OF_MEMORY +#undef MLK_ERR_RNG_FAIL #undef MLK_EXTERNAL_API #undef MLK_FIPS202X4_HEADER_FILE #undef MLK_FIPS202_HEADER_FILE diff --git a/mlkem/mlkem_native.c b/mlkem/mlkem_native.c index 73190a2dc5..572890832b 100644 --- a/mlkem/mlkem_native.c +++ b/mlkem/mlkem_native.c @@ -156,6 +156,7 @@ #undef MLK_CONFIG_API_QUALIFIER #undef MLK_ERR_FAIL #undef MLK_ERR_OUT_OF_MEMORY +#undef MLK_ERR_RNG_FAIL #undef MLK_H #undef MLK_MAX3_ #undef MLK_TOTAL_ALLOC_1024 @@ -201,6 +202,7 @@ #undef MLK_EMPTY_CU #undef MLK_ERR_FAIL #undef MLK_ERR_OUT_OF_MEMORY +#undef MLK_ERR_RNG_FAIL #undef MLK_EXTERNAL_API #undef MLK_FIPS202X4_HEADER_FILE #undef MLK_FIPS202_HEADER_FILE diff --git a/mlkem/mlkem_native.h b/mlkem/mlkem_native.h index 63f305826a..302ca3fab6 100644 --- a/mlkem/mlkem_native.h +++ b/mlkem/mlkem_native.h @@ -116,6 +116,9 @@ /* An allocation failed. This can only happen if MLK_CONFIG_CUSTOM_ALLOC_FREE * is defined and the provided MLK_CUSTOM_ALLOC can fail. */ #define MLK_ERR_OUT_OF_MEMORY -2 +/* An rng failure occured. Might be due to insufficient entropy or + * system misconfiguration. */ +#define MLK_ERR_RNG_FAIL -3 /****************************** Function API **********************************/ @@ -240,6 +243,7 @@ int MLK_API_NAMESPACE(keypair_derand)( * PCT failed. * - MLK_ERR_OUT_OF_MEMORY: If MLK_CONFIG_CUSTOM_ALLOC_FREE is * used and an allocation via MLK_CUSTOM_ALLOC returned NULL. + * - MLK_ERR_RNG_FAIL: Random number generation failed. * * Specification: Implements @[FIPS203, Algorithm 19, ML-KEM.KeyGen] * @@ -312,6 +316,7 @@ int MLK_API_NAMESPACE(enc_derand)( * for the public key fails. * - MLK_ERR_OUT_OF_MEMORY: If MLK_CONFIG_CUSTOM_ALLOC_FREE is * used and an allocation via MLK_CUSTOM_ALLOC returned NULL. + * - MLK_ERR_RNG_FAIL: Random number generation failed. * * Specification: Implements @[FIPS203, Algorithm 20, ML-KEM.Encaps] * diff --git a/mlkem/mlkem_native_config.h b/mlkem/mlkem_native_config.h index f8db69c164..6ec34f3b63 100644 --- a/mlkem/mlkem_native_config.h +++ b/mlkem/mlkem_native_config.h @@ -393,7 +393,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -404,9 +404,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/mlkem/src/common.h b/mlkem/src/common.h index bd4879049c..f7988fb9ec 100644 --- a/mlkem/src/common.h +++ b/mlkem/src/common.h @@ -245,6 +245,9 @@ /* An allocation failed. This can only happen if MLK_CONFIG_CUSTOM_ALLOC_FREE * is defined and the provided MLK_CUSTOM_ALLOC can fail. */ #define MLK_ERR_OUT_OF_MEMORY -2 +/* An rng failure occured. Might be due to insufficient entropy or + * system misconfiguration. */ +#define MLK_ERR_RNG_FAIL -3 #endif /* !__ASSEMBLER__ */ diff --git a/mlkem/src/indcpa.h b/mlkem/src/indcpa.h index 9a71052452..6e5745475b 100644 --- a/mlkem/src/indcpa.h +++ b/mlkem/src/indcpa.h @@ -81,7 +81,8 @@ __contract__( assigns(memory_slice(pk, MLKEM_INDCPA_PUBLICKEYBYTES)) assigns(memory_slice(sk, MLKEM_INDCPA_SECRETKEYBYTES)) ensures(return_value == 0 || return_value == MLK_ERR_FAIL || - return_value == MLK_ERR_OUT_OF_MEMORY) + return_value == MLK_ERR_OUT_OF_MEMORY || + return_value == MLK_ERR_RNG_FAIL) ); #define mlk_indcpa_enc MLK_NAMESPACE_K(indcpa_enc) MLK_CONTEXT_PARAMETERS_4 diff --git a/mlkem/src/kem.c b/mlkem/src/kem.c index 7b3fd53859..41171e8cec 100644 --- a/mlkem/src/kem.c +++ b/mlkem/src/kem.c @@ -128,7 +128,8 @@ __contract__( requires(memory_no_alias(pk, MLKEM_INDCCA_PUBLICKEYBYTES)) requires(memory_no_alias(sk, MLKEM_INDCCA_SECRETKEYBYTES)) ensures(return_value == 0 || return_value == MLK_ERR_FAIL || - return_value == MLK_ERR_OUT_OF_MEMORY) + return_value == MLK_ERR_OUT_OF_MEMORY || + return_value == MLK_ERR_RNG_FAIL) ); #if defined(MLK_CONFIG_KEYGEN_PCT) @@ -267,7 +268,12 @@ int mlk_kem_keypair(uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES], } /* Acquire necessary randomness, and mark it as secret. */ - mlk_randombytes(coins, 2 * MLKEM_SYMBYTES); + if (mlk_randombytes(coins, 2 * MLKEM_SYMBYTES) != 0) + { + ret = MLK_ERR_RNG_FAIL; + goto cleanup; + } + MLK_CT_TESTING_SECRET(coins, 2 * MLKEM_SYMBYTES); ret = mlk_kem_keypair_derand(pk, sk, coins, context); @@ -352,7 +358,12 @@ int mlk_kem_enc(uint8_t ct[MLKEM_INDCCA_CIPHERTEXTBYTES], goto cleanup; } - mlk_randombytes(coins, MLKEM_SYMBYTES); + if (mlk_randombytes(coins, MLKEM_SYMBYTES) != 0) + { + ret = MLK_ERR_RNG_FAIL; + goto cleanup; + } + MLK_CT_TESTING_SECRET(coins, MLKEM_SYMBYTES); ret = mlk_kem_enc_derand(ct, ss, pk, coins, context); diff --git a/mlkem/src/kem.h b/mlkem/src/kem.h index 318f2fd2f7..13f9406ad3 100644 --- a/mlkem/src/kem.h +++ b/mlkem/src/kem.h @@ -156,7 +156,8 @@ __contract__( assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES)) assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES)) ensures(return_value == 0 || return_value == MLK_ERR_FAIL || - return_value == MLK_ERR_OUT_OF_MEMORY) + return_value == MLK_ERR_OUT_OF_MEMORY || + return_value == MLK_ERR_RNG_FAIL) ); /************************************************* @@ -173,10 +174,11 @@ __contract__( * bytes) * * Returns: - 0: On success - * - MLK_ERR_FAIL: If MLK_CONFIG_KEYGEN_PCT is enabled and the - * PCT failed. * - MLK_ERR_OUT_OF_MEMORY: If MLK_CONFIG_CUSTOM_ALLOC_FREE is * used and an allocation via MLK_CUSTOM_ALLOC returned NULL. + * - MLK_ERR_RNG_FAIL: Random number generation failed. + * - MLK_ERR_FAIL: If MLK_CONFIG_KEYGEN_PCT is enabled and the + * PCT failed. * * Specification: Implements @[FIPS203, Algorithm 19, ML-KEM.KeyGen] * @@ -192,7 +194,8 @@ __contract__( assigns(memory_slice(pk, MLKEM_INDCCA_PUBLICKEYBYTES)) assigns(memory_slice(sk, MLKEM_INDCCA_SECRETKEYBYTES)) ensures(return_value == 0 || return_value == MLK_ERR_FAIL || - return_value == MLK_ERR_OUT_OF_MEMORY) + return_value == MLK_ERR_OUT_OF_MEMORY || + return_value == MLK_ERR_RNG_FAIL) ); /************************************************* @@ -256,10 +259,11 @@ __contract__( * bytes) * * Returns: - 0 on success - * - MLK_ERR_FAIL: If the 'modulus check' @[FIPS203, Section 7.2] - * for the public key fails. * - MLK_ERR_OUT_OF_MEMORY: If MLK_CONFIG_CUSTOM_ALLOC_FREE is * used and an allocation via MLK_CUSTOM_ALLOC returned NULL. + * - MLK_ERR_RNG_FAIL: Random number generation failed. + * - MLK_ERR_FAIL: If the 'modulus check' @[FIPS203, Section 7.2] + * for the public key fails. * * Specification: Implements @[FIPS203, Algorithm 20, ML-KEM.Encaps] * @@ -277,7 +281,8 @@ __contract__( assigns(memory_slice(ct, MLKEM_INDCCA_CIPHERTEXTBYTES)) assigns(memory_slice(ss, MLKEM_SSBYTES)) ensures(return_value == 0 || return_value == MLK_ERR_FAIL || - return_value == MLK_ERR_OUT_OF_MEMORY) + return_value == MLK_ERR_OUT_OF_MEMORY || + return_value == MLK_ERR_RNG_FAIL) ); /************************************************* diff --git a/mlkem/src/randombytes.h b/mlkem/src/randombytes.h index 33fe04a0e5..e911782cd3 100644 --- a/mlkem/src/randombytes.h +++ b/mlkem/src/randombytes.h @@ -12,11 +12,11 @@ #if !defined(MLK_CONFIG_NO_RANDOMIZED_API) #if !defined(MLK_CONFIG_CUSTOM_RANDOMBYTES) -void randombytes(uint8_t *out, size_t outlen); -static MLK_INLINE void mlk_randombytes(uint8_t *out, size_t outlen) +int randombytes(uint8_t *out, size_t outlen); +static MLK_INLINE int mlk_randombytes(uint8_t *out, size_t outlen) __contract__( requires(memory_no_alias(out, outlen)) - assigns(memory_slice(out, outlen))) { randombytes(out, outlen); } + assigns(memory_slice(out, outlen))) { return randombytes(out, outlen); } #endif /* !MLK_CONFIG_CUSTOM_RANDOMBYTES */ #endif /* !MLK_CONFIG_NO_RANDOMIZED_API */ #endif /* !MLK_RANDOMBYTES_H */ diff --git a/proofs/cbmc/mlkem_native_config_cbmc.h b/proofs/cbmc/mlkem_native_config_cbmc.h index 5fc3e99f4f..bc41f907dd 100644 --- a/proofs/cbmc/mlkem_native_config_cbmc.h +++ b/proofs/cbmc/mlkem_native_config_cbmc.h @@ -410,7 +410,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -421,9 +421,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/scripts/lint b/scripts/lint index 018d863f05..2285c343a0 100755 --- a/scripts/lint +++ b/scripts/lint @@ -150,14 +150,14 @@ gh_group_end check-spdx() { local success=true - for file in $(git ls-files -- ":/" ":/!:*.json" ":/!:*.png" ":/!:*LICENSE*" ":/!:.git*" ":/!:flake.lock"); do + for file in $(git ls-files -- ":/" ":/!:*.json" ":/!:*.png" ":/!:*.patch" ":/!:*LICENSE*" ":/!:.git*" ":/!:flake.lock"); do # Ignore symlinks if [[ ! -L $file && $(grep "SPDX-License-Identifier:" $file | wc -l) == 0 ]]; then gh_error "$file" "${line:-1}" "Missing license header error" "$file is missing SPDX License header" success=false fi done - for file in $(git ls-files -- "*.[chsS]" "*.py" "*.mk" "*.yml" "**/Makefile*" ":/!proofs/cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*" ":/!examples/custom_backend/mlkem_native/src/fips202/native/custom/src/*"); do + for file in $(git ls-files -- "*.[chsS]" "*.py" "*.mk" "*.yml" "**/Makefile*" ":/!proofs/cbmc/*.py" ":/!examples/bring_your_own_fips202/custom_fips202/tiny_sha3/*" ":/!examples/custom_backend/mlkem_native/src/fips202/native/custom/src/*" ":/!:*.patch"); do # Ignore symlinks if [[ ! -L $file && $(grep "Copyright (c) The mlkem-native project authors" $file | wc -l) == 0 ]]; then gh_error "$file" "${line:-1}" "Missing copyright header error" "$file is missing copyright header" @@ -165,7 +165,7 @@ check-spdx() fi done # For source files in dev/* and mlkem/*, we enforce `Apache-2.0 OR ISC OR MIT` - for file in $(git ls-files -- "*.[chsSi]" | grep "^dev/\|^mlkem/"); do + for file in $(git ls-files -- "*.[chsSi]" | grep "^dev/\|^mlkem/" | grep -v "\.patch$"); do # Ignore symlinks if [[ ! -L $file && $(grep "SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT" $file | wc -l) == 0 ]]; then gh_error "$file" "${line:-1}" "Missing license header error" "$file is not licensed under 'Apache-2.0 OR ISC OR MIT'" diff --git a/test/bench/bench_components_mlkem.c b/test/bench/bench_components_mlkem.c index d18ddf305c..82ba4ec260 100644 --- a/test/bench/bench_components_mlkem.c +++ b/test/bench/bench_components_mlkem.c @@ -27,28 +27,41 @@ static int cmp_uint64_t(const void *a, const void *b) return (int)((*((const uint64_t *)a)) - (*((const uint64_t *)b))); } -#define BENCH(txt, code) \ - for (i = 0; i < NTESTS; i++) \ - { \ - randombytes((uint8_t *)data0, sizeof(data0)); \ - randombytes((uint8_t *)data1, sizeof(data1)); \ - randombytes((uint8_t *)data2, sizeof(data2)); \ - randombytes((uint8_t *)data3, sizeof(data3)); \ - randombytes((uint8_t *)data4, sizeof(data4)); \ - for (j = 0; j < NWARMUP; j++) \ - { \ - code; \ - } \ - \ - t0 = get_cyclecounter(); \ - for (j = 0; j < NITERATIONS; j++) \ - { \ - code; \ - } \ - t1 = get_cyclecounter(); \ - (cyc)[i] = t1 - t0; \ - } \ - qsort((cyc), NTESTS, sizeof(uint64_t), cmp_uint64_t); \ +#define CHECK(x) \ + do \ + { \ + int rc; \ + rc = (x); \ + if (!rc) \ + { \ + fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \ + return 1; \ + } \ + } while (0) + + +#define BENCH(txt, code) \ + for (i = 0; i < NTESTS; i++) \ + { \ + CHECK(randombytes((uint8_t *)data0, sizeof(data0)) == 0); \ + CHECK(randombytes((uint8_t *)data1, sizeof(data1)) == 0); \ + CHECK(randombytes((uint8_t *)data2, sizeof(data2)) == 0); \ + CHECK(randombytes((uint8_t *)data3, sizeof(data3)) == 0); \ + CHECK(randombytes((uint8_t *)data4, sizeof(data4)) == 0); \ + for (j = 0; j < NWARMUP; j++) \ + { \ + code; \ + } \ + \ + t0 = get_cyclecounter(); \ + for (j = 0; j < NITERATIONS; j++) \ + { \ + code; \ + } \ + t1 = get_cyclecounter(); \ + (cyc)[i] = t1 - t0; \ + } \ + qsort((cyc), NTESTS, sizeof(uint64_t), cmp_uint64_t); \ printf(txt " cycles=%" PRIu64 "\n", (cyc)[NTESTS >> 1] / NITERATIONS); static int bench(void) diff --git a/test/bench/bench_mlkem.c b/test/bench/bench_mlkem.c index e221e251b4..6757e7305e 100644 --- a/test/bench/bench_mlkem.c +++ b/test/bench/bench_mlkem.c @@ -80,8 +80,8 @@ static int bench(void) for (i = 0; i < NTESTS; i++) { int ret = 0; - randombytes(kg_rand, 2 * CRYPTO_BYTES); - randombytes(enc_rand, CRYPTO_BYTES); + CHECK(randombytes(kg_rand, 2 * CRYPTO_BYTES) == 0); + CHECK(randombytes(enc_rand, CRYPTO_BYTES) == 0); /* Key-pair generation */ for (j = 0; j < NWARMUP; j++) diff --git a/test/configs/break_pct_config.h b/test/configs/break_pct_config.h index 2ca0faa98e..2f0ae66518 100644 --- a/test/configs/break_pct_config.h +++ b/test/configs/break_pct_config.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/configs.yml b/test/configs/configs.yml index e88e2d7e09..195db1708a 100644 --- a/test/configs/configs.yml +++ b/test/configs/configs.yml @@ -37,9 +37,9 @@ configs: #include #include "../mlkem/src/sys.h" #include "notrandombytes/notrandombytes.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { - randombytes(ptr, len); + return randombytes(ptr, len); } #endif /* !__ASSEMBLER__ */ @@ -353,9 +353,9 @@ configs: #include #include "src/sys.h" #include "test_only_rng/notrandombytes.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { - randombytes(ptr, len); + return randombytes(ptr, len); } #endif /* !__ASSEMBLER__ */ diff --git a/test/configs/custom_heap_alloc_config.h b/test/configs/custom_heap_alloc_config.h index 3174a86a1c..386e1f5b06 100644 --- a/test/configs/custom_heap_alloc_config.h +++ b/test/configs/custom_heap_alloc_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_memcpy_config.h b/test/configs/custom_memcpy_config.h index 82c05d8cc3..fbcb61dd5b 100644 --- a/test/configs/custom_memcpy_config.h +++ b/test/configs/custom_memcpy_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_memset_config.h b/test/configs/custom_memset_config.h index 7b6e0c796e..3f8f71b87a 100644 --- a/test/configs/custom_memset_config.h +++ b/test/configs/custom_memset_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_native_capability_config_0.h b/test/configs/custom_native_capability_config_0.h index df37c9b7c7..d49d7afd4f 100644 --- a/test/configs/custom_native_capability_config_0.h +++ b/test/configs/custom_native_capability_config_0.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_native_capability_config_1.h b/test/configs/custom_native_capability_config_1.h index 033ba18a4c..d911c2d5d0 100644 --- a/test/configs/custom_native_capability_config_1.h +++ b/test/configs/custom_native_capability_config_1.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_native_capability_config_CPUID_AVX2.h b/test/configs/custom_native_capability_config_CPUID_AVX2.h index 276bef4c53..f3c273e6cb 100644 --- a/test/configs/custom_native_capability_config_CPUID_AVX2.h +++ b/test/configs/custom_native_capability_config_CPUID_AVX2.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_native_capability_config_ID_AA64PFR1_EL1.h b/test/configs/custom_native_capability_config_ID_AA64PFR1_EL1.h index 381fc21868..cb9e715d7a 100644 --- a/test/configs/custom_native_capability_config_ID_AA64PFR1_EL1.h +++ b/test/configs/custom_native_capability_config_ID_AA64PFR1_EL1.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_randombytes_config.h b/test/configs/custom_randombytes_config.h index 6a30f7df73..581084c711 100644 --- a/test/configs/custom_randombytes_config.h +++ b/test/configs/custom_randombytes_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,9 @@ #include #include "../mlkem/src/sys.h" #include "notrandombytes/notrandombytes.h" -static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) +static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { - randombytes(ptr, len); + return randombytes(ptr, len); } #endif /* !__ASSEMBLER__ */ diff --git a/test/configs/custom_stdlib_config.h b/test/configs/custom_stdlib_config.h index a12ed8a4ba..9ceb060ea4 100644 --- a/test/configs/custom_stdlib_config.h +++ b/test/configs/custom_stdlib_config.h @@ -409,7 +409,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/custom_zeroize_config.h b/test/configs/custom_zeroize_config.h index ba95eaa0b9..2ab073bd06 100644 --- a/test/configs/custom_zeroize_config.h +++ b/test/configs/custom_zeroize_config.h @@ -409,7 +409,7 @@ static MLK_INLINE void mlk_zeroize(void *ptr, size_t len) * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -420,9 +420,10 @@ static MLK_INLINE void mlk_zeroize(void *ptr, size_t len) #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/no_asm_config.h b/test/configs/no_asm_config.h index 377eeaac52..99e7fb6179 100644 --- a/test/configs/no_asm_config.h +++ b/test/configs/no_asm_config.h @@ -410,7 +410,7 @@ static MLK_INLINE void mlk_zeroize(void *ptr, size_t len) * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -421,9 +421,10 @@ static MLK_INLINE void mlk_zeroize(void *ptr, size_t len) #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/serial_fips202_config.h b/test/configs/serial_fips202_config.h index 7baee26ca1..77677be2e0 100644 --- a/test/configs/serial_fips202_config.h +++ b/test/configs/serial_fips202_config.h @@ -408,7 +408,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -419,9 +419,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/configs/test_alloc_config.h b/test/configs/test_alloc_config.h index 7f1550fb85..e474cbab66 100644 --- a/test/configs/test_alloc_config.h +++ b/test/configs/test_alloc_config.h @@ -411,7 +411,7 @@ * consumer. * * If this option is not set, mlkem-native expects a function - * void randombytes(uint8_t *out, size_t outlen). + * int randombytes(uint8_t *out, size_t outlen). * * Set this option and define `mlk_randombytes` if you want to * use a custom method to sample randombytes with a different name @@ -422,9 +422,10 @@ #if !defined(__ASSEMBLER__) #include #include "src/sys.h" - static MLK_INLINE void mlk_randombytes(uint8_t *ptr, size_t len) + static MLK_INLINE int mlk_randombytes(uint8_t *ptr, size_t len) { ... your implementation ... + return 0; } #endif */ diff --git a/test/notrandombytes/notrandombytes.c b/test/notrandombytes/notrandombytes.c index 203eab3c5f..704629b26c 100644 --- a/test/notrandombytes/notrandombytes.c +++ b/test/notrandombytes/notrandombytes.c @@ -86,7 +86,7 @@ static void surf(void) } } -void randombytes(uint8_t *buf, size_t n) +int randombytes(uint8_t *buf, size_t n) { while (n > 0) { @@ -109,4 +109,5 @@ void randombytes(uint8_t *buf, size_t n) ++buf; --n; } + return 0; } diff --git a/test/notrandombytes/notrandombytes.h b/test/notrandombytes/notrandombytes.h index 1e466f1048..50540ae75f 100644 --- a/test/notrandombytes/notrandombytes.h +++ b/test/notrandombytes/notrandombytes.h @@ -29,6 +29,6 @@ */ void randombytes_reset(void); -void randombytes(uint8_t *buf, size_t n); +int randombytes(uint8_t *buf, size_t n); #endif /* !NOTRANDOMBYTES_H */ diff --git a/test/src/test_mlkem.c b/test/src/test_mlkem.c index 5ca02166a5..88564b4df9 100644 --- a/test/src/test_mlkem.c +++ b/test/src/test_mlkem.c @@ -98,7 +98,7 @@ static int test_invalid_sk_a(void) /* Bob derives a secret key and creates a response */ CHECK(crypto_kem_enc(ct, key_b, pk) == 0); /* Replace first part of secret key with random values */ - randombytes(sk, 10); + CHECK(randombytes(sk, 10) == 0); /* Alice uses Bobs response to get her shared key * This should fail due to wrong sk */ CHECK(crypto_kem_dec(key_a, ct, sk) == 0); @@ -122,7 +122,7 @@ static int test_invalid_sk_b(void) /* Bob derives a secret key and creates a response */ CHECK(crypto_kem_enc(ct, key_b, pk) == 0); /* Replace H(pk) with radom values; */ - randombytes(sk + CRYPTO_SECRETKEYBYTES - 64, 32); + CHECK(randombytes(sk + CRYPTO_SECRETKEYBYTES - 64, 32) == 0); /* Alice uses Bobs response to get her shared key * This should fail due to the input validation */ CHECK(crypto_kem_dec(key_a, ct, sk) != 0); @@ -141,9 +141,9 @@ static int test_invalid_ciphertext(void) do { - randombytes(&b, sizeof(uint8_t)); + CHECK(randombytes(&b, sizeof(uint8_t)) == 0); } while (!b); - randombytes((uint8_t *)&pos, sizeof(size_t)); + CHECK(randombytes((uint8_t *)&pos, sizeof(size_t)) == 0); /* Alice generates a public key */ CHECK(crypto_kem_keypair(pk, sk) == 0); From 27aacda824489060fca8537f6026f9142a38d856 Mon Sep 17 00:00:00 2001 From: Andreas Hatziiliou Date: Sun, 4 Jan 2026 20:29:20 -0500 Subject: [PATCH 2/3] testing: add rng failure test Tests that crypto_kem_enc and crypto_kem_keypair, correctly return MLD_ERR_RNG_FAIL when randombytes() fails. We systematically inject failures at each invocation point. This test is based off the work from the test_alloc implementation. Signed-off-by: Andreas Hatziiliou --- Makefile | 34 ++++-- scripts/tests | 47 ++++++++ test/configs/configs.yml | 1 + test/mk/components.mk | 9 +- test/mk/rules.mk | 1 + test/src/test_rng_fail.c | 234 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 316 insertions(+), 10 deletions(-) create mode 100644 test/src/test_rng_fail.c diff --git a/Makefile b/Makefile index ac0289072d..2befb7b454 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,14 @@ # Copyright (c) The mlkem-native project authors # SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT -.PHONY: func kat acvp stack alloc \ - func_512 kat_512 acvp_512 stack_512 alloc_512 \ - func_768 kat_768 acvp_768 stack_768 alloc_768 \ - func_1024 kat_1024 acvp_1024 stack_1024 alloc_1024 \ - run_func run_kat run_acvp run_stack run_alloc \ - run_func_512 run_kat_512 run_stack_512 run_alloc_512 \ - run_func_768 run_kat_768 run_stack_768 run_alloc_768 \ - run_func_1024 run_kat_1024 run_stack_1024 run_alloc_1024 \ +.PHONY: func kat acvp stack alloc rng_fail \ + func_512 kat_512 acvp_512 stack_512 alloc_512 rng_fail_512 \ + func_768 kat_768 acvp_768 stack_768 alloc_768 rng_fail_768 \ + func_1024 kat_1024 acvp_1024 stack_1024 alloc_1024 rng_fail_1024 \ + run_func run_kat run_acvp run_stack run_alloc run_rng_fail \ + run_func_512 run_kat_512 run_stack_512 run_alloc_512 run_rng_fail_512 \ + run_func_768 run_kat_768 run_stack_768 run_alloc_768 run_rng_fail_768 \ + run_func_1024 run_kat_1024 run_stack_1024 run_alloc_1024 run_rng_fail_1024 \ bench_512 bench_768 bench_1024 bench \ run_bench_512 run_bench_768 run_bench_1024 run_bench \ bench_components_512 bench_components_768 bench_components_1024 bench_components \ @@ -47,7 +47,7 @@ quickcheck: test build: func kat acvp $(Q)echo " Everything builds fine!" -test: run_kat run_func run_acvp run_unit run_alloc +test: run_kat run_func run_acvp run_unit run_alloc run_rng_fail $(Q)echo " Everything checks fine!" # Detect available SHA256 command @@ -156,6 +156,22 @@ run_alloc_1024: alloc_1024 $(W) $(MLKEM1024_DIR)/bin/test_alloc1024 run_alloc: run_alloc_512 run_alloc_768 run_alloc_1024 +rng_fail_512: $(MLKEM512_DIR)/bin/test_rng_fail512 + $(Q)echo " RNG_FAIL ML-KEM-512: $^" +rng_fail_768: $(MLKEM768_DIR)/bin/test_rng_fail768 + $(Q)echo " RNG_FAIL ML-KEM-768: $^" +rng_fail_1024: $(MLKEM1024_DIR)/bin/test_rng_fail1024 + $(Q)echo " RNG_FAIL ML-KEM-1024: $^" +rng_fail: rng_fail_512 rng_fail_768 rng_fail_1024 + +run_rng_fail_512: rng_fail_512 + $(W) $(MLKEM512_DIR)/bin/test_rng_fail512 +run_rng_fail_768: rng_fail_768 + $(W) $(MLKEM768_DIR)/bin/test_rng_fail768 +run_rng_fail_1024: rng_fail_1024 + $(W) $(MLKEM1024_DIR)/bin/test_rng_fail1024 +run_rng_fail: run_rng_fail_512 run_rng_fail_768 run_rng_fail_1024 + lib: $(BUILD_DIR)/libmlkem.a $(BUILD_DIR)/libmlkem512.a $(BUILD_DIR)/libmlkem768.a $(BUILD_DIR)/libmlkem1024.a # Enforce setting CYCLES make variable when diff --git a/scripts/tests b/scripts/tests index 1e46db4dbb..89e269e1e2 100755 --- a/scripts/tests +++ b/scripts/tests @@ -212,6 +212,7 @@ class TEST_TYPES(Enum): BASIC_DETERMINISTIC = 18 UNIT = 19 ALLOC = 20 + RNG_FAIL = 21 def is_benchmark(self): return self in [TEST_TYPES.BENCH, TEST_TYPES.BENCH_COMPONENTS] @@ -288,6 +289,8 @@ class TEST_TYPES(Enum): return "Unit Test" if self == TEST_TYPES.ALLOC: return "Alloc Test" + if self == TEST_TYPES.RNG_FAIL: + return "RNG Failure Test" def make_dir(self): if self == TEST_TYPES.BRING_YOUR_OWN_FIPS202: @@ -355,6 +358,8 @@ class TEST_TYPES(Enum): return "unit" if self == TEST_TYPES.ALLOC: return "alloc" + if self == TEST_TYPES.RNG_FAIL: + return "rng_fail" def make_run_target(self, scheme): t = self.make_target() @@ -667,6 +672,19 @@ class Tests: self.check_fail() + def rng_fail(self): + def _rng_fail(opt): + self._compile_schemes(TEST_TYPES.RNG_FAIL, opt) + if self.args.run: + self._run_schemes(TEST_TYPES.RNG_FAIL, opt) + + if self.do_no_opt(): + _rng_fail(False) + if self.do_opt(): + _rng_fail(True) + + self.check_fail() + def acvp(self): def _acvp(opt): self._compile_schemes(TEST_TYPES.ACVP, opt) @@ -802,6 +820,7 @@ class Tests: stack = self.args.stack unit = self.args.unit alloc = self.args.alloc + rng_fail = self.args.rng_fail def _all(opt): if func is True: @@ -816,6 +835,8 @@ class Tests: self._compile_schemes(TEST_TYPES.UNIT, opt) if alloc is True: self._compile_schemes(TEST_TYPES.ALLOC, opt) + if rng_fail is True: + self._compile_schemes(TEST_TYPES.RNG_FAIL, opt) if self.args.check_namespace is True: p = subprocess.run( @@ -841,6 +862,8 @@ class Tests: self._run_schemes(TEST_TYPES.UNIT, opt) if alloc is True: self._run_schemes(TEST_TYPES.ALLOC, opt) + if rng_fail is True: + self._run_schemes(TEST_TYPES.RNG_FAIL, opt) if self.do_no_opt(): _all(False) @@ -1227,6 +1250,21 @@ def cli(): help="Do not run alloc tests", ) + rng_fail_group = all_parser.add_mutually_exclusive_group() + rng_fail_group.add_argument( + "--rng-fail", + action="store_true", + dest="rng_fail", + help="Run RNG failure tests", + default=True, + ) + rng_fail_group.add_argument( + "--no-rng-fail", + action="store_false", + dest="rng_fail", + help="Do not run RNG failure tests", + ) + # acvp arguments acvp_parser = cmd_subparsers.add_parser( "acvp", help="Run ACVP client", parents=[common_parser] @@ -1440,6 +1478,13 @@ def cli(): parents=[common_parser], ) + # rng_fail arguments + rng_fail_parser = cmd_subparsers.add_parser( + "rng_fail", + help="Run the RNG failure tests for all parameter sets", + parents=[common_parser], + ) + args = main_parser.parse_args() if not hasattr(args, "mac_taskpolicy"): @@ -1473,6 +1518,8 @@ def cli(): Tests(args).size() elif args.cmd == "alloc": Tests(args).alloc() + elif args.cmd == "rng_fail": + Tests(args).rng_fail() if __name__ == "__main__": diff --git a/test/configs/configs.yml b/test/configs/configs.yml index 195db1708a..177411cd09 100644 --- a/test/configs/configs.yml +++ b/test/configs/configs.yml @@ -449,3 +449,4 @@ configs: #endif /* !__ASSEMBLER__ */ MLK_CONFIG_FILE: comment: "/* No need to set this -- we _are_ already in a custom config */" + diff --git a/test/mk/components.mk b/test/mk/components.mk index 685cc1a1c7..49a904dab2 100644 --- a/test/mk/components.mk +++ b/test/mk/components.mk @@ -17,6 +17,7 @@ ACVP_TESTS = acvp_mlkem BENCH_TESTS = bench_mlkem bench_components_mlkem UNIT_TESTS = test_unit ALLOC_TESTS = test_alloc +RNG_FAIL_TESTS = test_rng_fail ALL_TESTS = $(BASIC_TESTS) $(ACVP_TESTS) $(BENCH_TESTS) $(UNIT_TESTS) $(ALLOC_TESTS) MLKEM512_DIR = $(BUILD_DIR)/mlkem512 @@ -46,7 +47,6 @@ $(MLKEM768_ALLOC_OBJS): CFLAGS += -DMLK_CONFIG_PARAMETER_SET=768 -DMLK_CONFIG_FI MLKEM1024_ALLOC_OBJS = $(call MAKE_OBJS,$(MLKEM1024_DIR)/alloc,$(SOURCES) $(FIPS202_SRCS)) $(MLKEM1024_ALLOC_OBJS): CFLAGS += -DMLK_CONFIG_PARAMETER_SET=1024 -DMLK_CONFIG_FILE=\"../test/configs/test_alloc_config.h\" - CFLAGS += -Imlkem $(BUILD_DIR)/libmlkem512.a: $(MLKEM512_OBJS) @@ -118,6 +118,12 @@ $(BUILD_DIR)/$(1)/bin/test_alloc$(subst mlkem,,$(1)): LDLIBS += -L$(BUILD_DIR) - $(BUILD_DIR)/$(1)/bin/test_alloc$(subst mlkem,,$(1)): $(BUILD_DIR)/$(1)/test/src/test_alloc.c.o $(BUILD_DIR)/lib$(1)_alloc.a $(call MAKE_OBJS, $(BUILD_DIR)/$(1), $(wildcard test/notrandombytes/*.c)) endef +# Special rule for test_rng_fail - link against rng_fail libraries with custom randombytes config +define ADD_SOURCE_RNG_FAIL +$(BUILD_DIR)/$(1)/bin/test_rng_fail$(subst mlkem,,$(1)): LDLIBS += -L$(BUILD_DIR) -l$(1) +$(BUILD_DIR)/$(1)/bin/test_rng_fail$(subst mlkem,,$(1)): $(BUILD_DIR)/$(1)/test/src/test_rng_fail.c.o $(BUILD_DIR)/lib$(1).a +endef + $(foreach scheme,mlkem512 mlkem768 mlkem1024, \ $(foreach test,$(ACVP_TESTS), \ $(eval $(call ADD_SOURCE,$(scheme),$(test),acvp)) \ @@ -130,6 +136,7 @@ $(foreach scheme,mlkem512 mlkem768 mlkem1024, \ ) \ $(eval $(call ADD_SOURCE_UNIT,$(scheme))) \ $(eval $(call ADD_SOURCE_ALLOC,$(scheme))) \ + $(eval $(call ADD_SOURCE_RNG_FAIL,$(scheme))) \ ) $(ALL_TESTS:%=$(MLKEM512_DIR)/bin/%512): $(call MAKE_OBJS, $(MLKEM512_DIR), $(wildcard test/notrandombytes/*.c) $(EXTRA_SOURCES)) diff --git a/test/mk/rules.mk b/test/mk/rules.mk index 5468fdab74..3f7f8bf310 100644 --- a/test/mk/rules.mk +++ b/test/mk/rules.mk @@ -111,3 +111,4 @@ $(BUILD_DIR)/mlkem1024/alloc/%.S.o: %.S $(CONFIG) $(Q)echo " AS $@" $(Q)[ -d $(@D) ] || mkdir -p $(@D) $(Q)$(CC) -c -o $@ $(CFLAGS) $< + diff --git a/test/src/test_rng_fail.c b/test/src/test_rng_fail.c new file mode 100644 index 0000000000..2d9612aad7 --- /dev/null +++ b/test/src/test_rng_fail.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) The mlkem-native project authors + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + */ +#include +#include +#include +#include + +/* Expose internal functions */ +#define MLK_BUILD_INTERNAL +#include "../../mlkem/mlkem_native.h" +#include "../../mlkem/src/common.h" + +/* + * This test checks that we handle randombytes failures correctly by: + * - Returning MLK_ERR_RNG_FAIL when randombytes fails + * + * This is done through a custom randombytes implementation that can be + * configured to fail at specific invocation counts. + */ + +/* + * Randombytes invocation tracker + */ + +int randombytes(uint8_t *out, size_t outlen); +int randombytes_counter = 0; +int randombytes_fail_on_counter = -1; + +static void reset_all(void) +{ + randombytes_counter = 0; + randombytes_fail_on_counter = -1; +} + +/* Basic pseudo-rng implementation using rand() */ +int randombytes(uint8_t *out, size_t outlen) +{ + int current_invocation = randombytes_counter++; + size_t i; + + if (current_invocation == randombytes_fail_on_counter) + { + return -1; + } + + /* Fill the output buffer with random bytes */ + for (i = 0; i < outlen; i++) + { + out[i] = (uint8_t)(((unsigned int)rand() * outlen) % 256); + } + + return 0; +} + +#define TEST_RNG_FAILURE(test_name, call) \ + do \ + { \ + int num_randombytes_calls, i, rc; \ + /* First pass: count randombytes invocations */ \ + reset_all(); \ + rc = call; \ + if (rc != 0) \ + { \ + fprintf(stderr, \ + "ERROR: %s failed with return code %d " \ + "in dry-run\n", \ + test_name, rc); \ + return 1; \ + } \ + num_randombytes_calls = randombytes_counter; \ + if (num_randombytes_calls == 0) \ + { \ + printf("Skipping %s (no randombytes() calls)\n", test_name); \ + break; \ + } \ + /* Second pass: test each randombytes failure */ \ + for (i = 0; i < num_randombytes_calls; i++) \ + { \ + reset_all(); \ + randombytes_fail_on_counter = i; \ + rc = call; \ + if (rc != MLK_ERR_RNG_FAIL) \ + { \ + int rc2; \ + /* Re-run to ensure clean state */ \ + reset_all(); \ + rc2 = call; \ + (void)rc2; \ + if (rc == 0) \ + { \ + fprintf(stderr, \ + "ERROR: %s unexpectedly succeeded when randombytes " \ + "%d/%d was instrumented to fail\n", \ + test_name, i + 1, num_randombytes_calls); \ + } \ + else \ + { \ + fprintf(stderr, \ + "ERROR: %s failed with wrong error code %d " \ + "(expected %d) when randombytes %d/%d was " \ + "instrumented to fail\n", \ + test_name, rc, MLK_ERR_RNG_FAIL, i + 1, \ + num_randombytes_calls); \ + } \ + return 1; \ + } \ + } \ + printf( \ + "RNG failure test for %s PASSED.\n" \ + " Tested %d randombytes invocation point(s)\n", \ + test_name, num_randombytes_calls); \ + } while (0) + +static int test_keygen_rng_failure(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + + TEST_RNG_FAILURE("crypto_kem_keypair", crypto_kem_keypair(pk, sk)); + return 0; +} + +static int test_enc_rng_failure(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + uint8_t ct[CRYPTO_CIPHERTEXTBYTES]; + uint8_t ss[CRYPTO_BYTES]; + + /* Generate valid keypair first */ + reset_all(); + if (crypto_kem_keypair(pk, sk) != 0) + { + fprintf(stderr, "ERROR: crypto_kem_keypair failed in enc test setup\n"); + return 1; + } + + TEST_RNG_FAILURE("crypto_kem_enc", crypto_kem_enc(ct, ss, pk)); + return 0; +} + +static int test_dec_rng_failure(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + uint8_t ct[CRYPTO_CIPHERTEXTBYTES]; + uint8_t ss_enc[CRYPTO_BYTES]; + uint8_t ss_dec[CRYPTO_BYTES]; + + /* Generate valid keypair and ciphertext first */ + reset_all(); + if (crypto_kem_keypair(pk, sk) != 0) + { + fprintf(stderr, "ERROR: crypto_kem_keypair failed in dec test setup\n"); + return 1; + } + + if (crypto_kem_enc(ct, ss_enc, pk) != 0) + { + fprintf(stderr, "ERROR: crypto_kem_enc failed in dec test setup\n"); + return 1; + } + + TEST_RNG_FAILURE("crypto_kem_dec", crypto_kem_dec(ss_dec, ct, sk)); + return 0; +} + +static int test_check_pk_rng_failure(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + + /* Generate valid keypair first */ + reset_all(); + if (crypto_kem_keypair(pk, sk) != 0) + { + fprintf(stderr, + "ERROR: crypto_kem_keypair failed in check_pk test setup\n"); + return 1; + } + + TEST_RNG_FAILURE("crypto_kem_check_pk", crypto_kem_check_pk(pk)); + return 0; +} + +static int test_check_sk_rng_failure(void) +{ + uint8_t pk[CRYPTO_PUBLICKEYBYTES]; + uint8_t sk[CRYPTO_SECRETKEYBYTES]; + + /* Generate valid keypair first */ + reset_all(); + if (crypto_kem_keypair(pk, sk) != 0) + { + fprintf(stderr, + "ERROR: crypto_kem_keypair failed in check_sk test setup\n"); + return 1; + } + + TEST_RNG_FAILURE("crypto_kem_check_sk", crypto_kem_check_sk(sk)); + return 0; +} + +int main(void) +{ + if (test_keygen_rng_failure() != 0) + { + return 1; + } + + if (test_enc_rng_failure() != 0) + { + return 1; + } + + if (test_dec_rng_failure() != 0) + { + return 1; + } + + if (test_check_pk_rng_failure() != 0) + { + return 1; + } + + if (test_check_sk_rng_failure() != 0) + { + return 1; + } + + return 0; +} From 5389be5d87dd2fe3d893e8802add82e8a3518266 Mon Sep 17 00:00:00 2001 From: Andreas Hatziiliou Date: Sun, 4 Jan 2026 20:36:16 -0500 Subject: [PATCH 3/3] testing: add rng failure test to CI Add the rng failure test to the CI. Signed-off-by: Andreas Hatziiliou --- .github/actions/config-variations/action.yml | 12 ++++++++++++ .github/actions/functest/action.yml | 8 ++++++-- .github/actions/multi-functest/action.yml | 12 ++++++++++++ .github/workflows/baremetal.yml | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/actions/config-variations/action.yml b/.github/actions/config-variations/action.yml index e66f5a255d..c0117826d6 100644 --- a/.github/actions/config-variations/action.yml +++ b/.github/actions/config-variations/action.yml @@ -65,6 +65,7 @@ runs: extra_env: 'ASAN_OPTIONS=detect_leaks=1' examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom zeroization (explicit_bzero)" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-zeroize') }} uses: ./.github/actions/multi-functest @@ -79,6 +80,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom native capability functions (static ON)" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'native-cap-ON') }} uses: ./.github/actions/multi-functest @@ -93,6 +95,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom native capability functions (static OFF)" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'native-cap-OFF') }} uses: ./.github/actions/multi-functest @@ -107,6 +110,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom native capability functions (ID_AA64PFR1_EL1 detection)" if: ${{ (inputs.tests == 'all' || contains(inputs.tests, 'native-cap-ID_AA64PFR1_EL1')) && runner.os == 'Linux' && runner.arch == 'ARM64' }} uses: ./.github/actions/multi-functest @@ -121,6 +125,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom native capability functions (CPUID AVX2 detection)" if: ${{ (inputs.tests == 'all' || contains(inputs.tests, 'native-cap-CPUID_AVX2')) && runner.os == 'Linux' && runner.arch == 'X64' }} uses: ./.github/actions/multi-functest @@ -135,6 +140,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "No ASM" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'no-asm') }} uses: ./.github/actions/multi-functest @@ -149,6 +155,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Serial FIPS202 (no batched Keccak)" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'serial-fips202') }} uses: ./.github/actions/multi-functest @@ -163,6 +170,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom randombytes" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-randombytes') }} uses: ./.github/actions/multi-functest @@ -177,6 +185,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom memcpy" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-memcpy') }} uses: ./.github/actions/multi-functest @@ -191,6 +200,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom memset" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-memset') }} uses: ./.github/actions/multi-functest @@ -205,6 +215,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "Custom stdlib (memcpy + memset)" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'custom-stdlib') }} uses: ./.github/actions/multi-functest @@ -219,6 +230,7 @@ runs: opt: ${{ inputs.opt }} examples: false # Some examples use a custom config themselves alloc: false # Requires custom config + rng_fail: false # Requires custom config - name: "MLKEM_GEN_MATRIX_NBLOCKS=1" if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'nblocks-1') }} uses: ./.github/actions/multi-functest diff --git a/.github/actions/functest/action.yml b/.github/actions/functest/action.yml index 50f227c2a1..b5d6ea023b 100644 --- a/.github/actions/functest/action.yml +++ b/.github/actions/functest/action.yml @@ -59,6 +59,9 @@ inputs: alloc: description: Determine whether to run alloc tests or not default: "true" + rng_fail: + description: Determine whether to run rng fail tests or not + default: "true" extra_args: description: Additional arguments to pass to the tests script default: "" @@ -80,6 +83,7 @@ runs: echo EXAMPLES="${{ inputs.examples == 'true' && 'examples' || 'no-examples' }}" >> $GITHUB_ENV echo STACK="${{ inputs.stack == 'true' && 'stack' || 'no-stack' }}" >> $GITHUB_ENV echo ALLOC="${{ inputs.alloc == 'true' && 'alloc' || 'no-alloc' }}" >> $GITHUB_ENV + echo RNGFAIL="${{ inputs.rng_fail == 'true' && 'rng-fail' || 'no-rng-fail' }}" >> $GITHUB_ENV - name: Setup nix uses: ./.github/actions/setup-shell with: @@ -110,11 +114,11 @@ runs: - $(python3 --version) - $(${{ inputs.cross_prefix }}${CC} --version | grep -m1 "") EOF - - name: ${{ env.MODE }} ${{ inputs.opt }} tests (${{ env.FUNC }}, ${{ env.KAT }}, ${{ env.EXAMPLES }}, ${{ env.STACK }}, ${{ env.UNIT }}, ${{ env.ALLOC }}) + - name: ${{ env.MODE }} ${{ inputs.opt }} tests (${{ env.FUNC }}, ${{ env.KAT }}, ${{ env.EXAMPLES }}, ${{ env.STACK }}, ${{ env.UNIT }}, ${{ env.ALLOC }}, ${{ env.RNGFAIL }}) shell: ${{ env.SHELL }} run: | make clean - ${{ inputs.extra_env }} ./scripts/tests all ${{ inputs.check_namespace == 'true' && '--check-namespace' || ''}} --exec-wrapper="${{ inputs.exec_wrapper }}" --cross-prefix="${{ inputs.cross_prefix }}" --cflags="${{ inputs.cflags }}" --ldflags="${{ inputs.ldflags }}" --opt=${{ inputs.opt }} --${{ env.FUNC }} --${{ env.KAT }} --${{ env.ACVP }} --${{ env.EXAMPLES }} --${{ env.STACK }} --${{ env.UNIT }} --${{ env.ALLOC }} -v ${{ inputs.extra_args }} + ${{ inputs.extra_env }} ./scripts/tests all ${{ inputs.check_namespace == 'true' && '--check-namespace' || ''}} --exec-wrapper="${{ inputs.exec_wrapper }}" --cross-prefix="${{ inputs.cross_prefix }}" --cflags="${{ inputs.cflags }}" --ldflags="${{ inputs.ldflags }}" --opt=${{ inputs.opt }} --${{ env.FUNC }} --${{ env.KAT }} --${{ env.ACVP }} --${{ env.EXAMPLES }} --${{ env.STACK }} --${{ env.UNIT }} --${{ env.ALLOC }} --${{ env.RNGFAIL }} -v ${{ inputs.extra_args }} - name: Post ${{ env.MODE }} Tests shell: ${{ env.SHELL }} if: success() || failure() diff --git a/.github/actions/multi-functest/action.yml b/.github/actions/multi-functest/action.yml index c5ce25a4c8..7435907e74 100644 --- a/.github/actions/multi-functest/action.yml +++ b/.github/actions/multi-functest/action.yml @@ -56,6 +56,9 @@ inputs: alloc: description: Determine whether to run alloc tests or not default: "true" + rng_fail: + description: Determine whether to run rng fail tests or not + default: "true" extra_args: description: Additional arguments to pass to the tests script default: "" @@ -85,6 +88,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross x86_64 Tests @@ -109,6 +113,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross aarch64 Tests @@ -133,6 +138,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross ppc64le Tests @@ -157,6 +163,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross aarch64_be Tests @@ -181,6 +188,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross riscv64 Tests (RVV, VLEN=128) @@ -205,6 +213,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross riscv64 Tests (RVV, VLEN=256) @@ -228,6 +237,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross riscv64 Tests (RVV, VLEN=512) @@ -251,6 +261,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross riscv64 Tests (RVV, VLEN=1024) @@ -274,6 +285,7 @@ runs: check_namespace: ${{ inputs.check_namespace }} stack: ${{ inputs.stack }} alloc: ${{ inputs.alloc }} + rng_fail: ${{ inputs.rng_fail }} extra_args: ${{ inputs.extra_args }} extra_env: ${{ inputs.extra_env }} - name: Cross riscv32 Tests diff --git a/.github/workflows/baremetal.yml b/.github/workflows/baremetal.yml index 95b35090e3..0957179c14 100644 --- a/.github/workflows/baremetal.yml +++ b/.github/workflows/baremetal.yml @@ -49,3 +49,4 @@ jobs: examples: false stack: false alloc: ${{ matrix.target.alloc }} + rng_fail: false