Skip to content

Commit c99bd22

Browse files
committed
Harden ConstantCompare() and use it for the ATECC GCM tag check
1 parent 5c9b8c3 commit c99bd22

7 files changed

Lines changed: 20 additions & 6 deletions

File tree

‎.wolfssl_known_macro_extras‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,7 @@ WOLFSSL_NO_CHACHA20_POLY1305_FUSED_IFMA
10581058
WOLFSSL_NO_CHACHA20_POLY1305_SHORT
10591059
WOLFSSL_NO_CHACHA20_POLY1305_SMALL_ASM
10601060
WOLFSSL_NO_CLIENT_CERT_ERROR
1061+
WOLFSSL_NO_CONST_CMP
10611062
WOLFSSL_NO_COPY_CERT
10621063
WOLFSSL_NO_COPY_KEY
10631064
WOLFSSL_NO_CRL_DATE_CHECK

‎ChangeLog.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@
112112
one wider than the modulus, instead of computing a result. by @stenslae
113113
(PR 11159)
114114

115+
* **Behavioral change (`WOLFSSL_NO_CONST_CMP`)**: no longer defined
116+
automatically. The minimal `WOLFCRYPT_ONLY` builds that got it now define
117+
`WC_NO_CONST_CMP_API` instead, which leaves out only the exported
118+
`wc_ConstantCompare()`; the internal `ConstantCompare()` stays available to
119+
RSA, ECC and its other callers. by @stenslae (PR 11159)
120+
115121
## Post-Quantum Cryptography (PQC)
116122

117123
* Added opt-in per-key Falcon signing caches (`--enable-falcon=cache-key`, `cache-basis`), roughly doubling signing speed with the default integer fpr backend. by @Frauschi
@@ -127,6 +133,7 @@
127133
* ECCSI signing (`wc_SignEccsiHash()`) now blinds its modular inverse instead of inverting the secret value directly. by @stenslae (PR 11159)
128134
* SAKKE RSK derivation now blinds the inverse of a + z_T, which involves the KMS master secret. by @stenslae (PR 11159)
129135
* Heap-math (`--enable-heapmath`) `mp_addmod_ct()`, `mp_submod_ct()` and `mp_div_2_mod_ct()` no longer branch on the values or limb counts of reduced operands. by @stenslae (PR 11159)
136+
* The ATECC GCM tag check now compares in constant time with `ConstantCompare()`, whose loads are now volatile so it cannot be compiled to an early-exit compare. by @stenslae (PR 11159)
130137

131138
* Fixed `wc_AsconAEAD128_SetAD` called more than once: the function
132139
absorbs the key, nonce and associated data into the sponge state and then

‎wolfcrypt/src/memory.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,7 @@ void wc_ForceZero(void *mem, size_t len)
17371737
}
17381738
#endif
17391739

1740-
#ifndef WOLFSSL_NO_CONST_CMP
1740+
#if !defined(WOLFSSL_NO_CONST_CMP) && !defined(WC_NO_CONST_CMP_API)
17411741
/* Exported version of ConstantCompare(). */
17421742
int wc_ConstantCompare(const byte* a, const byte* b, int length)
17431743

‎wolfcrypt/src/misc.c‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,9 +832,13 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b,
832832
{
833833
int i;
834834
int compareSum = 0;
835+
/* Volatile loads keep the compiler from turning this into an early-exit
836+
* memcmp() or a vectorised compare-and-branch. */
837+
const volatile byte* va = (const volatile byte*)a;
838+
const volatile byte* vb = (const volatile byte*)b;
835839

836840
for (i = 0; i < length; i++) {
837-
compareSum |= a[i] ^ b[i];
841+
compareSum |= va[i] ^ vb[i];
838842
}
839843

840844
return compareSum;

‎wolfcrypt/src/port/atmel/atmel.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2037,7 +2037,7 @@ static int wc_Microchip_AesGcmCommon(Aes* aes, byte* out, const byte* in,
20372037
in, sz, out, tag_buf);
20382038
if (status == ATCA_SUCCESS) {
20392039
copy_sz = authTagSz;
2040-
if (XMEMCMP(tag_buf, authTag, copy_sz) != 0) {
2040+
if (ConstantCompare(tag_buf, authTag, (int)copy_sz) != 0) {
20412041
return AES_GCM_AUTH_E;
20422042
}
20432043
}

‎wolfssl/wolfcrypt/memory.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ WOLFSSL_LOCAL void wc_MemZero_Check(void* addr, size_t len);
335335
WOLFSSL_API void wc_ForceZero(void *mem, size_t len);
336336
#endif
337337

338-
#ifndef WOLFSSL_NO_CONST_CMP
338+
#if !defined(WOLFSSL_NO_CONST_CMP) && !defined(WC_NO_CONST_CMP_API)
339339
WOLFSSL_API int wc_ConstantCompare(const byte* a, const byte* b, int length);
340340
#endif
341341

‎wolfssl/wolfcrypt/settings.h‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5312,10 +5312,12 @@ blinding by defining WC_BLINDING_NO_RNG_ACKNOWLEDGE_WEAKNESS."
53125312
#define WOLFSSL_NO_CT_OPS
53135313
#endif
53145314

5315+
/* Minimal wolfCrypt-only builds leave out the exported wc_ConstantCompare().
5316+
* The internal ConstantCompare() stays available to its callers. */
53155317
#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(HAVE_CURVE25519) && \
53165318
!defined(HAVE_CURVE448) && defined(WC_NO_RNG) && defined(WC_NO_RSA_OAEP)
5317-
#undef WOLFSSL_NO_CONST_CMP
5318-
#define WOLFSSL_NO_CONST_CMP
5319+
#undef WC_NO_CONST_CMP_API
5320+
#define WC_NO_CONST_CMP_API
53195321
#endif
53205322

53215323
#if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(WOLFSSL_SHA384) && \

0 commit comments

Comments
 (0)