Coverage Report

Created: 2025-07-11 06:15

/src/Botan-3.4.0/build/include/public/botan/mem_ops.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Memory Operations
3
* (C) 1999-2009,2012,2015 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#ifndef BOTAN_MEMORY_OPS_H_
9
#define BOTAN_MEMORY_OPS_H_
10
11
#include <botan/concepts.h>
12
#include <botan/types.h>
13
#include <array>
14
#include <cstring>
15
#include <ranges>
16
#include <span>
17
#include <type_traits>
18
#include <vector>
19
20
/*
21
The header mem_ops.h previously included the contents of allocator.h
22
23
Library code should always include allocator.h to see these
24
declarations; however when we are not building the library continue to
25
include the header here to avoid breaking application code.
26
*/
27
#if !defined(BOTAN_IS_BEING_BUILT)
28
   #include <botan/allocator.h>
29
#endif
30
31
namespace Botan {
32
33
/**
34
* Scrub memory contents in a way that a compiler should not elide,
35
* using some system specific technique. Note that this function might
36
* not zero the memory (for example, in some hypothetical
37
* implementation it might combine the memory contents with the output
38
* of a system PRNG), but if you can detect any difference in behavior
39
* at runtime then the clearing is side-effecting and you can just
40
* use `clear_mem`.
41
*
42
* Use this function to scrub memory just before deallocating it, or on
43
* a stack buffer before returning from the function.
44
*
45
* @param ptr a pointer to memory to scrub
46
* @param n the number of bytes pointed to by ptr
47
*/
48
BOTAN_PUBLIC_API(2, 0) void secure_scrub_memory(void* ptr, size_t n);
49
50
/**
51
* Scrub memory contents in a way that a compiler should not elide,
52
* using some system specific technique. Note that this function might
53
* not zero the memory.
54
*
55
* @param data  the data region to be scrubbed
56
*/
57
void secure_scrub_memory(ranges::contiguous_output_range auto&& data) {
58
   secure_scrub_memory(std::ranges::data(data), ranges::size_bytes(data));
59
}
60
61
#if !defined(BOTAN_IS_BEGIN_BUILT)
62
63
/**
64
* Memory comparison, input insensitive
65
* @param x a pointer to an array
66
* @param y a pointer to another array
67
* @param len the number of Ts in x and y
68
* @return 0xFF iff x[i] == y[i] forall i in [0...n) or 0x00 otherwise
69
*/
70
BOTAN_DEPRECATED("This function is deprecated, use constant_time_compare()")
71
BOTAN_PUBLIC_API(2, 9) uint8_t ct_compare_u8(const uint8_t x[], const uint8_t y[], size_t len);
72
73
#endif
74
75
/**
76
 * Memory comparison, input insensitive
77
 * @param x a range of bytes
78
 * @param y another range of bytes
79
 * @return true iff x and y have equal lengths and x[i] == y[i] forall i in [0...n)
80
 */
81
BOTAN_PUBLIC_API(3, 3) bool constant_time_compare(std::span<const uint8_t> x, std::span<const uint8_t> y);
82
83
/**
84
* Memory comparison, input insensitive
85
* @param x a pointer to an array
86
* @param y a pointer to another array
87
* @param len the number of Ts in x and y
88
* @return true iff x[i] == y[i] forall i in [0...n)
89
*/
90
0
inline bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len) {
91
0
   // simply assumes that *x and *y point to len allocated bytes at least
92
0
   return constant_time_compare({x, len}, {y, len});
93
0
}
94
95
/**
96
* Zero out some bytes. Warning: use secure_scrub_memory instead if the
97
* memory is about to be freed or otherwise the compiler thinks it can
98
* elide the writes.
99
*
100
* @param ptr a pointer to memory to zero
101
* @param bytes the number of bytes to zero in ptr
102
*/
103
1.02G
inline constexpr void clear_bytes(void* ptr, size_t bytes) {
104
1.02G
   if(bytes > 0) {
105
892M
      std::memset(ptr, 0, bytes);
106
892M
   }
107
1.02G
}
108
109
/**
110
* Zero memory before use. This simply calls memset and should not be
111
* used in cases where the compiler cannot see the call as a
112
* side-effecting operation (for example, if calling clear_mem before
113
* deallocating memory, the compiler would be allowed to omit the call
114
* to memset entirely under the as-if rule.)
115
*
116
* @param ptr a pointer to an array of Ts to zero
117
* @param n the number of Ts pointed to by ptr
118
*/
119
template <typename T>
120
1.02G
inline constexpr void clear_mem(T* ptr, size_t n) {
121
1.02G
   clear_bytes(ptr, sizeof(T) * n);
122
1.02G
}
void Botan::clear_mem<unsigned long>(unsigned long*, unsigned long)
Line
Count
Source
120
881M
inline constexpr void clear_mem(T* ptr, size_t n) {
121
881M
   clear_bytes(ptr, sizeof(T) * n);
122
881M
}
void Botan::clear_mem<unsigned char>(unsigned char*, unsigned long)
Line
Count
Source
120
9.53M
inline constexpr void clear_mem(T* ptr, size_t n) {
121
9.53M
   clear_bytes(ptr, sizeof(T) * n);
122
9.53M
}
void Botan::clear_mem<int>(int*, unsigned long)
Line
Count
Source
120
132M
inline constexpr void clear_mem(T* ptr, size_t n) {
121
132M
   clear_bytes(ptr, sizeof(T) * n);
122
132M
}
Unexecuted instantiation: void Botan::clear_mem<unsigned int>(unsigned int*, unsigned long)
123
124
/**
125
* Zero memory before use. This simply calls memset and should not be
126
* used in cases where the compiler cannot see the call as a
127
* side-effecting operation.
128
*
129
* @param mem a contiguous range of Ts to zero
130
*/
131
template <ranges::contiguous_output_range R>
132
inline constexpr void clear_mem(R&& mem)
133
   requires std::is_trivially_copyable_v<std::ranges::range_value_t<R>>
