Coverage Report

Created: 2026-10-13 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/src/lib/utils/mem_utils.cpp
Line
Count
Source
1
/*
2
* (C) 2025 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/mem_ops.h>
8
9
#include <botan/internal/target_info.h>
10
#include <cstring>
11
12
#if defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO)
13
   #include <string.h>
14
#endif
15
16
#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY)
17
   #define NOMINMAX 1
18
   #define _WINSOCKAPI_  // stop windows.h including winsock.h
19
   #include <windows.h>
20
#endif
21
22
namespace Botan {
23
24
972k
void secure_scrub_memory(void* ptr, size_t n) {
25
#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY)
26
   ::RtlSecureZeroMemory(ptr, n);
27
28
#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO)
29
   ::explicit_bzero(ptr, n);
30
31
#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_MEMSET)
32
   (void)::explicit_memset(ptr, 0, n);
33
34
#else
35
   /*
36
   * Call memset through a static volatile pointer, which the compiler should
37
   * not elide. This construct should be safe in conforming compilers, but who
38
   * knows. This has been checked to generate the expected code, which saves the
39
   * memset address in the data segment and unconditionally loads and jumps to
40
   * that address, with the following targets:
41
   *
42
   * x86-64: Clang 19, GCC 6, 11, 13, 14
43
   * riscv64: GCC 14
44
   * aarch64: GCC 14
45
   * armv7: GCC 14
46
   *
47
   * Actually all of them generated the expected jump even without marking the
48
   * function pointer as volatile. However this seems worth including as an
49
   * additional precaution.
50
   */
51
   static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset;
52
   (memset_ptr)(ptr, 0, n);
53
#endif
54
972k
}
55
56
}  // namespace Botan