Skip to content

Commit 1c08126

Browse files
real-or-randomtheStack
authored andcommitted
Add secp256k1_memclear() for clearing secret data
We rely on memset() and an __asm__ memory barrier where it's available or on SecureZeroMemory() on Windows. The fallback implementation uses a volatile function pointer to memset which the compiler is not clever enough to optimize.
1 parent e7d3844 commit 1c08126

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

src/util.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88
#define SECP256K1_UTIL_H
99

1010
#include "../include/secp256k1.h"
11+
#include "checkmem.h"
1112

13+
#include <string.h>
1214
#include <stdlib.h>
1315
#include <stdint.h>
1416
#include <stdio.h>
1517
#include <limits.h>
18+
#if defined(_MSC_VER)
19+
/* For SecureZeroMemory */
20+
#include <Windows.h>
21+
#endif
1622

1723
#define STR_(x) #x
1824
#define STR(x) STR_(x)
@@ -221,6 +227,34 @@ static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) {
221227
}
222228
}
223229

230+
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
231+
static SECP256K1_INLINE void secp256k1_memclear(void *ptr, size_t len) {
232+
#if defined(_MSC_VER)
233+
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
234+
SecureZeroMemory(ptr, len);
235+
#elif defined(__GNUC__)
236+
/* We use a memory barrier that scares the compiler away from optimizing out the memset.
237+
*
238+
* Quoting Adam Langley <[email protected]> in commit ad1907fe73334d6c696c8539646c21b11178f20f
239+
* in BoringSSL (ISC License):
240+
* As best as we can tell, this is sufficient to break any optimisations that
241+
* might try to eliminate "superfluous" memsets.
242+
* This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
243+
* is pretty efficient, because the compiler can still implement the memset() efficently,
244+
* just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
245+
* Yang et al. (USENIX Security 2017) for more background.
246+
*/
247+
memset(ptr, 0, len);
248+
__asm__ __volatile__("" : : "r"(ptr) : "memory");
249+
#else
250+
void *(*volatile const volatile_memset)(void *, int, size_t) = memset;
251+
volatile_memset(ptr, 0, len);
252+
#endif
253+
#ifdef VERIFY
254+
SECP256K1_CHECKMEM_UNDEFINE(ptr, len);
255+
#endif
256+
}
257+
224258
/** Semantics like memcmp. Variable-time.
225259
*
226260
* We use this to avoid possible compiler bugs with memcmp, e.g.

0 commit comments

Comments
 (0)