diff --git a/libcrux-ml-kem/cg/eurydice_glue.h b/libcrux-ml-kem/cg/eurydice_glue.h index bc07ba4b9..cdd27af77 100644 --- a/libcrux-ml-kem/cg/eurydice_glue.h +++ b/libcrux-ml-kem/cg/eurydice_glue.h @@ -164,7 +164,7 @@ static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { #define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ (((iter_ptr)->start == (iter_ptr)->end) \ - ? (CLITERAL(ret_t){.tag = None}) \ + ? (CLITERAL(ret_t){.tag = None, .f0 = 0}) \ : (CLITERAL(ret_t){.tag = Some, .f0 = (iter_ptr)->start++})) #define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A__TraitClause_0___6__next \ diff --git a/libcrux-ml-kem/cg/fuzz/.gitignore b/libcrux-ml-kem/cg/fuzz/.gitignore new file mode 100644 index 000000000..d28f1baa8 --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/.gitignore @@ -0,0 +1,5 @@ +dec_fuzz +enc_fuzz +mkcorpus +valid_fuzz +*.o diff --git a/libcrux-ml-kem/cg/fuzz/Makefile b/libcrux-ml-kem/cg/fuzz/Makefile new file mode 100644 index 000000000..bf98a1b02 --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/Makefile @@ -0,0 +1,35 @@ +CC=clang-18 +CXX=clang++-18 +FUZZ_FLAGS=-fsanitize=address,undefined,fuzzer -fno-omit-frame-pointer +FUZZ_LIBS=-L/usr/lib/llvm-18/lib -lFuzzer + +CXXFLAGS=-O2 -g -Wall -Wextra -Wno-unused-parameter -Wno-exceptions -I.. +CFLAGS=$(CXXFLAGS) +LDFLAGS=-g +LIBS= +COMMON_DEPS= + +TARGETS=enc_fuzz valid_fuzz dec_fuzz mkcorpus + +all: $(TARGETS) + +.cc.o: + $(CXX) $(CXXFLAGS) $(FUZZ_FLAGS) -c $< -o $@ + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +enc_fuzz: enc_fuzz.o $(COMMON_DEPS) + $(CXX) -o $@ enc_fuzz.o $(LDFLAGS) $(LIBS) $(FUZZ_FLAGS) $(FUZZ_LIBS) + +dec_fuzz: dec_fuzz.o $(COMMON_DEPS) + $(CXX) -o $@ dec_fuzz.o $(LDFLAGS) $(LIBS) $(FUZZ_FLAGS) $(FUZZ_LIBS) + +valid_fuzz: valid_fuzz.o $(COMMON_DEPS) + $(CXX) -o $@ valid_fuzz.o $(LDFLAGS) $(LIBS) $(FUZZ_FLAGS) $(FUZZ_LIBS) + +mkcorpus: mkcorpus.o + $(CC) -o $@ mkcorpus.o + +clean: + -rm -f *.o $(TARGETS) diff --git a/libcrux-ml-kem/cg/fuzz/dec_fuzz.cc b/libcrux-ml-kem/cg/fuzz/dec_fuzz.cc new file mode 100644 index 000000000..f6b35097d --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/dec_fuzz.cc @@ -0,0 +1,52 @@ +// Basic fuzz test for depcapsulate operation, + +#include +#include +#include +#include +#include +#include + +#include "libcrux_mlkem768_portable.h" + +extern "C" +{ + + void privkeys(libcrux_ml_kem_types_MlKemPrivateKey_55 *zero_sk, + libcrux_ml_kem_types_MlKemPrivateKey_55 *rnd_sk) + { + uint8_t rnd[64]; + memset(rnd, 0, sizeof(rnd)); + auto kp = libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair(rnd); + *zero_sk = kp.sk; + (void)getentropy(rnd, sizeof(rnd)); + kp = libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair(rnd); + *rnd_sk = kp.sk; + } + + int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len) + { + static bool once; + uint8_t ret[32]; + libcrux_ml_kem_types_MlKemPrivateKey_55 zero_sk, rnd_sk; + libcrux_ml_kem_mlkem768_MlKem768Ciphertext ct; + + if (!once) + { + privkeys(&zero_sk, &rnd_sk); + once = true; + } + + memset(&ct, 0, sizeof(ct)); + if (len > sizeof(ct.value)) + { + len = sizeof(ct.value); + } + memcpy(ct.value, input, len); + + libcrux_ml_kem_mlkem768_portable_decapsulate(&zero_sk, &ct, ret); + libcrux_ml_kem_mlkem768_portable_decapsulate(&rnd_sk, &ct, ret); + return 0; + } + +} // extern diff --git a/libcrux-ml-kem/cg/fuzz/enc_fuzz.cc b/libcrux-ml-kem/cg/fuzz/enc_fuzz.cc new file mode 100644 index 000000000..1cf5f9d2c --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/enc_fuzz.cc @@ -0,0 +1,34 @@ +// Basic fuzz test for encapsulate operation. + +#include +#include +#include +#include +#include +#include + +#include "libcrux_mlkem768_portable.h" + +extern "C" +{ + + int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len) + { + uint8_t rnd[32]; + libcrux_ml_kem_mlkem768_MlKem768PublicKey pk; + + memset(rnd, 0, sizeof(rnd)); + memset(&pk, 0, sizeof(pk)); + if (len > sizeof(pk.value)) + { + len = sizeof(pk.value); + } + memcpy(pk.value, input, len); + + (void)libcrux_ml_kem_mlkem768_portable_encapsulate(&pk, rnd); + (void)getentropy(rnd, sizeof(rnd)); + (void)libcrux_ml_kem_mlkem768_portable_encapsulate(&pk, rnd); + return 0; + } + +} // extern diff --git a/libcrux-ml-kem/cg/fuzz/mkcorpus.c b/libcrux-ml-kem/cg/fuzz/mkcorpus.c new file mode 100644 index 000000000..b681e2fb3 --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/mkcorpus.c @@ -0,0 +1,65 @@ +// Makes basic seed corpora for other fuzzers +// +// Will write to ./pubkey_corpus (for valid_fuzz and enc_fuzz) and +// to ./ciphertext_corpus (for dec_fuzz) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libcrux_mlkem768_portable.h" + +#define NSEEDS 1000 + +void write_blob(const char *path, int n, const char *suffix, const void *p, + size_t l) { + char name[256]; + FILE *f; + + snprintf(name, sizeof(name), "%s/%06d.%s", path, n, suffix); + if ((f = fopen(name, "wb+")) == NULL) { + err(1, "fopen %s", name); + } + if (fwrite(p, l, 1, f) != 1) { + err(1, "write %s", name); + } + fclose(f); +} + +int main(void) { + int i; + uint8_t rnd[64]; + libcrux_ml_kem_mlkem768_MlKem768KeyPair kp; + tuple_3c enc; + + if (mkdir("pubkey_corpus", 0777) != 0 && errno != EEXIST) + err(1, "mkdir pubkey_corpus"); + if (mkdir("ciphertext_corpus", 0777) != 0 && errno != EEXIST) + err(1, "mkdir ciphertext_corpus"); + + for (i = 0; i < NSEEDS; i++) { + if (i == 0) { + memset(rnd, 0, sizeof(rnd)); + } else { + (void)getentropy(rnd, sizeof(rnd)); + } + kp = libcrux_ml_kem_mlkem768_portable_kyber_generate_key_pair(rnd); + write_blob("pubkey_corpus", i, "pk", kp.pk.value, sizeof(kp.pk.value)); + + if (i == 0) { + memset(rnd, 0, sizeof(rnd)); + } else { + (void)getentropy(rnd, sizeof(rnd)); + } + enc = libcrux_ml_kem_mlkem768_portable_encapsulate(&kp.pk, rnd); + write_blob("ciphertext_corpus", i, "ct", enc.fst.value, + sizeof(enc.fst.value)); + } + return 0; +} diff --git a/libcrux-ml-kem/cg/fuzz/valid_fuzz.cc b/libcrux-ml-kem/cg/fuzz/valid_fuzz.cc new file mode 100644 index 000000000..44c34945b --- /dev/null +++ b/libcrux-ml-kem/cg/fuzz/valid_fuzz.cc @@ -0,0 +1,32 @@ +// Basic fuzz test for pubkey validation. + +#include +#include +#include +#include +#include +#include + +#include "libcrux_mlkem768_portable.h" + +extern "C" +{ + + int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len) + { + uint8_t rnd[32]; + libcrux_ml_kem_mlkem768_MlKem768PublicKey pk; + + memset(rnd, 0, sizeof(rnd)); + memset(&pk, 0, sizeof(pk)); + if (len > sizeof(pk.value)) + { + len = sizeof(pk.value); + } + memcpy(pk.value, input, len); + + (void)libcrux_ml_kem_mlkem768_portable_validate_public_key(&pk); + return 0; + } + +} // extern