From dd7ec129af2ba83d77cf68554d1d6f41b3bb2550 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 30 Jan 2025 01:23:26 -0600 Subject: [PATCH 1/2] fixes for gating/tooling around ASCON. --- CMakeLists.txt | 1 + wolfcrypt/test/test.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bb9e7dbba..19f3819642 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2488,6 +2488,7 @@ if(WOLFSSL_EXAMPLES) # Build unit tests add_executable(unit_test tests/api.c + tests/api/ascon.c tests/hash.c tests/srp.c tests/suites.c diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f50905e5b3..53897c9a0f 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -598,8 +598,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes192_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesofb_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void); +#ifdef HAVE_ASCON WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_hash256_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_aead128_test(void); +#endif #if defined(WOLFSSL_SIPHASH) WOLFSSL_TEST_SUBROUTINE wc_test_ret_t siphash_test(void); #endif From 0de38040f48647a3c91f52bc9b0f2cc4bd2af436 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 30 Jan 2025 01:24:40 -0600 Subject: [PATCH 2/2] CT tweaks: in wolfcrypt/src/coding.c, add ALIGN64 to hexDecode[], and add hexEncode[] for use by Base16_Encode(); in wolfcrypt/src/misc.c and wolfssl/wolfcrypt/misc.h: move ctMask*() up so that min() and max() can use them, and add ctMaskWord32GTE(); add ALIGN64 to kHexChar[]; add CT implementation of CharIsWhiteSpace(); remove min_size_t() and max_size_t() recently added, but only one user (refactored). --- src/internal.c | 3 +- wolfcrypt/src/coding.c | 18 ++- wolfcrypt/src/misc.c | 263 +++++++++++++++++++++------------------ wolfcrypt/src/sp_int.c | 2 +- wolfssl/wolfcrypt/misc.h | 5 +- 5 files changed, 153 insertions(+), 138 deletions(-) diff --git a/src/internal.c b/src/internal.c index 6bf9e06ea2..17098ee220 100644 --- a/src/internal.c +++ b/src/internal.c @@ -25852,7 +25852,8 @@ int ReceiveData(WOLFSSL* ssl, byte* output, size_t sz, int peek) #endif } - size = (int)min_size_t(sz, (size_t)ssl->buffers.clearOutputBuffer.length); + size = (sz < (size_t)ssl->buffers.clearOutputBuffer.length) ? + (int)sz : (int)ssl->buffers.clearOutputBuffer.length; XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size); diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index a0691cf9bc..571f90f182 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -490,7 +490,7 @@ int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen) #ifdef WOLFSSL_BASE16 static -const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +const ALIGN64 byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, BAD, BAD, BAD, BAD, BAD, BAD, BAD, 10, 11, 12, 13, 14, 15, /* upper case A-F */ BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, @@ -556,6 +556,11 @@ int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) return 0; } +static +const ALIGN64 byte hexEncode[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) { word32 outIdx = 0; @@ -571,15 +576,8 @@ int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) byte hb = in[i] >> 4; byte lb = in[i] & 0x0f; - /* ASCII value */ - hb = (byte)(hb + '0'); - if (hb > '9') - hb = (byte)(hb + 7U); - - /* ASCII value */ - lb = (byte)(lb + '0'); - if (lb>'9') - lb = (byte)(lb + 7U); + hb = hexEncode[hb]; + lb = hexEncode[lb]; out[outIdx++] = hb; out[outIdx++] = lb; diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index 92d4bd3022..5af55ec674 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -506,6 +506,125 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, } #endif +#ifndef WOLFSSL_NO_CT_OPS +/* Constant time - mask set when a > b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b) +{ + return (byte)((((word32)a - (word32)b - 1) >> 31) - 1); +} + +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskGTE(int a, int b) +{ + return (byte)((((word32)a - (word32)b) >> 31) - 1); +} + +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b) +{ + return (int)((((word32)a - (word32)b) >> 31) - 1); +} + +#ifdef WORD64_AVAILABLE +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE word32 ctMaskWord32GTE(word32 a, word32 b) +{ + return (word32)((((word64)a - (word64)b) >> 63) - 1); +} +#endif + +/* Constant time - mask set when a < b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskLT(int a, int b) +{ + return (byte)((((word32)b - (word32)a - 1) >> 31) - 1); +} + +/* Constant time - mask set when a <= b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskLTE(int a, int b) +{ + return (byte)((((word32)b - (word32)a) >> 31) - 1); +} + +/* Constant time - mask set when a == b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskEq(int a, int b) +{ + return (byte)((byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b))); +} + +/* Constant time - sets 16 bit integer mask when a > b */ +WC_MISC_STATIC WC_INLINE word16 ctMask16GT(int a, int b) +{ + return (word16)((((word32)a - (word32)b - 1) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a >= b */ +WC_MISC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b) +{ + return (word16)((((word32)a - (word32)b) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a < b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16LT(int a, int b) +{ + return (word16)((((word32)b - (word32)a - 1) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a <= b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b) +{ + return (word16)((((word32)b - (word32)a) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a == b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b) +{ + return (word16)((word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b))); +} + +/* Constant time - mask set when a != b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b) +{ + return (byte)((byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b)); +} + +/* Constant time - select a when mask is set and b otherwise. */ +WC_MISC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b) +{ + return (byte)((b & ((byte)~(word32)m)) | (a & m)); +} + +/* Constant time - select integer a when mask is set and integer b otherwise. */ +WC_MISC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b) +{ + return (b & (~(signed int)(signed char)m)) | + (a & ( (signed int)(signed char)m)); +} + +/* Constant time - select word32 a when mask is set and word32 b otherwise. */ +WC_MISC_STATIC WC_INLINE word32 ctMaskSelWord32(byte m, word32 a, word32 b) +{ + return (((word32)b & (word32)(~(signed int)(signed char)m)) | + ((word32)a & (word32)( (signed int)(signed char)m))); +} + +/* Constant time - bit set when a <= b. */ +WC_MISC_STATIC WC_INLINE byte ctSetLTE(int a, int b) +{ + return (byte)(((word32)a - (word32)b - 1) >> 31); +} + +/* Constant time - conditionally copy size bytes from src to dst if mask is set + */ +WC_MISC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src, + word16 size) +{ + int i; + for (i = 0; i < size; ++i) { + dst[i] ^= (dst[i] ^ src[i]) & mask; + } +} + +#endif /* !WOLFSSL_NO_CT_OPS */ #ifndef WOLFSSL_HAVE_MIN #define WOLFSSL_HAVE_MIN @@ -515,15 +634,15 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, /* returns the smaller of a and b */ WC_MISC_STATIC WC_INLINE word32 min(word32 a, word32 b) { +#if !defined(WOLFSSL_NO_CT_OPS) && defined(WORD64_AVAILABLE) + word32 gte_mask = (word32)ctMaskWord32GTE(a, b); + return (a & ~gte_mask) | (b & gte_mask); +#else /* WOLFSSL_NO_CT_OPS */ return a > b ? b : a; +#endif /* WOLFSSL_NO_CT_OPS */ } #endif /* !WOLFSSL_HAVE_MIN */ - WC_MISC_STATIC WC_INLINE size_t min_size_t(size_t a, size_t b) - { - return a > b ? b : a; - } - #ifndef WOLFSSL_HAVE_MAX #define WOLFSSL_HAVE_MAX #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */ @@ -531,15 +650,15 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, #endif WC_MISC_STATIC WC_INLINE word32 max(word32 a, word32 b) { +#if !defined(WOLFSSL_NO_CT_OPS) && defined(WORD64_AVAILABLE) + word32 gte_mask = (word32)ctMaskWord32GTE(a, b); + return (a & gte_mask) | (b & ~gte_mask); +#else /* WOLFSSL_NO_CT_OPS */ return a > b ? a : b; +#endif /* WOLFSSL_NO_CT_OPS */ } #endif /* !WOLFSSL_HAVE_MAX */ - WC_MISC_STATIC WC_INLINE size_t max_size_t(size_t a, size_t b) - { - return a > b ? a : b; - } - #ifndef WOLFSSL_NO_INT_ENCODE /* converts a 32 bit integer to 24 bit */ WC_MISC_STATIC WC_INLINE void c32to24(word32 in, word24 out) @@ -641,8 +760,10 @@ WC_MISC_STATIC WC_INLINE signed char HexCharToByte(char ch) WC_MISC_STATIC WC_INLINE char ByteToHex(byte in) { - static const char kHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static ALIGN64 const char kHexChar[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; return (char)(kHexChar[in & 0xF]); } @@ -658,6 +779,11 @@ WC_MISC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out) WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch) { +#ifndef WOLFSSL_NO_CT_OPS + return (ctMaskEq(ch, ' ') | + ctMaskEq(ch, '\t') | + ctMaskEq(ch, '\n')) & 1; +#else /* WOLFSSL_NO_CT_OPS */ switch (ch) { case ' ': case '\t': @@ -666,120 +792,9 @@ WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch) default: return 0; } +#endif /* WOLFSSL_NO_CT_OPS */ } -#ifndef WOLFSSL_NO_CT_OPS -/* Constant time - mask set when a > b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b) -{ - return (byte)((((word32)a - (word32)b - 1) >> 31) - 1); -} - -/* Constant time - mask set when a >= b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskGTE(int a, int b) -{ - return (byte)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - mask set when a >= b. */ -WC_MISC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b) -{ - return (int)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - mask set when a < b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskLT(int a, int b) -{ - return (byte)((((word32)b - (word32)a - 1) >> 31) - 1); -} - -/* Constant time - mask set when a <= b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskLTE(int a, int b) -{ - return (byte)((((word32)b - (word32)a) >> 31) - 1); -} - -/* Constant time - mask set when a == b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskEq(int a, int b) -{ - return (byte)((byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b))); -} - -/* Constant time - sets 16 bit integer mask when a > b */ -WC_MISC_STATIC WC_INLINE word16 ctMask16GT(int a, int b) -{ - return (word16)((((word32)a - (word32)b - 1) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a >= b */ -WC_MISC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b) -{ - return (word16)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a < b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16LT(int a, int b) -{ - return (word16)((((word32)b - (word32)a - 1) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a <= b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b) -{ - return (word16)((((word32)b - (word32)a) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a == b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b) -{ - return (word16)((word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b))); -} - -/* Constant time - mask set when a != b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b) -{ - return (byte)((byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b)); -} - -/* Constant time - select a when mask is set and b otherwise. */ -WC_MISC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b) -{ - return (byte)((b & ((byte)~(word32)m)) | (a & m)); -} - -/* Constant time - select integer a when mask is set and integer b otherwise. */ -WC_MISC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b) -{ - return (b & (~(signed int)(signed char)m)) | - (a & ( (signed int)(signed char)m)); -} - -/* Constant time - select word32 a when mask is set and word32 b otherwise. */ -WC_MISC_STATIC WC_INLINE word32 ctMaskSelWord32(byte m, word32 a, word32 b) -{ - return (((word32)b & (word32)(~(signed int)(signed char)m)) | - ((word32)a & (word32)( (signed int)(signed char)m))); -} - -/* Constant time - bit set when a <= b. */ -WC_MISC_STATIC WC_INLINE byte ctSetLTE(int a, int b) -{ - return (byte)(((word32)a - (word32)b - 1) >> 31); -} - -/* Constant time - conditionally copy size bytes from src to dst if mask is set - */ -WC_MISC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src, - word16 size) -{ - int i; - for (i = 0; i < size; ++i) { - dst[i] ^= (dst[i] ^ src[i]) & mask; - } -} - -#endif - #if defined(WOLFSSL_W64_WRAPPER) #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST) WC_MISC_STATIC WC_INLINE void w64Increment(w64wrapper *n) { diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index caf666b62e..efdcdb0cb6 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -8016,7 +8016,7 @@ int sp_submod(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r) } #endif /* WOLFSSL_SP_MATH_ALL */ -/* Constant time clamping/ +/* Constant time clamping. * * @param [in, out] a SP integer to clamp. */ diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 9f195c6888..561c9a2b97 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -107,7 +107,6 @@ void ByteReverseWords64(word64* out, const word64* in, word32 byteCount); #endif WOLFSSL_LOCAL word32 min(word32 a, word32 b); #endif -WOLFSSL_LOCAL size_t min_size_t(size_t a, size_t b); #ifndef WOLFSSL_HAVE_MAX #if defined(HAVE_FIPS) && !defined(max) /* so ifdef check passes */ @@ -115,7 +114,6 @@ WOLFSSL_LOCAL size_t min_size_t(size_t a, size_t b); #endif WOLFSSL_LOCAL word32 max(word32 a, word32 b); #endif /* WOLFSSL_HAVE_MAX */ -WOLFSSL_LOCAL size_t max_size_t(size_t a, size_t b); void c32to24(word32 in, word24 out); @@ -136,6 +134,9 @@ WOLFSSL_LOCAL int CharIsWhiteSpace(char ch); WOLFSSL_LOCAL byte ctMaskGT(int a, int b); WOLFSSL_LOCAL byte ctMaskGTE(int a, int b); WOLFSSL_LOCAL int ctMaskIntGTE(int a, int b); +#ifdef WORD64_AVAILABLE +WOLFSSL_LOCAL word32 ctMaskWord32GTE(word32 a, word32 b); +#endif WOLFSSL_LOCAL byte ctMaskLT(int a, int b); WOLFSSL_LOCAL byte ctMaskLTE(int a, int b); WOLFSSL_LOCAL byte ctMaskEq(int a, int b);