Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -27309,6 +27309,7 @@ static int test_wolfSSL_dup_CA_list(void)
return res;
}

#ifndef WOLFSSL_NO_FORCE_ZERO
static int test_ForceZero(void)
{
EXPECT_DECLS;
Expand Down Expand Up @@ -27339,6 +27340,7 @@ static int test_ForceZero(void)

return EXPECT_RESULT();
}
#endif /* !WOLFSSL_NO_FORCE_ZERO */

#ifndef NO_BIO

Expand Down Expand Up @@ -36864,7 +36866,9 @@ TEST_CASE testCases[] = {
* wolfcrypt
*********************************/

#ifndef WOLFSSL_NO_FORCE_ZERO
TEST_DECL(test_ForceZero),
#endif

TEST_DECL(test_wolfCrypt_Init),

Expand Down
7 changes: 7 additions & 0 deletions tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -10583,7 +10583,9 @@ static int test_CryptoCb_Aes_Cb(int devId, wc_CryptoInfo* info, void* ctx)

if (aes != NULL && aes->devCtx == cryptoCbAesMockHandle) {
/* "Delete" key from simulated SE */
#ifndef WOLFSSL_NO_FORCE_ZERO
ForceZero(&mockSeKey, sizeof(mockSeKey));
#endif
cryptoCbAesFreeCalled++;
}

Expand Down Expand Up @@ -10963,7 +10965,9 @@ static int test_CryptoCb_AesGcm_Offload_Cb(int devId, wc_CryptoInfo* info, void*

if (aes != NULL && aes->devCtx == cryptoCbAesGcmMockHandle) {
/* "Delete" key from simulated SE */
#ifndef WOLFSSL_NO_FORCE_ZERO
ForceZero(&mockSeKeyOffload, sizeof(mockSeKeyOffload));
#endif
cryptoCbAesGcmFreeCalled++;
}

Expand Down Expand Up @@ -11619,8 +11623,11 @@ static int test_Tls13Zero_CryptoCb(int devId, wc_CryptoInfo* info, void* ctx)

Aes* aes = (Aes*)info->free.obj;
if (aes != NULL && aes->devCtx != NULL) {
#ifndef WOLFSSL_NO_FORCE_ZERO
Tls13ZeroKeySlot* slot = (Tls13ZeroKeySlot*)aes->devCtx;
/* slot is static; zero, don't free. */
ForceZero(slot, sizeof(*slot));
#endif
aes->devCtx = NULL;
}
return 0;
Expand Down
4 changes: 4 additions & 0 deletions tests/api/test_tls13.c
Original file line number Diff line number Diff line change
Expand Up @@ -7111,12 +7111,16 @@ int test_tls13_fragmented_session_ticket(void)
if (EXPECT_SUCCESS() && ssl_c->arrays != NULL) {
/* Zero before freeing so WOLFSSL_CHECK_MEM_ZERO builds don't abort. */
if (ssl_c->arrays->preMasterSecret != NULL) {
#ifndef WOLFSSL_NO_FORCE_ZERO
ForceZero(ssl_c->arrays->preMasterSecret, ENCRYPT_LEN);
#endif
XFREE(ssl_c->arrays->preMasterSecret, ssl_c->heap,
DYNAMIC_TYPE_SECRET);
ssl_c->arrays->preMasterSecret = NULL;
}
#ifndef WOLFSSL_NO_FORCE_ZERO
ForceZero(ssl_c->arrays, sizeof(Arrays));
#endif
XFREE(ssl_c->arrays, ssl_c->heap, DYNAMIC_TYPE_ARRAYS);
ssl_c->arrays = NULL;
}
Expand Down
14 changes: 8 additions & 6 deletions wolfcrypt/src/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -693,10 +693,12 @@ WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count)
with zeros. It ensures compiler optimization doesn't skip it. */
WC_MISC_STATIC WC_INLINE void ForceZero(void* mem, size_t len)
{
byte *zb = (byte *)mem;
unsigned long *zl;
/* Volatile pointers prevent dead-store elimination.
* WC_BARRIER() prevents compiler reordering. */
volatile byte *zb = (volatile byte *)mem;
volatile unsigned long *zl;

XFENCE();
WC_BARRIER();

while ((wc_ptr_t)zb & (wc_ptr_t)(sizeof(unsigned long) - 1U)) {
if (len == 0)
Expand All @@ -705,21 +707,21 @@ WC_MISC_STATIC WC_INLINE void ForceZero(void* mem, size_t len)
--len;
}

zl = (unsigned long *)zb;
zl = (volatile unsigned long *)zb;

while (len >= sizeof(unsigned long)) {
*zl++ = 0;
len -= sizeof(unsigned long);
}

zb = (byte *)zl;
zb = (volatile byte *)zl;

while (len) {
*zb++ = 0;
--len;
}

XFENCE();
WC_BARRIER();
}
#endif

Expand Down
53 changes: 53 additions & 0 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,11 @@ typedef struct testVector {
#ifndef WC_TEST_EXPORT_SUBTESTS

WOLFSSL_TEST_SUBROUTINE wc_test_ret_t macro_test(void);
/* Under NO_INLINE, ForceZero() is WOLFSSL_LOCAL (hidden visibility) inside
* libwolfssl and unreachable from this separate test binary. */
#if !defined(WOLFSSL_NO_FORCE_ZERO) && !defined(NO_INLINE)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t forcezero_test(void);
#endif
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void);
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base64_test(void);
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base16_test(void);
Expand Down Expand Up @@ -2409,6 +2414,13 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
else
TEST_PASS("macro test passed!\n");

#if !defined(WOLFSSL_NO_FORCE_ZERO) && !defined(NO_INLINE)
if ( (ret = forcezero_test()) != 0)
TEST_FAIL("forcezero test failed!\n", ret);
else
TEST_PASS("forcezero test passed!\n");
#endif

if ( (ret = error_test()) != 0)
TEST_FAIL("error test failed!\n", ret);
else
Expand Down Expand Up @@ -4097,6 +4109,47 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t macro_test(void)
return ret;
}