134
{
135
   clear_bytes(std::ranges::data(mem), ranges::size_bytes(mem));
136
}
137
138
/**
139
* Copy memory
140
* @param out the destination array
141
* @param in the source array
142
* @param n the number of elements of in/out
143
*/
144
template <typename T>
145
   requires std::is_trivial<typename std::decay<T>::type>::value
146
208M
inline constexpr void copy_mem(T* out, const T* in, size_t n) {
147
208M
   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
148
149
208M
   if(in != nullptr && out != nullptr && n > 0) {
150
208M
      std::memmove(out, in, sizeof(T) * n);
151
208M
   }
152
208M
}
_ZN5Botan8copy_memIhQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m
Line
Count
Source
146
1.43M
inline constexpr void copy_mem(T* out, const T* in, size_t n) {
147
1.43M
   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
148
149
1.43M
   if(in != nullptr && out != nullptr && n > 0) {
150
1.43M
      std::memmove(out, in, sizeof(T) * n);
151
1.43M
   }
152
1.43M
}
Unexecuted instantiation: _ZN5Botan8copy_memIjQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m
_ZN5Botan8copy_memImQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m
Line
Count
Source
146
207M
inline constexpr void copy_mem(T* out, const T* in, size_t n) {
147
207M
   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
148
149
207M
   if(in != nullptr && out != nullptr && n > 0) {
150
207M
      std::memmove(out, in, sizeof(T) * n);
151
207M
   }
152
207M
}
_ZN5Botan8copy_memIiQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m
Line
Count
Source
146
12.3k
inline constexpr void copy_mem(T* out, const T* in, size_t n) {
147
12.3k
   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
148
149
12.3k
   if(in != nullptr && out != nullptr && n > 0) {
150
12.3k
      std::memmove(out, in, sizeof(T) * n);
151
12.3k
   }
152
12.3k
}
153
154
/**
155
* Copy memory
156
* @param out the destination array
157
* @param in the source array
158
*/
159
template <ranges::contiguous_output_range OutR, ranges::contiguous_range InR>
160
   requires std::is_same_v<std::ranges::range_value_t<OutR>, std::ranges::range_value_t<InR>> &&
