From 86b39cf8879a2c2179d7af32cd325d1267e799a1 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:17:08 -0500 Subject: [PATCH] Fix windows-x86 and arm compiling error. (#1634) * Fix windows-x86 and arm compiling error. --------- Co-authored-by: Norman Ashley --- CMakeLists.txt | 2 +- README.md | 2 +- .../copy_from_upstream/copy_from_upstream.py | 2 +- src/common/sha2/sha2_armv8.c | 110 +++++++++--------- src/oqsconfig.h.cmake | 2 + src/sig_stfl/lms/sig_stfl_lms.h | 4 +- src/sig_stfl/sig_stfl.h | 14 +-- src/sig_stfl/xmss/external/xmss_commons.c | 14 ++- src/sig_stfl/xmss/external/xmss_core_fast.c | 69 ++++++----- tests/helpers.py | 3 +- tests/test_sig_stfl.c | 17 ++- 11 files changed, 132 insertions(+), 107 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b353a24461..e3003eb897 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,13 +196,13 @@ endif() if(OQS_ENABLE_SIG_SPHINCS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/sphincs/sig_sphincs.h) endif() +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END if(OQS_ENABLE_SIG_STFL_XMSS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/xmss/sig_stfl_xmss.h) endif() if(OQS_ENABLE_SIG_STFL_LMS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/lms/sig_stfl_lms.h) endif() -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PUBLIC_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${INTERNAL_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) diff --git a/README.md b/README.md index a9331e7022..a93d18f737 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,9 @@ All names other than `ML-KEM` and `ML-DSA` are subject to change. `liboqs` makes - **ML-DSA**: ML-DSA-44-ipd (alias: ML-DSA-44), ML-DSA-65-ipd (alias: ML-DSA-65), ML-DSA-87-ipd (alias: ML-DSA-87) - **SPHINCS+-SHA2**: SPHINCS+-SHA2-128f-simple, SPHINCS+-SHA2-128s-simple, SPHINCS+-SHA2-192f-simple, SPHINCS+-SHA2-192s-simple, SPHINCS+-SHA2-256f-simple, SPHINCS+-SHA2-256s-simple - **SPHINCS+-SHAKE**: SPHINCS+-SHAKE-128f-simple, SPHINCS+-SHAKE-128s-simple, SPHINCS+-SHAKE-192f-simple, SPHINCS+-SHAKE-192s-simple, SPHINCS+-SHAKE-256f-simple, SPHINCS+-SHAKE-256s-simple + - **XMSS**: XMSS-SHA2_10_256, XMSS-SHA2_16_256, XMSS-SHA2_20_256, XMSS-SHAKE_10_256, XMSS-SHAKE_16_256, XMSS-SHAKE_20_256, XMSS-SHA2_10_512, XMSS-SHA2_16_512, XMSS-SHA2_20_512, XMSS-SHAKE_10_512, XMSS-SHAKE_16_512, XMSS-SHAKE_20_512, XMSSMT-SHA2_20/2_256, XMSSMT-SHA2_20/4_256, XMSSMT-SHA2_40/2_256, XMSSMT-SHA2_40/4_256, XMSSMT-SHA2_40/8_256, XMSSMT-SHA2_60/3_256, XMSSMT-SHA2_60/6_256, XMSSMT-SHA2_60/12_256, XMSSMT-SHAKE_20/2_256, XMSSMT-SHAKE_20/4_256, XMSSMT-SHAKE_40/2_256, XMSSMT-SHAKE_40/4_256, XMSSMT-SHAKE_40/8_256, XMSSMT-SHAKE_60/3_256, XMSSMT-SHAKE_60/6_256, XMSSMT-SHAKE_60/12_256 - **LMS**: LMS_SHA256_H5_W1, LMS_SHA256_H5_W2, LMS_SHA256_H5_W4, LMS_SHA256_H5_W8, LMS_SHA256_H10_W1, LMS_SHA256_H10_W2, LMS_SHA256_H10_W4, LMS_SHA256_H10_W8, LMS_SHA256_H15_W1, LMS_SHA256_H15_W2, LMS_SHA256_H15_W4, LMS_SHA256_H15_W8, LMS_SHA256_H20_W1, LMS_SHA256_H20_W2, LMS_SHA256_H20_W4, LMS_SHA256_H20_W8, LMS_SHA256_H25_W1, LMS_SHA256_H25_W2, LMS_SHA256_H25_W4, LMS_SHA256_H25_W8, LMS_SHA256_H5_W8_H5_W8, LMS_SHA256_H10_W4_H5_W8, LMS_SHA256_H10_W8_H5_W8, LMS_SHA256_H10_W2_H10_W2, LMS_SHA256_H10_W4_H10_W4, LMS_SHA256_H10_W8_H10_W8, LMS_SHA256_H15_W8_H5_W8, LMS_SHA256_H15_W8_H10_W8, LMS_SHA256_H15_W8_H15_W8, LMS_SHA256_H20_W8_H5_W8, LMS_SHA256_H20_W8_H10_W8, LMS_SHA256_H20_W8_H15_W8, LMS_SHA256_H20_W8_H20_W8 - Note that for algorithms marked with a dagger (†), liboqs contains at least one implementation that uses a large amount of stack space; this may cause failures when run in threads or in constrained environments. For more information, consult the algorithm information sheets in the [docs/algorithms](https://github.com/open-quantum-safe/liboqs/tree/main/docs/algorithms) folder. diff --git a/scripts/copy_from_upstream/copy_from_upstream.py b/scripts/copy_from_upstream/copy_from_upstream.py index 0db38f54bf..9c4f8f2232 100755 --- a/scripts/copy_from_upstream/copy_from_upstream.py +++ b/scripts/copy_from_upstream/copy_from_upstream.py @@ -642,7 +642,7 @@ def verify_from_upstream(): '{}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) verifydir = os.path.join(basedir, 'src', family['type'], family['name'], '{}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) - if not os.path.isdir(oqsdir) and os.path.isdir(erifydir): + if not os.path.isdir(oqsdir) and os.path.isdir(verifydir): print('Available implementation in upstream that isn\'t integrated into LIBOQS: {}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) else: diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index b8f6b16cb3..dc8661485b 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -15,7 +15,6 @@ * from http://bench.cr.yp.to/supercop.html * by D. J. Bernstein */ - static uint64_t load_bigendian_64(const uint8_t *x) { return (uint64_t)(x[7]) | (((uint64_t)(x[6])) << 8) | (((uint64_t)(x[5])) << 16) | (((uint64_t)(x[4])) << 24) | @@ -24,21 +23,21 @@ static uint64_t load_bigendian_64(const uint8_t *x) { } static void store_bigendian_64(uint8_t *x, uint64_t u) { - x[7] = (uint8_t) u; + x[7] = (uint8_t)u; u >>= 8; - x[6] = (uint8_t) u; + x[6] = (uint8_t)u; u >>= 8; - x[5] = (uint8_t) u; + x[5] = (uint8_t)u; u >>= 8; - x[4] = (uint8_t) u; + x[4] = (uint8_t)u; u >>= 8; - x[3] = (uint8_t) u; + x[3] = (uint8_t)u; u >>= 8; - x[2] = (uint8_t) u; + x[2] = (uint8_t)u; u >>= 8; - x[1] = (uint8_t) u; + x[1] = (uint8_t)u; u >>= 8; - x[0] = (uint8_t) u; + x[0] = (uint8_t)u; } static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, @@ -63,9 +62,9 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, }; unsigned long long pos = 0; /* load constants */ - uint32x4_t c0 = vld1q_u32(s256cst + 0); - uint32x4_t c1 = vld1q_u32(s256cst + 4); - uint32x4_t c2 = vld1q_u32(s256cst + 8); + uint32x4_t c0 = vld1q_u32(s256cst + 0); + uint32x4_t c1 = vld1q_u32(s256cst + 4); + uint32x4_t c2 = vld1q_u32(s256cst + 8); uint32x4_t c3 = vld1q_u32(s256cst + 12); uint32x4_t c4 = vld1q_u32(s256cst + 16); uint32x4_t c5 = vld1q_u32(s256cst + 20); @@ -80,13 +79,13 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, uint32x4_t ce = vld1q_u32(s256cst + 56); uint32x4_t cf = vld1q_u32(s256cst + 60); /* load state */ - uint32x4_t d0 = vld1q_u32((uint32_t *)(statebytes + 0)); + uint32x4_t d0 = vld1q_u32((uint32_t *)(statebytes + 0)); uint32x4_t d1 = vld1q_u32((uint32_t *)(statebytes + 16)); uint32x4_t s0, s1, h0, h1; /* make state big-endian */ d0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d0))); d1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d1))); - while (length >= 64) { + while (length >= 64) { /* load one block */ uint32x4_t i0 = vld1q_u32((const uint32_t *)(data + pos + 0)); uint32x4_t i1 = vld1q_u32((const uint32_t *)(data + pos + 16)); @@ -110,33 +109,33 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, * using 16 constants in c0..c3 * we need h0,h1,x0,x1 as scratch */ -#define DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3) \ - h0 = vaddq_u32(i0, c0); \ - x0 = vsha256hq_u32(s0, s1, h0); \ - x1 = vsha256h2q_u32(s1, s0, h0); \ - h1 = vaddq_u32(i1, c1); \ - s0 = vsha256hq_u32(x0, x1, h1); \ - s1 = vsha256h2q_u32(x1, x0, h1); \ - h0 = vaddq_u32(i2, c2); \ - x0 = vsha256hq_u32(s0, s1, h0); \ - x1 = vsha256h2q_u32(s1, s0, h0); \ - h1 = vaddq_u32(i3, c3); \ - s0 = vsha256hq_u32(x0, x1, h1); \ - s1 = vsha256h2q_u32(x1, x0, h1) +#define DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3) \ + h0 = vaddq_u32(i0, c0); \ + x0 = vsha256hq_u32(s0, s1, h0); \ + x1 = vsha256h2q_u32(s1, s0, h0); \ + h1 = vaddq_u32(i1, c1); \ + s0 = vsha256hq_u32(x0, x1, h1); \ + s1 = vsha256h2q_u32(x1, x0, h1); \ + h0 = vaddq_u32(i2, c2); \ + x0 = vsha256hq_u32(s0, s1, h0); \ + x1 = vsha256h2q_u32(s1, s0, h0); \ + h1 = vaddq_u32(i3, c3); \ + s0 = vsha256hq_u32(x0, x1, h1); \ + s1 = vsha256h2q_u32(x1, x0, h1) /* * this expands the block (or previously * expanded) in i0..i3 to j0..j3 */ #define DO16EXPANDS(i0, i1, i2, i3, j0, j1, j2, j3) \ - j0 = vsha256su0q_u32(i0, i1); \ - j0 = vsha256su1q_u32(j0, i2, i3); \ - j1 = vsha256su0q_u32(i1, i2); \ - j1 = vsha256su1q_u32(j1, i3, j0); \ - j2 = vsha256su0q_u32(i2, i3); \ - j2 = vsha256su1q_u32(j2, j0, j1); \ - j3 = vsha256su0q_u32(i3, j0); \ - j3 = vsha256su1q_u32(j3, j1, j2) + j0 = vsha256su0q_u32(i0, i1); \ + j0 = vsha256su1q_u32(j0, i2, i3); \ + j1 = vsha256su0q_u32(i1, i2); \ + j1 = vsha256su1q_u32(j1, i3, j0); \ + j2 = vsha256su0q_u32(i2, i3); \ + j2 = vsha256su1q_u32(j2, j0, j1); \ + j3 = vsha256su0q_u32(i3, j0); \ + j3 = vsha256su1q_u32(j3, j1, j2) DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3); @@ -163,11 +162,10 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, /* store back to little-endian */ d0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d0))); d1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d1))); - vst1q_u32((uint32_t *)(statebytes + 0), d0); + vst1q_u32((uint32_t *)(statebytes + 0), d0); vst1q_u32((uint32_t *)(statebytes + 16), d1); return length; - } void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen) { @@ -180,7 +178,8 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui if (new_inlen == inlen) { new_in = in; - } else { //Combine incremental data with final input + } else { + // Combine incremental data with final input tmp_in = malloc(tmp_len); if (tmp_in == NULL) { exit(111); @@ -201,7 +200,6 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui new_inlen &= 63; new_in -= new_inlen; - for (size_t i = 0; i < new_inlen; ++i) { padded[i] = new_in[i]; } @@ -211,27 +209,27 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui for (size_t i = new_inlen + 1; i < 56; ++i) { padded[i] = 0; } - padded[56] = (uint8_t) (bytes >> 53); - padded[57] = (uint8_t) (bytes >> 45); - padded[58] = (uint8_t) (bytes >> 37); - padded[59] = (uint8_t) (bytes >> 29); - padded[60] = (uint8_t) (bytes >> 21); - padded[61] = (uint8_t) (bytes >> 13); - padded[62] = (uint8_t) (bytes >> 5); - padded[63] = (uint8_t) (bytes << 3); + padded[56] = (uint8_t)(bytes >> 53); + padded[57] = (uint8_t)(bytes >> 45); + padded[58] = (uint8_t)(bytes >> 37); + padded[59] = (uint8_t)(bytes >> 29); + padded[60] = (uint8_t)(bytes >> 21); + padded[61] = (uint8_t)(bytes >> 13); + padded[62] = (uint8_t)(bytes >> 5); + padded[63] = (uint8_t)(bytes << 3); crypto_hashblocks_sha256_armv8(state->ctx, padded, 64); } else { for (size_t i = new_inlen + 1; i < 120; ++i) { padded[i] = 0; } - padded[120] = (uint8_t) (bytes >> 53); - padded[121] = (uint8_t) (bytes >> 45); - padded[122] = (uint8_t) (bytes >> 37); - padded[123] = (uint8_t) (bytes >> 29); - padded[124] = (uint8_t) (bytes >> 21); - padded[125] = (uint8_t) (bytes >> 13); - padded[126] = (uint8_t) (bytes >> 5); - padded[127] = (uint8_t) (bytes << 3); + padded[120] = (uint8_t)(bytes >> 53); + padded[121] = (uint8_t)(bytes >> 45); + padded[122] = (uint8_t)(bytes >> 37); + padded[123] = (uint8_t)(bytes >> 29); + padded[124] = (uint8_t)(bytes >> 21); + padded[125] = (uint8_t)(bytes >> 13); + padded[126] = (uint8_t)(bytes >> 5); + padded[127] = (uint8_t)(bytes << 3); crypto_hashblocks_sha256_armv8(state->ctx, padded, 128); } @@ -314,7 +312,7 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) } void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) { - oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *) state, in, inblocks); + oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *)state, in, inblocks); } void oqs_sha2_sha256_armv8(uint8_t *out, const uint8_t *in, size_t inlen) { diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 7fdfd7bdb9..9d533a8b27 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -221,6 +221,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 1 #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 + #cmakedefine OQS_ENABLE_SIG_STFL_LMS 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 1 @@ -235,3 +236,4 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 + diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index b583782e64..4405e60c1c 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -251,8 +251,8 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void); -OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 70797ee80a..a0691a9d59 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -485,7 +485,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); * @param[in] lock function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); /** * OQS_SIG_STFL_SECRET_KEY_SET_unlock . @@ -496,7 +496,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock * @param[in] unlock function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); /** * OQS_SIG_STFL_SECRET_KEY_SET_mutex . @@ -507,7 +507,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key * @param[in] mutex function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); /** * OQS_SIG_STFL_SECRET_KEY_lock . @@ -518,7 +518,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex) * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock * */ -OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_unlock . @@ -529,7 +529,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock * */ -OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . @@ -543,7 +543,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); * Applications allocates, tracks, deallocates this. Signature generation fails without this set. * */ -void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); /** * OQS_SECRET_KEY_STFL_serialize_key . @@ -572,7 +572,7 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); #if defined(__cplusplus) -} // extern "C" +// extern "C" #endif #endif /* OQS_SIG_STATEFUL_H */ diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 9838f755b0..5f3818d184 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -151,8 +151,8 @@ int xmssmt_core_sign_open(const xmss_params *params, unsigned char *root = leaf + params->n; unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; - + unsigned long long m_with_prefix_len = mlen + prefix_length; + unsigned char *m_with_prefix = NULL; unsigned char *mhash = root; unsigned long long idx = 0; unsigned int i, ret; @@ -169,13 +169,18 @@ int xmssmt_core_sign_open(const xmss_params *params, // Unused since smlen is a constant (void) smlen; + if ((m_with_prefix_len == 0) || (m_with_prefix = malloc(m_with_prefix_len)) == NULL){ + ret = -1; + goto fail; + } + /* Convert the index bytes from the signature to an integer. */ idx = bytes_to_ull(sm, params->index_bytes); /* Put the message at the m_with_prefix buffer, so that we can * prepend the required other inputs for the hash function. */ - memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); - memcpy(m_with_prefix + prefix_length, m, mlen); + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); + memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); /* Compute the message hash. */ hash_message(params, mhash, sm + params->index_bytes, pk, idx, @@ -221,6 +226,7 @@ int xmssmt_core_sign_open(const xmss_params *params, ret = 0; fail: OQS_MEM_insecure_free(tmp); + OQS_MEM_insecure_free(m_with_prefix); return ret; } diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index deaedefa8a..70b4b9774e 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -13,7 +13,7 @@ typedef struct{ unsigned char h; - unsigned long next_idx; + unsigned long long next_idx; unsigned char stackusage; unsigned char completed; unsigned char *node; @@ -27,7 +27,7 @@ typedef struct { unsigned char *keep; treehash_inst *treehash; unsigned char *retain; - unsigned int next_leaf; + unsigned long long next_leaf; } bds_state; /* These serialization functions provide a transition between the current @@ -94,7 +94,7 @@ static void xmssmt_deserialize_state(const xmss_params *params, states[i].stack = sk; sk += (params->tree_height + 1) * params->n; - states[i].stackoffset = bytes_to_ull(sk, 4); + states[i].stackoffset = (unsigned int)bytes_to_ull(sk, 4); sk += 4; states[i].stacklevels = sk; @@ -107,16 +107,16 @@ static void xmssmt_deserialize_state(const xmss_params *params, sk += (params->tree_height >> 1) * params->n; for (j = 0; j < params->tree_height - params->bds_k; j++) { - states[i].treehash[j].h = bytes_to_ull(sk, 1); + states[i].treehash[j].h = (unsigned char)bytes_to_ull(sk, 1); sk += 1; - states[i].treehash[j].next_idx = bytes_to_ull(sk, 4); + states[i].treehash[j].next_idx = (unsigned long long)bytes_to_ull(sk, 4); sk += 4; - states[i].treehash[j].stackusage = bytes_to_ull(sk, 1); + states[i].treehash[j].stackusage = (unsigned char)bytes_to_ull(sk, 1); sk += 1; - states[i].treehash[j].completed = bytes_to_ull(sk, 1); + states[i].treehash[j].completed = (unsigned char)bytes_to_ull(sk, 1); sk += 1; states[i].treehash[j].node = sk; @@ -126,7 +126,7 @@ static void xmssmt_deserialize_state(const xmss_params *params, states[i].retain = sk; sk += ((1 << params->bds_k) - params->bds_k - 1) * params->n; - states[i].next_leaf = bytes_to_ull(sk, 4); + states[i].next_leaf = (unsigned long long)bytes_to_ull(sk, 4); sk += 4; } @@ -149,9 +149,9 @@ static void xmss_deserialize_state(const xmss_params *params, static void memswap(void *a, void *b, void *t, unsigned long long len) { - memcpy(t, a, len); - memcpy(a, b, len); - memcpy(b, t, len); + memcpy(t, a, (size_t)len); + memcpy(a, b, (size_t)len); + memcpy(b, t, (size_t)len); } /** @@ -637,7 +637,7 @@ int xmss_core_sign(const xmss_params *params, // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); - memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + memset(sk + params->index_bytes, 0, (size_t)(params->sk_bytes - params->index_bytes)); if (idx > ((1ULL << params->full_height) - 1)) { ret = -2; // We already used all one-time keys goto cleanup; @@ -682,9 +682,9 @@ int xmss_core_sign(const xmss_params *params, /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char *m_with_prefix = malloc(mlen + prefix_length); - memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); - memcpy(m_with_prefix + prefix_length, m, mlen); + unsigned char *m_with_prefix = malloc((size_t)(mlen + prefix_length)); + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); + memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); /* Compute the message hash. */ hash_message(params, msg_h, R, pub_root, idx, @@ -717,7 +717,7 @@ int xmss_core_sign(const xmss_params *params, // Prepare Address set_type(ots_addr, 0); - set_ots_addr(ots_addr, idx); + set_ots_addr(ots_addr, (uint32_t) idx); // Compute WOTS signature wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr); @@ -728,8 +728,8 @@ int xmss_core_sign(const xmss_params *params, // the auth path was already computed during the previous round memcpy(sm, state.auth, params->tree_height*params->n); - if (idx < (1U << params->tree_height) - 1) { - bds_round(params, &state, idx, sk_seed, pub_seed, ots_addr); + if (idx < (1ULL << params->tree_height) - 1) { + bds_round(params, &state, (const unsigned long)idx, sk_seed, pub_seed, ots_addr); bds_treehash_update(params, &state, (params->tree_height - params->bds_k) >> 1, sk_seed, pub_seed, ots_addr); } @@ -829,7 +829,7 @@ int xmssmt_core_sign(const xmss_params *params, uint64_t idx_tree; uint32_t idx_leaf; - uint64_t i, j; + unsigned int i, j; int needswap_upto = -1; unsigned int updates; @@ -847,7 +847,8 @@ int xmssmt_core_sign(const xmss_params *params, unsigned char *wots_sigs = NULL; unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; + unsigned long long m_with_prefix_len = mlen + prefix_length; + unsigned char *m_with_prefix = NULL; int ret = 0; // TODO refactor BDS state not to need separate treehash instances @@ -864,6 +865,11 @@ int xmssmt_core_sign(const xmss_params *params, states[i].next_leaf = 0; } + if ((m_with_prefix_len == 0) || (m_with_prefix = malloc(m_with_prefix_len)) == NULL) { + ret = -1; + goto cleanup; + } + xmssmt_deserialize_state(params, states, &wots_sigs, sk); // Extract SK @@ -887,7 +893,7 @@ int xmssmt_core_sign(const xmss_params *params, // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); - memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + memset(sk + params->index_bytes, 0, (size_t)(params->sk_bytes - params->index_bytes)); if (idx > ((1ULL << params->full_height) - 1)) { // We already used all one-time keys ret = -2; @@ -895,9 +901,9 @@ int xmssmt_core_sign(const xmss_params *params, } } - memcpy(sk_seed, sk+params->index_bytes, params->n); - memcpy(sk_prf, sk+params->index_bytes+params->n, params->n); - memcpy(pub_seed, sk+params->index_bytes+3*params->n, params->n); + memcpy(sk_seed, sk+params->index_bytes, (size_t)params->n); + memcpy(sk_prf, sk+params->index_bytes+params->n, (size_t)params->n); + memcpy(pub_seed, sk+params->index_bytes+3*params->n, (size_t)params->n); // Update SK for (i = 0; i < params->index_bytes; i++) { @@ -991,24 +997,24 @@ int xmssmt_core_sign(const xmss_params *params, set_tree_addr(addr, (idx_tree + 1)); // mandatory update for NEXT_0 (does not count towards h-k/2) if NEXT_0 exists - if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << params->full_height)) { + if ((1 + idx_tree) * (1ULL << params->tree_height) + idx_leaf < (1ULL << (unsigned long long) params->full_height)) { bds_state_update(params, &states[params->d], sk_seed, pub_seed, addr); } for (i = 0; i < params->d; i++) { // check if we're not at the end of a tree if (! (((idx + 1) & ((1ULL << ((i+1)*params->tree_height)) - 1)) == 0)) { - idx_leaf = (idx >> (params->tree_height * i)) & ((1 << params->tree_height)-1); + idx_leaf = (uint32_t)((idx >> (params->tree_height * i)) & ((1 << params->tree_height)-1)); idx_tree = (idx >> (params->tree_height * (i+1))); set_layer_addr(addr, i); - set_tree_addr(addr, idx_tree); + set_tree_addr(addr, (uint32_t)idx_tree); if (i == (unsigned int) (needswap_upto + 1)) { bds_round(params, &states[i], idx_leaf, sk_seed, pub_seed, addr); } updates = bds_treehash_update(params, &states[i], updates, sk_seed, pub_seed, addr); set_tree_addr(addr, (idx_tree + 1)); // if a NEXT-tree exists for this level; - if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << (params->full_height - params->tree_height * i))) { + if ((1 + idx_tree) * (1ULL << params->tree_height) + idx_leaf < (1ULL << (params->full_height - params->tree_height * i))) { if (i > 0 && updates > 0 && states[params->d + i].next_leaf < (1ULL << params->full_height)) { bds_state_update(params, &states[params->d + i], sk_seed, pub_seed, addr); updates--; @@ -1018,9 +1024,9 @@ int xmssmt_core_sign(const xmss_params *params, else if (idx < (1ULL << params->full_height) - 1) { deep_state_swap(params, &states[params->d + i], &states[i]); - set_layer_addr(ots_addr, (i+1)); + set_layer_addr(ots_addr, (uint32_t)(i+1)); set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height))); - set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1 << params->tree_height)-1))); + set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1ULL << params->tree_height)-1))); wots_sign(params, wots_sigs + i*params->wots_sig_bytes, states[i].stack, sk_seed, pub_seed, ots_addr); @@ -1028,7 +1034,7 @@ int xmssmt_core_sign(const xmss_params *params, states[params->d + i].next_leaf = 0; updates--; // WOTS-signing counts as one update - needswap_upto = i; + needswap_upto = (int)i; for (j = 0; j < params->tree_height-params->bds_k; j++) { states[i].treehash[j].completed = 1; } @@ -1041,6 +1047,7 @@ int xmssmt_core_sign(const xmss_params *params, OQS_MEM_insecure_free(treehash); OQS_MEM_insecure_free(states); OQS_MEM_insecure_free(tmp); + OQS_MEM_insecure_free(m_with_prefix); return ret; } diff --git a/tests/helpers.py b/tests/helpers.py index b911f5d9bd..077b4d428f 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -175,7 +175,8 @@ def path_to_executable(program_name): for executable in [ os.path.join(path, program_name), os.path.join(path, program_name + ".EXE"), - os.path.join(path, program_name + ".exe")]: + os.path.join(path, program_name + ".exe"), + os.path.join(path, "Debug", program_name + ".exe"),]: if os.path.isfile(executable): return executable assert False, "Unable to find executable file {}".format(program_name) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a3d4bfd3f5..a8b3e7962d 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -7,10 +7,14 @@ #include #include #include +#if defined(_WIN32) #include +#define strcasecmp _stricmp +#else +#include +#endif #include -#include #include #include "tmp_store.c" @@ -1100,10 +1104,17 @@ int main(int argc, char **argv) { OQS_MEM_insecure_free(lock_test_context); OQS_MEM_insecure_free(signature_1); OQS_MEM_insecure_free(signature_2); - if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS || - rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { + + OQS_destroy(); + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { return EXIT_FAILURE; } + +#if OQS_USE_PTHREADS_IN_TESTS + if (rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { + return EXIT_FAILURE; + } +#endif return exit_status; #else rc = sig_stfl_test_correctness(alg_name, katfile);