Bitcoin Core  26.99.0
P2P Digital Currency
checkmem.h
Go to the documentation of this file.
1 /***********************************************************************
2  * Copyright (c) 2022 Pieter Wuille *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5  ***********************************************************************/
6 
7 /* The code here is inspired by Kris Kwiatkowski's approach in
8  * https://github.com/kriskwiatkowski/pqc/blob/main/src/common/ct_check.h
9  * to provide a general interface for memory-checking mechanisms, primarily
10  * for constant-time checking.
11  */
12 
13 /* These macros are defined by this header file:
14  *
15  * - SECP256K1_CHECKMEM_ENABLED:
16  * - 1 if memory-checking integration is available, 0 otherwise.
17  * This is just a compile-time macro. Use the next macro to check it is actually
18  * available at runtime.
19  * - SECP256K1_CHECKMEM_RUNNING():
20  * - Acts like a function call, returning 1 if memory checking is available
21  * at runtime.
22  * - SECP256K1_CHECKMEM_CHECK(p, len):
23  * - Assert or otherwise fail in case the len-byte memory block pointed to by p is
24  * not considered entirely defined.
25  * - SECP256K1_CHECKMEM_CHECK_VERIFY(p, len):
26  * - Like SECP256K1_CHECKMEM_CHECK, but only works in VERIFY mode.
27  * - SECP256K1_CHECKMEM_UNDEFINE(p, len):
28  * - marks the len-byte memory block pointed to by p as undefined data (secret data,
29  * in the context of constant-time checking).
30  * - SECP256K1_CHECKMEM_DEFINE(p, len):
31  * - marks the len-byte memory pointed to by p as defined data (public data, in the
32  * context of constant-time checking).
33  *
34  */
35 
36 #ifndef SECP256K1_CHECKMEM_H
37 #define SECP256K1_CHECKMEM_H
38 
39 /* Define a statement-like macro that ignores the arguments. */
40 #define SECP256K1_CHECKMEM_NOOP(p, len) do { (void)(p); (void)(len); } while(0)
41 
42 /* If compiling under msan, map the SECP256K1_CHECKMEM_* functionality to msan.
43  * Choose this preferentially, even when VALGRIND is defined, as msan-compiled
44  * binaries can't be run under valgrind anyway. */
45 #if defined(__has_feature)
46 # if __has_feature(memory_sanitizer)
47 # include <sanitizer/msan_interface.h>
48 # define SECP256K1_CHECKMEM_ENABLED 1
49 # define SECP256K1_CHECKMEM_UNDEFINE(p, len) __msan_allocated_memory((p), (len))
50 # define SECP256K1_CHECKMEM_DEFINE(p, len) __msan_unpoison((p), (len))
51 # define SECP256K1_CHECKMEM_CHECK(p, len) __msan_check_mem_is_initialized((p), (len))
52 # define SECP256K1_CHECKMEM_RUNNING() (1)
53 # endif
54 #endif
55 
56 /* If valgrind integration is desired (through the VALGRIND define), implement the
57  * SECP256K1_CHECKMEM_* macros using valgrind. */
58 #if !defined SECP256K1_CHECKMEM_ENABLED
59 # if defined VALGRIND
60 # include <stddef.h>
61 # if defined(__clang__) && defined(__APPLE__)
62 # pragma clang diagnostic push
63 # pragma clang diagnostic ignored "-Wreserved-identifier"
64 # endif
65 # include <valgrind/memcheck.h>
66 # if defined(__clang__) && defined(__APPLE__)
67 # pragma clang diagnostic pop
68 # endif
69 # define SECP256K1_CHECKMEM_ENABLED 1
70 # define SECP256K1_CHECKMEM_UNDEFINE(p, len) VALGRIND_MAKE_MEM_UNDEFINED((p), (len))
71 # define SECP256K1_CHECKMEM_DEFINE(p, len) VALGRIND_MAKE_MEM_DEFINED((p), (len))
72 # define SECP256K1_CHECKMEM_CHECK(p, len) VALGRIND_CHECK_MEM_IS_DEFINED((p), (len))
73  /* VALGRIND_MAKE_MEM_DEFINED returns 0 iff not running on memcheck.
74  * This is more precise than the RUNNING_ON_VALGRIND macro, which
75  * checks for valgrind in general instead of memcheck specifically. */
76 # define SECP256K1_CHECKMEM_RUNNING() (VALGRIND_MAKE_MEM_DEFINED(NULL, 0) != 0)
77 # endif
78 #endif
79 
80 /* As a fall-back, map these macros to dummy statements. */
81 #if !defined SECP256K1_CHECKMEM_ENABLED
82 # define SECP256K1_CHECKMEM_ENABLED 0
83 # define SECP256K1_CHECKMEM_UNDEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
84 # define SECP256K1_CHECKMEM_DEFINE(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
85 # define SECP256K1_CHECKMEM_CHECK(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
86 # define SECP256K1_CHECKMEM_RUNNING() (0)
87 #endif
88 
89 #if defined VERIFY
90 #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_CHECK((p), (len))
91 #else
92 #define SECP256K1_CHECKMEM_CHECK_VERIFY(p, len) SECP256K1_CHECKMEM_NOOP((p), (len))
93 #endif
94 
95 #endif /* SECP256K1_CHECKMEM_H */