UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
secure_erase.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_DETAIL_SECURE_ERASE_HPP
2#define SECP256K1_DETAIL_SECURE_ERASE_HPP
3
4// -- Secure buffer erasure (not optimized away by the compiler) ---------------
5// Defense-in-depth strategy:
6// 1. Platform-specific guaranteed-not-elided erase when available
7// (memset_s / explicit_bzero / SecureZeroMemory)
8// 2. Volatile function-pointer trick (libsecp256k1 pattern) as fallback
9// 3. std::atomic_signal_fence as compiler barrier to prevent LTO/IPO
10// from seeing through the volatile trick
11
12#include <cstddef>
13#include <cstring>
14#include <atomic>
15#if defined(_MSC_VER)
16# ifndef NOMINMAX
17# define NOMINMAX
18# endif
19# include <windows.h> // SecureZeroMemory
20# ifdef min
21# undef min
22# endif
23# ifdef max
24# undef max
25# endif
26#endif
27
28namespace secp256k1::detail {
29
30inline void secure_erase(void* ptr, std::size_t len) noexcept {
31 if (len == 0) return;
32
33#if defined(_MSC_VER)
34 // Windows/MSVC provides an explicit secure zero primitive.
35 // It is documented as non-elidable and avoids Annex-K availability issues.
36 SecureZeroMemory(ptr, len);
37#elif defined(__STDC_LIB_EXT1__)
38 // C11 Annex K secure erase when available.
39 (void)memset_s(ptr, len, 0, len);
40#elif defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
41 // glibc 2.25+: explicit_bzero is guaranteed not to be optimized away.
42 explicit_bzero(ptr, len);
43#elif defined(__OpenBSD__) || defined(__FreeBSD__)
44 // BSD: explicit_bzero available.
45 explicit_bzero(ptr, len);
46#else
47 // Fallback: volatile function-pointer trick (from libsecp256k1).
48 // The compiler cannot prove the callee is memset, so cannot elide the call.
49 void *(*volatile const volatile_memset)(void *, int, std::size_t) = std::memset;
50 volatile_memset(ptr, 0, len);
51#endif
52
53 // Defense-in-depth: compiler fence prevents LTO/IPO from reasoning
54 // across the barrier and optimizing away the erase above.
55 // std::atomic_signal_fence has no runtime cost but prevents reordering.
56 std::atomic_signal_fence(std::memory_order_seq_cst);
57}
58
59} // namespace secp256k1::detail
60
61#endif // SECP256K1_DETAIL_SECURE_ERASE_HPP
void secure_erase(void *ptr, std::size_t len) noexcept