161
            std::is_trivially_copyable_v<std::ranges::range_value_t<InR>>
162
inline constexpr void copy_mem(OutR&& out, InR&& in) {
163
   ranges::assert_equal_byte_lengths(out, in);
164
   if(std::is_constant_evaluated()) {
165
      std::copy(std::ranges::begin(in), std::ranges::end(in), std::ranges::begin(out));
166
   } else if(ranges::size_bytes(out) > 0) {
167
      std::memmove(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
168
   }
169
}
170
171
/**
172
 * Copy a range of a trivially copyable type into another range of trivially
173
 * copyable type of matching byte length.
174
 */
175
template <ranges::contiguous_output_range ToR, ranges::contiguous_range FromR>
176
   requires std::is_trivially_copyable_v<std::ranges::range_value_t<FromR>> &&
177
            std::is_trivially_copyable_v<std::ranges::range_value_t<ToR>>
178
530M
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
530M
   ranges::assert_equal_byte_lengths(out, in);
180
530M
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
530M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__15arrayImLm4EEETkNS1_16contiguous_rangeERNS2_4spanIhLm32EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS9_IXsr21__is_primary_templateINSA_Iu14__remove_cvrefIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSI_ISQ_EESR_E4type10value_typeEEEEvOSN_OSD_
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__15arrayImLm4EEETkNS1_16contiguous_rangeERNS2_4spanIKhLm32EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISH_EESI_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINSA_IXsr21__is_primary_templateINSB_Iu14__remove_cvrefIDTclL_ZNSD_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSJ_ISR_EESS_E4type10value_typeEEEEvOSO_OSE_
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanIhLm32EEETkNS1_16contiguous_rangeERNS2_5arrayImLm4EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm2EEETkNS1_16contiguous_rangeENS3_IKtLm1EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm4EEETkNS1_16contiguous_rangeENS3_IKjLm1EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
Line
Count
Source
178
652k
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
652k
   ranges::assert_equal_byte_lengths(out, in);
180
652k
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
652k
}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm8EEETkNS1_16contiguous_rangeENS3_IKmLm1EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
Line
Count
Source
178
24.8M
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
24.8M
   ranges::assert_equal_byte_lengths(out, in);
180
24.8M
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
24.8M
}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanIjLm1EEETkNS1_16contiguous_rangeERNS3_IKhLm4EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
Line
Count
Source
178
357M
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
357M
   ranges::assert_equal_byte_lengths(out, in);
180
357M
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
357M
}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanImLm1EEETkNS1_16contiguous_rangeERNS3_IKhLm8EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
Line
Count
Source
178
135M
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
135M
   ranges::assert_equal_byte_lengths(out, in);
180
135M
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
135M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanItLm1EEETkNS1_16contiguous_rangeERNS3_IKhLm2EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIjLm18446744073709551615EEETkNS1_16contiguous_rangeERNS3_IKhLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS9_IXsr21__is_primary_templateINSA_Iu14__remove_cvrefIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSI_ISQ_EESR_E4type10value_typeEEEEvOSN_OSD_
Line
Count
Source
178
12.3M
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
12.3M
   ranges::assert_equal_byte_lengths(out, in);
180
12.3M
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
12.3M
}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm18446744073709551615EEETkNS1_16contiguous_rangeERNS3_IKjLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS9_IXsr21__is_primary_templateINSA_Iu14__remove_cvrefIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSI_ISQ_EESR_E4type10value_typeEEEEvOSN_OSD_
Line
Count
Source
178
53.7k
inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
179
53.7k
   ranges::assert_equal_byte_lengths(out, in);
180
53.7k
   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
