diff --git a/mldsa/src/sign.c b/mldsa/src/sign.c index 944c9477b..ed5d76f7c 100644 --- a/mldsa/src/sign.c +++ b/mldsa/src/sign.c @@ -432,6 +432,24 @@ __contract__( /* @[FIPS204, Appendix C]. */ #define MLD_NONCE_UB ((UINT16_MAX - MLDSA_L) / MLDSA_L) +#ifdef CBMC +static void mld_cbmc_workaround_8813(mld_polyvecl **p1, mld_polyveck **p2) +__contract__( + requires(memory_no_alias(p1, sizeof(mld_polyvecl *))) + requires(memory_no_alias(p2, sizeof(mld_polyveck *))) + requires(memory_no_alias(*p2, sizeof(mld_polyveck))) + requires(*p1 == *p2) + assigns(*p1) + assigns(*p2) + ensures(memory_no_alias(*p2, sizeof(mld_polyveck))) + ensures(*p1 == *p2) +) +{ + (void)p1; + (void)p2; +} +#endif /* CBMC */ + /************************************************* * Name: attempt_signature_generation * @@ -486,20 +504,33 @@ __contract__( uint32_t z_invalid, w0_invalid, h_invalid; int ret; MLD_ALLOC(challenge_bytes, uint8_t, MLDSA_CTILDEBYTES); - MLD_ALLOC(y, mld_polyvecl, 1); + typedef union + { + mld_polyvecl y; + mld_polyveck h; + } u_yh; + MLD_ALLOC(yh, u_yh, 1); MLD_ALLOC(z, mld_polyvecl, 1); MLD_ALLOC(w1, mld_polyveck, 1); MLD_ALLOC(w0, mld_polyveck, 1); - MLD_ALLOC(h, mld_polyveck, 1); MLD_ALLOC(cp, mld_poly, 1); + mld_polyvecl *y = &yh->y; + mld_polyveck *h = &yh->h; + +#ifdef CBMC + /* TODO: Remove once + * https://github.com/diffblue/cbmc/issues/8813 is resolved */ + mld_cbmc_workaround_8813(&y, &h); +#endif - if (challenge_bytes == NULL || y == NULL || z == NULL || w1 == NULL || - w0 == NULL || h == NULL || cp == NULL) + if (challenge_bytes == NULL || yh == NULL || z == NULL || w1 == NULL || + w0 == NULL || cp == NULL) { ret = MLD_ERR_OUT_OF_MEMORY; goto cleanup; } + /* Sample intermediate vector y */ mld_polyvecl_uniform_gamma1(y, rhoprime, nonce); @@ -611,11 +642,10 @@ __contract__( cleanup: /* @[FIPS204, Section 3.6.3] Destruction of intermediate values. */ MLD_FREE(challenge_bytes, uint8_t, MLDSA_CTILDEBYTES); - MLD_FREE(y, mld_polyvecl, 1); + MLD_FREE(yh, u_yh, 1); MLD_FREE(z, mld_polyvecl, 1); MLD_FREE(w1, mld_polyveck, 1); MLD_FREE(w0, mld_polyveck, 1); - MLD_FREE(h, mld_polyveck, 1); MLD_FREE(cp, mld_poly, 1); return ret; diff --git a/proofs/cbmc/attempt_signature_generation/Makefile b/proofs/cbmc/attempt_signature_generation/Makefile index dc518af3d..d5d887fe5 100644 --- a/proofs/cbmc/attempt_signature_generation/Makefile +++ b/proofs/cbmc/attempt_signature_generation/Makefile @@ -43,7 +43,7 @@ USE_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)polyvecl_uniform_gamma1 \ $(MLD_NAMESPACE)polyveck_add \ $(MLD_NAMESPACE)polyveck_make_hint \ $(MLD_NAMESPACE)pack_sig -USE_FUNCTION_CONTRACTS+=mld_zeroize +USE_FUNCTION_CONTRACTS+=mld_zeroize mld_cbmc_workaround_8813 APPLY_LOOP_CONTRACTS=on USE_DYNAMIC_FRAMES=1 diff --git a/proofs/cbmc/cbmc_workaround_8813/Makefile b/proofs/cbmc/cbmc_workaround_8813/Makefile new file mode 100644 index 000000000..d61a5f7c9 --- /dev/null +++ b/proofs/cbmc/cbmc_workaround_8813/Makefile @@ -0,0 +1,58 @@ +# Copyright (c) The mldsa-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +include ../Makefile_params.common + +HARNESS_ENTRY = harness +HARNESS_FILE = cbmc_workaround_8813_harness + +# This should be a unique identifier for this proof, and will appear on the +# Litani dashboard. It can be human-readable and contain spaces if you wish. +PROOF_UID = mld_cbmc_workaround_8813 + +DEFINES += +INCLUDES += + +REMOVE_FUNCTION_BODY += +UNWINDSET += + +PROOF_SOURCES += $(PROOFDIR)/$(HARNESS_FILE).c +PROJECT_SOURCES += $(SRCDIR)/mldsa/src/sign.c + +CHECK_FUNCTION_CONTRACTS=mld_cbmc_workaround_8813 +USE_FUNCTION_CONTRACTS= + +APPLY_LOOP_CONTRACTS=on +USE_DYNAMIC_FRAMES=1 + +# Disable any setting of EXTERNAL_SAT_SOLVER, and choose SMT backend instead +EXTERNAL_SAT_SOLVER= +CBMCFLAGS=--smt2 +CBMCFLAGS += --slice-formula +CBMCFLAGS += --no-array-field-sensitivity + +FUNCTION_NAME = mld_cbmc_workaround_8813 + +# If this proof is found to consume huge amounts of RAM, you can set the +# EXPENSIVE variable. With new enough versions of the proof tools, this will +# restrict the number of EXPENSIVE CBMC jobs running at once. See the +# documentation in Makefile.common under the "Job Pools" heading for details. +# EXPENSIVE = true + +# This function is large enough to need... +CBMC_OBJECT_BITS = 12 + +# If you require access to a file-local ("static") function or object to conduct +# your proof, set the following (and do not include the original source file +# ("mldsa/poly.c") in PROJECT_SOURCES). +# REWRITTEN_SOURCES = $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i +# include ../Makefile.common +# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_SOURCE = $(SRCDIR)/mldsa/src/poly.c +# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_FUNCTIONS = foo bar +# $(PROOFDIR)/<__SOURCE_FILE_BASENAME__>.i_OBJECTS = baz +# Care is required with variables on the left-hand side: REWRITTEN_SOURCES must +# be set before including Makefile.common, but any use of variables on the +# left-hand side requires those variables to be defined. Hence, _SOURCE, +# _FUNCTIONS, _OBJECTS is set after including Makefile.common. + +include ../Makefile.common diff --git a/proofs/cbmc/cbmc_workaround_8813/cbmc_workaround_8813_harness.c b/proofs/cbmc/cbmc_workaround_8813/cbmc_workaround_8813_harness.c new file mode 100644 index 000000000..8701a5d3c --- /dev/null +++ b/proofs/cbmc/cbmc_workaround_8813/cbmc_workaround_8813_harness.c @@ -0,0 +1,14 @@ +// Copyright (c) The mldsa-native project authors +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +#include "sign.h" + +void mld_cbmc_workaround_8813(mld_polyvecl **p1, mld_polyveck **p2); + +void harness(void) +{ + mld_polyvecl **p1; + mld_polyveck **p2; + + mld_cbmc_workaround_8813(p1, p2); +}