/* Under NO_INLINE, ForceZero() is WOLFSSL_LOCAL (hidden visibility) inside
* libwolfssl and unreachable from this separate test binary. */
#if !defined(WOLFSSL_NO_FORCE_ZERO) && !defined(NO_INLINE)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t forcezero_test(void)
{
/* Test unaligned offsets and lengths. Oversized buffer prevents OOB writes. */
byte buf[64];
static const size_t offsets[] = { 0, 1, 2, 3, 7 };
static const size_t lens[] = { 0, 1, 3, 7, 8, 9, 16, 31 };
size_t oi, li;
ForceZero(NULL, 0);

for (oi = 0; oi < XELEM_CNT(offsets); oi++) {
for (li = 0; li < XELEM_CNT(lens); li++) {
size_t off = offsets[oi];
size_t len = lens[li];
size_t i;

XMEMSET(buf, 0xA5, sizeof(buf));
ForceZero(buf + off, len);

for (i = 0; i < len; i++) {
if (buf[off + i] != 0x00)
return WC_TEST_RET_ENC_NC;
}
/* bytes outside [off, off+len) must be untouched */
for (i = 0; i < off; i++) {
if (buf[i] != (byte)0xA5)
return WC_TEST_RET_ENC_NC;
}
for (i = off + len; i < sizeof(buf); i++) {
if (buf[i] != (byte)0xA5)
return WC_TEST_RET_ENC_NC;
}
}
}

return 0;
}
#endif

WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void)
{
const char* errStr;
Expand Down
5 changes: 5 additions & 0 deletions wolfcrypt/test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ wc_static_assert(-(long)MIN_CODE_E < 0x7ffL);
#endif

extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t macro_test(void);
/* Under NO_INLINE, ForceZero() is WOLFSSL_LOCAL (hidden visibility) inside
* libwolfssl and unreachable from this separate test binary. */
#if !defined(WOLFSSL_NO_FORCE_ZERO) && !defined(NO_INLINE)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t forcezero_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base64_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base16_test(void);
Expand Down
13 changes: 8 additions & 5 deletions wolfssl/wolfcrypt/wc_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -1919,14 +1919,17 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void);
#endif

#ifdef WOLF_C99
/* use alternate keyword for compatibility with -std=c99 */
#define XASM_VOLATILE(a) __asm__ volatile(a)
/* -std=c99 compat; "memory" clobber creates a compiler barrier. */
#define XASM_VOLATILE(a) __asm__ volatile(a ::: "memory") /* NOLINT(bugprone-macro-parentheses) */
#elif defined(__IAR_SYSTEMS_ICC__)
#define XASM_VOLATILE(a) asm volatile(a)
#define XASM_VOLATILE(a) asm volatile(a) /* NOLINT(bugprone-macro-parentheses) */
#elif defined(__KEIL__)
#define XASM_VOLATILE(a) __asm volatile(a)
/* No "memory" clobber: ARM Compiler 5 inline asm rejects GCC clobber
* syntax. */
#define XASM_VOLATILE(a) __asm volatile(a) /* NOLINT(bugprone-macro-parentheses) */
#else
#define XASM_VOLATILE(a) __asm__ __volatile__(a)
/* "memory" clobber strengthens XFENCE() into a full compiler barrier. */
#define XASM_VOLATILE(a) __asm__ __volatile__(a ::: "memory") /* NOLINT(bugprone-macro-parentheses) */
#endif

#ifndef WOLFSSL_NO_FENCE
Expand Down
Loading