181
53.7k
}
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanImLm18446744073709551615EEETkNS1_16contiguous_rangeERNS3_IKhLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS9_IXsr21__is_primary_templateINSA_Iu14__remove_cvrefIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSI_ISQ_EESR_E4type10value_typeEEEEvOSN_OSD_
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm18446744073709551615EEETkNS1_16contiguous_rangeERNS3_IKmLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS9_IXsr21__is_primary_templateINSA_Iu14__remove_cvrefIDTclL_ZNSC_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSI_ISQ_EESR_E4type10value_typeEEEEvOSN_OSD_
182
183
/**
184
 * Copy a range of trivially copyable type into an instance of trivially
185
 * copyable type with matching length.
186
 */
187
template <typename ToT, ranges::contiguous_range FromR>
188
   requires std::is_trivially_copyable_v<std::ranges::range_value_t<FromR>> && std::is_trivially_copyable_v<ToT> &&
189
            (!std::ranges::range<ToT>)
190
492M
inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
191
492M
   typecast_copy(std::span<ToT, 1>(&out, 1), in);
192
492M
}
_ZN5Botan13typecast_copyIjTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm4EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISL_EEEvRSL_OSB_
Line
Count
Source
190
357M
inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
191
357M
   typecast_copy(std::span<ToT, 1>(&out, 1), in);
192
357M
}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm8EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISL_EEEvRSL_OSB_
Line
Count
Source
190
135M
inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
191
135M
   typecast_copy(std::span<ToT, 1>(&out, 1), in);
192
135M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyItTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm2EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISL_EEEvRSL_OSB_
193
194
/**
195
 * Copy an instance of trivially copyable type into a range of trivially
196
 * copyable type with matching length.
197
 */
198
template <ranges::contiguous_output_range ToR, typename FromT>
199
   requires std::is_trivially_copyable_v<FromT> &&
200
            (!std::ranges::range<FromT>) && std::is_trivially_copyable_v<std::ranges::range_value_t<ToR>>
201
25.4M
inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
202
25.4M
   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
203
25.4M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm2EEEtQaaaasr3stdE23is_trivially_copyable_vIT0_Entsr3std6rangesE5rangeIS6_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEEEvOSB_RKS6_
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm4EEEjQaaaasr3stdE23is_trivially_copyable_vIT0_Entsr3std6rangesE5rangeIS6_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEEEvOSB_RKS6_
Line
Count
Source
201
652k
inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
202
652k
   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
203
652k
}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm8EEEmQaaaasr3stdE23is_trivially_copyable_vIT0_Entsr3std6rangesE5rangeIS6_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEEEvOSB_RKS6_
Line
Count
Source
201
24.8M
inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
202
24.8M
   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
203
24.8M
}
204
205
/**
206
 * Create a trivial type by bit-casting a range of trivially copyable type with
207
 * matching length into it.
208
 */
209
template <typename ToT, ranges::contiguous_range FromR>
210
   requires std::is_default_constructible_v<ToT> && std::is_trivially_copyable_v<ToT> &&
211
            std::is_trivially_copyable_v<std::ranges::range_value_t<FromR>>
