|
8 | 8 | #define SECP256K1_UTIL_H
|
9 | 9 |
|
10 | 10 | #include "../include/secp256k1.h"
|
| 11 | +#include "checkmem.h" |
11 | 12 |
|
| 13 | +#include <string.h> |
12 | 14 | #include <stdlib.h>
|
13 | 15 | #include <stdint.h>
|
14 | 16 | #include <stdio.h>
|
15 | 17 | #include <limits.h>
|
| 18 | +#if defined(_MSC_VER) |
| 19 | +/* For SecureZeroMemory */ |
| 20 | +#include <Windows.h> |
| 21 | +#endif |
16 | 22 |
|
17 | 23 | #define STR_(x) #x
|
18 | 24 | #define STR(x) STR_(x)
|
@@ -221,6 +227,34 @@ static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) {
|
221 | 227 | }
|
222 | 228 | }
|
223 | 229 |
|
| 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 | + |
224 | 258 | /** Semantics like memcmp. Variable-time.
|
225 | 259 | *
|
226 | 260 | * We use this to avoid possible compiler bugs with memcmp, e.g.
|
|
0 commit comments