212
492M
inline constexpr ToT typecast_copy(FromR&& src) noexcept {
213
492M
   ToT dst;
214
492M
   typecast_copy(dst, src);
215
492M
   return dst;
216
492M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyINSt3__15arrayImLm4EEETkNS_6ranges16contiguous_rangeENS1_4spanIhLm32EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS7_Esr3stdE23is_trivially_copyable_vINS1_11conditionalIXsr21__is_primary_templateINS1_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS1_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS1_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEEES7_OSC_
Unexecuted instantiation: _ZN5Botan13typecast_copyINSt3__15arrayImLm4EEETkNS_6ranges16contiguous_rangeENS1_4spanIKhLm32EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS8_Esr3stdE23is_trivially_copyable_vINS1_11conditionalIXsr21__is_primary_templateINS1_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS1_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS1_26indirectly_readable_traitsISG_EESH_E4type10value_typeEEEES8_OSD_
_ZN5Botan13typecast_copyIjTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm4EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS7_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEEES7_OSC_
Line
Count
Source
212
357M
inline constexpr ToT typecast_copy(FromR&& src) noexcept {
213
357M
   ToT dst;
214
357M
   typecast_copy(dst, src);
215
357M
   return dst;
216
357M
}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm8EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS7_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEEES7_OSC_
Line
Count
Source
212
135M
inline constexpr ToT typecast_copy(FromR&& src) noexcept {
213
135M
   ToT dst;
214
135M
   typecast_copy(dst, src);
215
135M
   return dst;
216
135M
}
Unexecuted instantiation: _ZN5Botan13typecast_copyItTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm2EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS7_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEEES7_OSC_
217
218
// TODO: deprecate and replace
219
template <typename T>
220
inline constexpr void typecast_copy(uint8_t out[], T in[], size_t N)
221
   requires std::is_trivially_copyable<T>::value
222
{
223
   // asserts that *in and *out point to the correct amount of memory
224
   typecast_copy(std::span<uint8_t>(out, sizeof(T) * N), std::span<const T>(in, N));
225
}
226
227
// TODO: deprecate and replace
228
template <typename T>
229
inline constexpr void typecast_copy(T out[], const uint8_t in[], size_t N)
230
   requires std::is_trivial<T>::value
231
{
232
   // asserts that *in and *out point to the correct amount of memory
233
   typecast_copy(std::span<T>(out, N), std::span<const uint8_t>(in, N * sizeof(T)));
234
}
235
236
// TODO: deprecate and replace
237
template <typename T>
238
inline constexpr void typecast_copy(uint8_t out[], const T& in) {
239
   // asserts that *out points to the correct amount of memory
240
   typecast_copy(std::span<uint8_t, sizeof(T)>(out, sizeof(T)), in);
241
}
242
243
// TODO: deprecate and replace
244
template <typename T>
245
   requires std::is_trivial<typename std::decay<T>::type>::value
246
inline constexpr void typecast_copy(T& out, const uint8_t in[]) {
247
   // asserts that *in points to the correct amount of memory
248
   typecast_copy(out, std::span<const uint8_t, sizeof(T)>(in, sizeof(T)));
249
}
250
251
// TODO: deprecate and replace
252
template <typename To>
253
   requires std::is_trivial<To>::value
254
inline constexpr To typecast_copy(const uint8_t src[]) noexcept {
255
   // asserts that *src points to the correct amount of memory
256
   return typecast_copy<To>(std::span<const uint8_t, sizeof(To)>(src, sizeof(To)));
257
}
258
259
#if !defined(BOTAN_IS_BEGIN_BUILT)
260
/**
261
* Set memory to a fixed value
262
* @param ptr a pointer to an array of bytes
263
* @param n the number of Ts pointed to by ptr
264
* @param val the value to set each byte to
265
*/
266
BOTAN_DEPRECATED("This function is deprecated")
267
268
0
inline constexpr void set_mem(uint8_t* ptr, size_t n, uint8_t val) {
269
0
   if(n > 0) {
270
0
      std::memset(ptr, val, n);
271
0
   }
272
0
}
273
#endif
274
275
7.87k
inline const uint8_t* cast_char_ptr_to_uint8(const char* s) {
276
7.87k
   return reinterpret_cast<const uint8_t*>(s);
277
7.87k
}
278
279
153
inline const char* cast_uint8_ptr_to_char(const uint8_t* b) {
280
153
   return reinterpret_cast<const char*>(b);
281
153
}
282
283
0
inline uint8_t* cast_char_ptr_to_uint8(char* s) {
284
0
   return reinterpret_cast<uint8_t*>(s);
285
0
}
286
287
0
inline char* cast_uint8_ptr_to_char(uint8_t* b) {
288
0
   return reinterpret_cast<char*>(b);
289
0
}
290
291
#if !defined(BOTAN_IS_BEING_BUILT)
292
/**
293
* Memory comparison, input insensitive
294
* @param p1 a pointer to an array
295
* @param p2 a pointer to another array
296
* @param n the number of Ts in p1 and p2
297
* @return true iff p1[i] == p2[i] forall i in [0...n)
298
*/
299
template <typename T>
300
BOTAN_DEPRECATED("This function is deprecated")
301
inline bool same_mem(const T* p1, const T* p2, size_t n) {
302
   volatile T difference = 0;
303
304
   for(size_t i = 0; i != n; ++i) {
305
      difference = difference | (p1[i] ^ p2[i]);
306
   }
307
308
   return difference == 0;
309
}
310
#endif
311
312
#if !defined(BOTAN_IS_BEING_BUILT)
313
314
template <typename T, typename Alloc>
315
BOTAN_DEPRECATED("The buffer_insert functions are deprecated")
316
size_t buffer_insert(std::vector<T, Alloc>& buf, size_t buf_offset, const T input[], size_t input_length) {
317
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
318
   const size_t to_copy = std::min(input_length, buf.size() - buf_offset);
319
   if(to_copy > 0) {
320
      copy_mem(&buf[buf_offset], input, to_copy);
321
   }
322
   return to_copy;
323
}
324
325
template <typename T, typename Alloc, typename Alloc2>
326
BOTAN_DEPRECATED("The buffer_insert functions are deprecated")
327
size_t buffer_insert(std::vector<T, Alloc>& buf, size_t buf_offset, const std::vector<T, Alloc2>& input) {
328
   BOTAN_ASSERT_NOMSG(buf_offset <= buf.size());
329
   const size_t to_copy = std::min(input.size(), buf.size() - buf_offset);
330
   if(to_copy > 0) {
331
      copy_mem(&buf[buf_offset], input.data(), to_copy);
332
   }
333
   return to_copy;
334
}
335
336
#endif
337
338
/**
339
* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length
340
* @param out the input/output range
341
* @param in the read-only input range
342
*/
343
inline constexpr void xor_buf(ranges::contiguous_output_range<uint8_t> auto&& out,
344
0
                              ranges::contiguous_range<uint8_t> auto&& in) {
345
0
   ranges::assert_equal_byte_lengths(out, in);
346
347
0
   std::span o{out};
348
0
   std::span i{in};
349
350
0
   for(; o.size_bytes() >= 32; o = o.subspan(32), i = i.subspan(32)) {
351
0
      auto x = typecast_copy<std::array<uint64_t, 4>>(o.template first<32>());
352
0
      const auto y = typecast_copy<std::array<uint64_t, 4>>(i.template first<32>());
353
354
0
      x[0] ^= y[0];
355
0
      x[1] ^= y[1];
356
0
      x[2] ^= y[2];
357
0
      x[3] ^= y[3];
358
359
0
      typecast_copy(o.template first<32>(), x);
360
0
   }
361
362
0
   for(size_t off = 0; off != o.size_bytes(); ++off) {
363
0
      o[off] ^= i[off];
364
0
   }
365
0
}
Unexecuted instantiation: _ZN5Botan7xor_bufITkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm18446744073709551615EEETkNS1_16contiguous_rangeIhEENS4_IKhLm18446744073709551615EEEEEvOT_OT0_
Unexecuted instantiation: _ZN5Botan7xor_bufITkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm18446744073709551615EEETkNS1_16contiguous_rangeIhEERKNS3_6vectorIhNS_16secure_allocatorIhEEEEEEvOT_OT0_
366
367
/**
368
* XOR arrays. Postcondition out[i] = in1[i] ^ in2[i] forall i = 0...length
369
* @param out the output range
370
* @param in1 the first input range
371
* @param in2 the second input range
372
*/
373
inline constexpr void xor_buf(ranges::contiguous_output_range<uint8_t> auto&& out,
374
                              ranges::contiguous_range<uint8_t> auto&& in1,
375
0
                              ranges::contiguous_range<uint8_t> auto&& in2) {
376
0
   ranges::assert_equal_byte_lengths(out, in1, in2);
377
378
0
   std::span o{out};
379
0
   std::span i1{in1};
380
0
   std::span i2{in2};
381
382
0
   for(; o.size_bytes() >= 32; o = o.subspan(32), i1 = i1.subspan(32), i2 = i2.subspan(32)) {
383
0
      auto x = typecast_copy<std::array<uint64_t, 4>>(i1.template first<32>());
384
0
      const auto y = typecast_copy<std::array<uint64_t, 4>>(i2.template first<32>());
385
386
0
      x[0] ^= y[0];
387
0
      x[1] ^= y[1];
388
0
      x[2] ^= y[2];
389
0
      x[3] ^= y[3];
390
391
0
      typecast_copy(o.template first<32>(), x);
392
0
   }
393
394
0
   for(size_t off = 0; off != o.size_bytes(); ++off) {
395
0
      o[off] = i1[off] ^ i2[off];
396
0
   }
397
0
}
398
399
/**
400
* XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length
401
* @param out the input/output buffer
402
* @param in the read-only input buffer
403
* @param length the length of the buffers
404
*/
405
0
inline void xor_buf(uint8_t out[], const uint8_t in[], size_t length) {
406
   // simply assumes that *out and *in point to "length" allocated bytes at least
407
0
   xor_buf(std::span{out, length}, std::span{in, length});
408
0
}
409
410
/**
411
* XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length
412
* @param out the output buffer
413
* @param in the first input buffer
414
* @param in2 the second input buffer
415
* @param length the length of the three buffers
416
*/
417
0
inline void xor_buf(uint8_t out[], const uint8_t in[], const uint8_t in2[], size_t length) {
418
   // simply assumes that *out, *in, and *in2 point to "length" allocated bytes at least
419
0
   xor_buf(std::span{out, length}, std::span{in, length}, std::span{in2, length});
420
0
}
421
422
// TODO: deprecate and replace, use .subspan()
423
0
inline void xor_buf(std::span<uint8_t> out, std::span<const uint8_t> in, size_t n) {
424
0
   BOTAN_ARG_CHECK(out.size() >= n, "output span is too small");
425
0
   BOTAN_ARG_CHECK(in.size() >= n, "input span is too small");
426
0
   xor_buf(out.first(n), in.first(n));
427
0
}
428
429
// TODO: deprecate and replace, use .subspan()
430
template <typename Alloc>
431
void xor_buf(std::vector<uint8_t, Alloc>& out, const uint8_t* in, size_t n) {
432
   BOTAN_ARG_CHECK(out.size() >= n, "output vector is too small");
433
   // simply assumes that *in points to "n" allocated bytes at least
434
   xor_buf(std::span{out}.first(n), std::span{in, n});
435
}
436
437
// TODO: deprecate and replace
438
template <typename Alloc, typename Alloc2>
439
void xor_buf(std::vector<uint8_t, Alloc>& out, const uint8_t* in, const std::vector<uint8_t, Alloc2>& in2, size_t n) {
440
   BOTAN_ARG_CHECK(out.size() >= n, "output vector is too small");
441
   BOTAN_ARG_CHECK(in2.size() >= n, "input vector is too small");
442
   // simply assumes that *in points to "n" allocated bytes at least
443
   xor_buf(std::span{out}.first(n), std::span{in, n}, std::span{in2}.first(n));
444
}
445
446
template <typename Alloc, typename Alloc2>
447
0
std::vector<uint8_t, Alloc>& operator^=(std::vector<uint8_t, Alloc>& out, const std::vector<uint8_t, Alloc2>& in) {
448
0
   if(out.size() < in.size()) {
449
0
      out.resize(in.size());
450
0
   }
451
452
0
   xor_buf(std::span{out}.first(in.size()), in);
453
0
   return out;
454
0
}
455
456
}  // namespace Botan
457
458
#endif