-
Notifications
You must be signed in to change notification settings - Fork 5
/
P1315R5.html
312 lines (298 loc) · 35.7 KB
/
P1315R5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>secure_clear</title>
<meta name="description" content="Sensitive data, like passwords or keying data, should be cleared from memory as soon as they are not needed. This requires ensuring the compiler will not optimize the memory overwrite away. This proposal adds a `secure_clear` function (C) and a `secure_clear` function template (C++) that guarantee users that a memory area is cleared.">
<meta name="author" content="Miguel Ojeda">
<meta property="og:url" content="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2505.htm">
<meta property="og:type" content="website">
<meta property="og:title" content="secure_clear">
<meta property="og:description" content="Sensitive data, like passwords or keying data, should be cleared from memory as soon as they are not needed. This requires ensuring the compiler will not optimize the memory overwrite away. This proposal adds a `secure_clear` function (C) and a `secure_clear` function template (C++) that guarantee users that a memory area is cleared.">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "WebSite",
"name": "secure_clear",
"description": "Sensitive data, like passwords or keying data, should be cleared from memory as soon as they are not needed. This requires ensuring the compiler will not optimize the memory overwrite away. This proposal adds a `secure_clear` function (C) and a `secure_clear` function template (C++) that guarantee users that a memory area is cleared.",
"url": "http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2505.htm",
"author": {
"@type": "Person",
"name": "Miguel Ojeda",
"description": "Software Engineer",
"jobTitle": "Software Engineer",
"url": "https://ojeda.io",
"email": "mailto:miguel@ojeda.io"
}
}
</script>
<link rel="icon" href="/favicon.png">
<link rel="apple-touch-icon-precomposed" href="/favicon-apple.png">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<style>
@media screen and (min-width: 992px) {
body {
background-color: #515558;
}
.container {
background-color: #ffffff;
box-shadow: 3px 3px 3px 1px rgba(0, 0, 0, 0.3);
max-width: 900px;
margin-top: 2.5rem;
margin-bottom: 2.5rem;
padding-top: 4rem;
padding-bottom: 4rem;
}
}
.col {
max-width: 600px;
}
h1 {
margin-top: 2rem;
}
h3 {
font-size: 1.5rem;
}
pre {
background-color: #f5faff;
border-radius: 0.4em;
border-color: #c5c5c5;
border-width: 1px;
border-style: solid;
padding: 0.7em;
}
blockquote {
background-color: #f5faff;
border-radius: 0.4em;
border-color: #c5c5c5;
border-width: 1px;
border-style: solid;
padding: 0.7em;
font-style: italic;
}
blockquote > p {
margin-bottom: 0;
}
a {
word-break: break-word;
}
p, ul > li {
text-align: justify;
}
</style>
</head>
<body>
<div class="container">
<div class="row justify-content-center">
<div class="col">
<h1><code>secure_clear</code></h1>
<p>C Document number: N2505 <br />
C++ Document number: P1315R5 <a href="http://wg21.link/P1315">[latest]</a><br />
Date: 2020-04-15<br />
Author: Miguel Ojeda <<a href="mailto:miguel@ojeda.io">miguel@ojeda.io</a>><br />
Project: ISO JTC1/SC22/WG14: Programming Language C<br />
Project: ISO JTC1/SC22/WG21: Programming Language C++</p>
<h2>Abstract</h2>
<p>Sensitive data, like passwords or keying data, should be cleared from memory as soon as they are not needed. This requires ensuring the compiler will not optimize the memory overwrite away. This proposal adds a <code>secure_clear</code> function (C) and a <code>secure_clear</code> function template (C++) that guarantee users that a memory area is cleared.</p>
<h2>Changelog</h2>
<p><strong>P1315R5</strong> – Merged WG14 C and WG21 C++ proposals. Same content as N2505. With respect to R4:</p>
<ul>
<li>The function <code>secure_clear</code> is now imported from C, so proposal changed accordingly (e.g. removed <code>noexcept</code>).</li>
<li>Updated template declaration to require a constraint on <code>is_trivially_copyable_v</code> instead of using the <code>TriviallyCopyable</code> pseudo-concept (since it does not exist in C++20 on its own). Also changed <code>pointer</code> to <code>is_pointer_v</code>.</li>
<li>Moved the <code>memset_s</code> wording suggestion into the C side.</li>
<li>Removed new header suggestion until discussed with WG14.</li>
</ul>
<h2>The problem</h2>
<p>When manipulating sensitive data, like passwords in memory or keying data, there is a need for library and application developers to clear the memory after the data is not needed anymore <a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations" title="MSC06-C. Beware of compiler optimizations">[1]</a><a href="https://cwe.mitre.org/data/definitions/14.html" title="CWE-14: Compiler Removal of Code to Clear Buffers">[2]</a><a href="https://www.viva64.com/en/w/v597/" title="V597. The compiler could delete the `memset` function call (...)">[3]</a><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf" title="N1381 --- #5 `memset_s()` to clear memory, without fear of removal">[4]</a>, in order to minimize the time window where it is possible to capture it (e.g. ending in a core dump or probed by a malicious actor). Recent vulnerabilities (e.g. Meltdown, Spectre-class, Rowhammer-class…) have made this requirement even more prominent.</p>
<p>In order to ensure that the memory is cleared, the developer needs to inform the compiler that it must not optimize away the memory write, even if it can prove it has no observable behavior. For C++, extra care is needed to consider all exceptional return paths.</p>
<p>For instance, the following C++ function may be vulnerable, since the compiler may optimize the <code>memset</code> call away because the <code>password</code> buffer is not read from before it goes out of scope:</p>
<pre><code>void f()
{
constexpr std::size_t size = 100;
char password[size];
// Acquire some sensitive data
getPasswordFromUser(password, size);
// Use it for some operations
usePassword(password, size);
// Attempt to clear the sensitive data
std::memset(password, 0, size);
}
</code></pre>
<p>On top of that, <code>usePassword</code> could throw an exception so <code>std::memset</code> is never called (i.e. assume the stack is not overwritten and/or that the memory is held in the free store).</p>
<p>There are many ways that developers may use to try to ensure the memory is cleared as expected (i.e. avoiding the optimizer):</p>
<ul>
<li>Calling a function defined in another translation unit, assuming LTO/WPO is not enabled.</li>
<li>Writing memory through a <code>volatile</code> pointer (e.g. <code>decaf_bzero</code> <a href="https://github.com/openssl/openssl/blob/f8385b0fc0215b378b61891582b0579659d0b9f4/crypto/ec/curve448/utils.c" title="`openssl/crypto/ec/curve448/utils.c` (old code)">[5]</a> from OpenSSL).</li>
<li>Calling <code>memset</code> through a <code>volatile</code> function pointer (e.g. <code>OPENSSL_cleanse</code> C implementation <a href="https://github.com/openssl/openssl/blob/master/crypto/mem_clr.c" title="`OPENSSL_cleanse` (implementation)">[6]</a>).</li>
<li>Creating a dependency by writing an <code>extern</code> variable into it (e.g. <code>CRYPTO_malloc</code> implementation <a href="https://github.com/openssl/openssl/blob/104ce8a9f02d250dd43c255eb7b8747e81b29422/crypto/mem.c#L143" title="`openssl/crypto/mem.c` (old code)">[7]</a> from OpenSSL).</li>
<li>Coding the memory write in assembly (e.g. <code>OPENSSL_cleanse</code> SPARC implementation <a href="https://github.com/openssl/openssl/blob/master/crypto/sparccpuid.S#L363" title="`openssl/crypto/sparccpuid.S` (example of assembly implementation)">[8]</a>).</li>
<li>Introducing a memory barrier (e.g. <code>memzero_explicit</code> implementation <a href="https://elixir.bootlin.com/linux/v4.18.5/source/lib/string.c#L706" title="`memzero_explicit` (implementation)">[9]</a> from the Linux Kernel).</li>
<li>Disabling specific compiler options/optimizations (e.g. <code>-fno-builtin-memset</code> <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html" title="Options Controlling C Dialect">[10]</a> in GCC).</li>
</ul>
<p>Or they may use a pre-existing solution whenever available:</p>
<ul>
<li>Using an operating system-provided API (e.g. <code>explicit_bzero</code> <a href="http://man7.org/linux/man-pages/man3/bzero.3.html" title="`bzero`, `explicit_bzero` - zero a byte string">[11]</a> from OpenBSD & FreeBSD, <code>SecureZeroMemory</code> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366877(v=vs.85).aspx" title="`SecureZeroMemory` function">[12]</a> from Windows).</li>
<li>Using a library function (e.g. <code>memzero_explicit</code> <a href="https://www.kernel.org/doc/htmldocs/kernel-api/API-memzero-explicit.html" title="`memzero_explicit`">[13]</a><a href="https://elixir.bootlin.com/linux/v4.18.5/source/lib/string.c#L706" title="`memzero_explicit` (implementation)">[9]</a> from the Linux Kernel, <code>OPENSSL_cleanse</code> <a href="https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_cleanse.html" title="`OPENSSL_cleanse`">[14]</a><a href="https://github.com/openssl/openssl/blob/master/crypto/mem_clr.c" title="`OPENSSL_cleanse` (implementation)">[6]</a>).</li>
</ul>
<p>Regardless of how it is done, none of these ways is — at the same time — portable, easy to recognize the intent (and/or <code>grep</code> for it), readily available and avoiding compiler implementation details. The topic may generate discussions in major projects on which is the best way to proceed and whether an specific approach ensures that the memory is actually cleansed (e.g. <a href="https://github.com/openssl/openssl/pull/455" title="Reimplement non-asm `OPENSSL_cleanse()` #455">[15]</a><a href="http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html" title="How to zero a buffer">[16]</a><a href="https://news.ycombinator.com/item?id=8270136" title="Hacker News: How to zero a buffer (daemonology.net)">[17]</a><a href="https://stackoverflow.com/questions/13299420/" title="Mac OS X equivalent of `SecureZeroMemory` / `RtlSecureZeroMemory`?">[18]</a><a href="https://gcc.gnu.org/ml/gcc-help/2014-10/msg00047.html" title="Optimising away `memset()` calls?">[19]</a>). Sometimes, such a way is not effective for a particular compiler (e.g. <a href="https://bugs.llvm.org/show_bug.cgi?id=15495" title="Bug 15495 - dead store pass ignores memory clobbering asm statement">[20]</a>). In the worst case, bugs happen (e.g. <a href="https://bugzilla.kernel.org/show_bug.cgi?id=82041" title="Bug 82041 - `memset` optimized out in `random.c`">[21]</a><a href="https://lkml.org/lkml/2014/8/25/497" title="[PATCH] random: add and use memzero_explicit() for clearing data">[22]</a>).</p>
<p>C11 (and C++17 as it was based on it) added <code>memset_s</code> (K.3.7.4.1) to give a standard solution to this problem <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf" title="N1381 --- #5 `memset_s()` to clear memory, without fear of removal">[4]</a><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf" title="N1548 --- C11 draft">[23]</a><a href="https://en.cppreference.com/w/c/string/byte/memset" title="`memset`, `memset_s`">[24]</a>. However, it is an optional extension (Annex K) and, at the time of writing, several major compiler vendors do not define <code>__STDC_LIB_EXT1__</code> (GCC <a href="https://godbolt.org/g/M7MyRg" title="Test for `memset_s` in gcc 8.2 at Godbolt">[25]</a>, Clang <a href="https://godbolt.org/g/ZwbkgY" title="Test for `memset_s` in clang 6.0.0 at Godbolt">[26]</a>, MSVC <a href="https://godbolt.org/g/FtrVJ8" title="Test for `memset_s` in MSVC 19 2017 at Godbolt">[27]</a>, icc <a href="https://godbolt.org/g/vHZNrW" title="Test for `memset_s` in icc 18.0.0 at Godbolt">[28]</a>). Therefore, in practical terms, there is no standard solution yet for C nor C++. A 2015 paper on this topic, WG14’s N1967 “Field Experience With Annex K — Bounds Checking Interfaces” <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm" title="N1967 (WG14) --- Field Experience With Annex K - Bounds Checking Interfaces">[29]</a>, concludes that “Annex K should be removed from the C standard”.</p>
<p>Other languages offer similar facilities in their standard libraries or as external projects:</p>
<ul>
<li>The <code>SecureString</code> class in .NET Core, .NET Framework and Xamarin <a href="https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring" title="`SecureString` Class">[30]</a>.</li>
<li>The <code>securemem</code> package in Haskell <a href="https://hackage.haskell.org/package/securemem" title="`securemem`: abstraction to an auto scrubbing and const time eq, memory chunk.">[31]</a>.</li>
<li>The <code>secstr</code> library in Rust <a href="https://github.com/myfreeweb/secstr" title="`secstr`: Secure string library for Rust">[32]</a>.</li>
<li>Limited private types in Ada and SPARK <a href="https://proteancode.com/wp-content/uploads/2017/06/ae2017_final3_for_web.pdf" title="Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…)">[33]</a><a href="https://link.springer.com/chapter/10.1007%2F978-3-319-60588-3_3" title="Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…)">[34]</a>.</li>
</ul>
<h2>The basic solution</h2>
<p>We can standarize current practise by providing a C <code>secure_clear</code> function that takes a pointer and a size, which clears the memory (with indeterminate values) and guarantees that it won’t be optimized away:</p>
<pre><code>secure_clear(password, size);
</code></pre>
<p>As well as a <code>secure_clear</code> function template for C++ that takes a reference to a non-pointer <code>trivially_copyable</code> object and clears it entirely:</p>
<pre><code>std::secure_clear(password);
</code></pre>
<p>Note that the intention here is not to discuss Annex K in its entirety (e.g. to make it mandatory). Instead, we want to focus on a specific need that projects have right now (clearing sensitive data from memory), as explained in the previous sections.</p>
<p>An alternative solution would be to just make <code>memset_s</code> mandatory. However:</p>
<ul>
<li>This implies specifying a particular value instead of leaving memory with indeterminate values, i.e. it looks like it is intended to <em><strong>set new</strong></em> values rather than <em><strong>disposing of old</strong></em> data. This point was polled at WG21 Kona 2019 <a href="http://wiki.edg.com/bin/view/Wg21kona2019/P1315" title="P1315R1 minutes at Kona 2019">[35]</a> and the result was to go for the latter (if the function were to be added to C++).</li>
<li>A different name for the function may also be key to emphasize the intended semantics.</li>
<li><code>memset_s</code>’ interface/signature follows Annex K patterns, which may be objected to.</li>
</ul>
<h2>Further issues and improvements</h2>
<p>While it is a good practise to ensure that the memory is cleared as soon as possible, there are other potential improvements when handling sensitive data in memory:</p>
<ul>
<li>Reducing the number of copies to a minimum.</li>
<li>Clearing registers, caches, the entire stack frame, etc.</li>
<li>Locking/pinning memory to avoid the data being swapped out to external storage (e.g. disk).</li>
<li>Encrypting the memory while it is not being accessed to avoid plain-text leaks (e.g. to a log or in a core dump).</li>
<li>Turning off speculative execution (or mitigating it). At the time of writing, Spectre-class vulnerabilities are still being fixed (either in software or in hardware), and new ones are coming up <a href="https://www.youtube.com/watch?v=_f7O3IfIR2k" title="CppCon 2018: Chandler Carruth “Spectre: Secrets, Side-Channels, Sandboxes, and Security”">[36]</a>.</li>
<li>Techniques related to control flow, e.g. control flow balancing (making all branches spend the same amount of time).</li>
</ul>
<p>Most of these extra improvements require either non-portable code, operating-system-specific calls, or compiler support as well, which also makes them a good target for standardization. A subset (e.g. encryption-at-rest and locking/pinning) may be relatively easy to tackle in the near future since libraries/projects and other languages handle them already. Other improvements, however, are well in the research stage on compilers, e.g.:</p>
<ul>
<li>The SECURE project and GCC (stack erasure implemented as a function attribute) <a href="https://www.youtube.com/watch?v=Lg_jJLtH7R0" title="The SECURE Project and GCC - GNU Tools Cauldron 2018">[37]</a><a href="https://gcc.gnu.org/wiki/cauldron2018#secure" title="The SECURE project and GCC">[38]</a><a href="https://www.embecosm.com/research/secure/" title="The Security Enhancing Compilation for Use in Real Environments (SECURE) project">[39]</a>.</li>
<li>Research on controlling side-effects in mainstream C compilers <a href="https://www.cl.cam.ac.uk/%7Erja14/Papers/whatyouc.pdf" title="What you get is what you C: Controlling side effects in mainstream C compilers">[40]</a>.</li>
</ul>
<p>Further, discussing the addition of security-related features to the C and C++ languages is rare. Therefore, this paper attempts to only spearhead the work on this area, providing access to users to the well-known “guaranteed memory clearing” function already used in the industry as explained in the previous sections.</p>
<p>Some other related C++ improvements based on the basic building blocks can be also thought of, too:</p>
<ul>
<li>For instance, earlier revisions of the C++ paper <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1315r1.html" title="P1315R1 `secure_val`: a secure-clear-on-move type">[41]</a> proposed, in addition, an uncopyable class template meant to wrap a memory area on which <code>secure_clear</code> is called on destruction/move, plus some other features (explicit read/modify/write access, locking/pinning, encryption-at-rest, etc.). This wrapper is a good approach to ensure memory is cleared even when dealing with exceptions. During the WG21 LEWGI review, it was acknowledged that similar types are in use by third-parties. Some libraries and languages feature similar types. It was decided at WG21 Kona 2019 <a href="http://wiki.edg.com/bin/view/Wg21kona2019/P1315" title="P1315R1 minutes at Kona 2019">[35]</a> to reduce the scope of the paper and only provide the basic building block, <code>secure_clear</code>.</li>
<li>A type-modifier with similar semantics as the wrapper class template above was suggested during the WG21 LEWGI review.</li>
<li>Dynamically-sized string-like types (e.g. <code>secure_string</code>) may be considered useful (e.g. for passwords).</li>
</ul>
<p>There are, as well, other related library features:</p>
<ul>
<li>A way to read non-echoed standard input (e.g. see the <code>getpass</code> module in Python <a href="https://docs.python.org/3.7/library/getpass.html" title="Portable password input">[42]</a>).</li>
</ul>
<h2>Proposal</h2>
<p>This proposal adds a <code>secure_clear</code> function (C) and a <code>secure_clear</code> function template (C++).</p>
<h3><code>secure_clear</code> function</h3>
<pre><code>void secure_clear(void * data, size_t size);
</code></pre>
<p>The <code>secure_clear</code> function is intended to make the contents of the memory range <code>[data, data + size)</code> impossible to recover. It can be considered equivalent to a call to <code>memset(data, value, size)</code> with indeterminate <code>value</code>s (i.e. there may even be different values, e.g. randomized). However, the compiler must guarantee the call is never optimized out unless the data was not in memory to begin with.</p>
<ul>
<li>To clarify: the call may be removed by the compiler if there is no actual memory involved, instead of forcing itself to use actual memory and then clearing it (which would make the call pointless and less secure to begin with). For instance, if the compiler chose to keep the data in a register because it is small enough (and its address was not taken anywhere else), then the call could be elided. In a way, there was no memory to clear to begin with, so it could be considered that it was not optimized out.</li>
<li>Note: at WG21 Kona 2019 <a href="http://wiki.edg.com/bin/view/Wg21kona2019/P1315" title="P1315R1 minutes at Kona 2019">[35]</a> it was polled whether the compiler should be free to implement further guarantees (e.g. clearing cache/registers containing it) and/or whether we should encourage them to do so. The result was neutral, so further input from experts from both WG14 and WG21 would be needed to decide this.</li>
</ul>
<p>An approach for the wording would be to use the one for <code>memset_s</code>:</p>
<blockquote>
<p>Unlike <code>memset</code>, any call to the <code>memset_s</code> function shall be evaluated strictly according to the rules of the abstract machine as described in (5.1.2.3). That is, any call to the <code>memset_s</code> function shall assume that the memory indicated by <code>s</code> and <code>n</code> may be accessible in the future and thus must contain the values indicated by <code>c</code>.</p>
</blockquote>
<p>In the case of C++ (assuming the function is not imported from C), a possible approach would be to lift the provision in [intro.abstract]p1 (i.e. the “as-if” rule) for calls to this function; thus conforming implementations need to emulate the behavior of the abstract machine and therefore produce code equivalent to having called the function, even if it has no effect on the observable behavior of the program.</p>
<p>Given this function imposes unusual restrictions/behavior, this paper was forwarded to WG21 EWG at Kona 2019 <a href="http://wiki.edg.com/bin/view/Wg21kona2019/P1315" title="P1315R1 minutes at Kona 2019">[35]</a>, and then to WG21 SG1 at Cologne 2019 <a href="http://wiki.edg.com/bin/view/Wg21cologne2019/P1315" title="P1315R2 minutes at Cologne 2019">[43]</a>.</p>
<h3><code>secure_clear</code> function template</h3>
<pre><code>namespace std {
template <class T>
requires is_trivially_copyable_v<T>
and (not is_pointer_v<T>)
void secure_clear(T & object) noexcept;
}
</code></pre>
<p>The <code>secure_clear</code> function template is equivalent to a call to <code>secure_clear(addressof(object), sizeof(object))</code>.</p>
<p>The <code>not is_pointer_v<T></code> constraint is intended to prevent unintended calls that would have cleared a pointer rather than the object it points to:</p>
<pre><code>char buf[100];
char * buf2 = buf;
std::secure_clear(buf); // OK, clears the array
std::secure_clear(buf2); // Error
std::secure_clear(buf2, sizeof(buf2)); // OK, explicit
</code></pre>
<h2>Naming</h2>
<p>Several alternatives were considered for the initial name of the proposed <code>secure_clear</code> function and function template. Some were also suggested during the WG21 LEWGI review.</p>
<p>In general, there are many possible terms that may be used to form a name:</p>
<ul>
<li><code>mem</code> and variations</li>
<li><code>secure</code></li>
<li><code>clear</code></li>
<li><code>explicit</code></li>
<li><code>zero</code></li>
<li><code>scrub</code></li>
<li><code>overwrite</code></li>
<li><code>smash</code></li>
<li><code>erase</code></li>
<li><code>set</code></li>
<li><code>sensitive</code></li>
<li>…</li>
</ul>
<p>Decisions regarding naming should come later on.</p>
<h2>Example implementation</h2>
<p>A trivial example implementation (i.e. relying on OS-specific functions) can be found at <a href="https://github.com/ojeda/secure_clear/tree/master/example-implementation" title="`secure_clear` Example implementation">[44]</a>.</p>
<h2>Acknowledgements</h2>
<p>Thanks to Aaron Ballman, JF Bastien and Billy O’Neal for providing guidance about the WG14 and WG21 standardization processes. Thanks to Ryan McDougall for presenting the paper at WG21 Kona 2019. Thanks to Graham Markall for his input regarding the SECURE project and the current state on compiler support for related features. Thanks to Martin Sebor for pointing out the SECURE project. Thanks to BSI for suggesting constraining the template to non-pointers. Thanks to everyone else that joined all the different discussions.</p>
<h2>References</h2>
<ol>
<li>MSC06-C. Beware of compiler optimizations — <a href="https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations" title="MSC06-C. Beware of compiler optimizations"><em>https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations</em></a></li>
<li>CWE-14: Compiler Removal of Code to Clear Buffers — <a href="https://cwe.mitre.org/data/definitions/14.html" title="CWE-14: Compiler Removal of Code to Clear Buffers"><em>https://cwe.mitre.org/data/definitions/14.html</em></a></li>
<li>V597. The compiler could delete the <code>memset</code> function call (…) — <a href="https://www.viva64.com/en/w/v597/" title="V597. The compiler could delete the `memset` function call (...)"><em>https://www.viva64.com/en/w/v597/</em></a></li>
<li>N1381 — #5 <code>memset_s()</code> to clear memory, without fear of removal — <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf" title="N1381 --- #5 `memset_s()` to clear memory, without fear of removal"><em>http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf</em></a></li>
<li><code>openssl/crypto/ec/curve448/utils.c</code> (old code) — <a href="https://github.com/openssl/openssl/blob/f8385b0fc0215b378b61891582b0579659d0b9f4/crypto/ec/curve448/utils.c" title="`openssl/crypto/ec/curve448/utils.c` (old code)"><em>https://github.com/openssl/openssl/blob/f8385b0fc0215b378b61891582b0579659d0b9f4/crypto/ec/curve448/utils.c</em></a></li>
<li><code>OPENSSL_cleanse</code> (implementation) — <a href="https://github.com/openssl/openssl/blob/master/crypto/mem_clr.c" title="`OPENSSL_cleanse` (implementation)"><em>https://github.com/openssl/openssl/blob/master/crypto/mem_clr.c</em></a></li>
<li><code>openssl/crypto/mem.c</code> (old code) — <a href="https://github.com/openssl/openssl/blob/104ce8a9f02d250dd43c255eb7b8747e81b29422/crypto/mem.c#L143" title="`openssl/crypto/mem.c` (old code)"><em>https://github.com/openssl/openssl/blob/104ce8a9f02d250dd43c255eb7b8747e81b29422/crypto/mem.c#L143</em></a></li>
<li><code>openssl/crypto/sparccpuid.S</code> (example of assembly implementation) — <a href="https://github.com/openssl/openssl/blob/master/crypto/sparccpuid.S#L363" title="`openssl/crypto/sparccpuid.S` (example of assembly implementation)"><em>https://github.com/openssl/openssl/blob/master/crypto/sparccpuid.S#L363</em></a></li>
<li><code>memzero_explicit</code> (implementation) — <a href="https://elixir.bootlin.com/linux/v4.18.5/source/lib/string.c#L706" title="`memzero_explicit` (implementation)"><em>https://elixir.bootlin.com/linux/v4.18.5/source/lib/string.c#L706</em></a></li>
<li>Options Controlling C Dialect — <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html" title="Options Controlling C Dialect"><em>https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html</em></a></li>
<li><code>bzero</code>, <code>explicit_bzero</code> - zero a byte string — <a href="http://man7.org/linux/man-pages/man3/bzero.3.html" title="`bzero`, `explicit_bzero` - zero a byte string"><em>http://man7.org/linux/man-pages/man3/bzero.3.html</em></a></li>
<li><code>SecureZeroMemory</code> function — <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa366877(v=vs.85).aspx" title="`SecureZeroMemory` function"><em>https://msdn.microsoft.com/en-us/library/windows/desktop/aa366877(v=vs.85).aspx</em></a></li>
<li><code>memzero_explicit</code> — <a href="https://www.kernel.org/doc/htmldocs/kernel-api/API-memzero-explicit.html" title="`memzero_explicit`"><em>https://www.kernel.org/doc/htmldocs/kernel-api/API-memzero-explicit.html</em></a></li>
<li><code>OPENSSL_cleanse</code> — <a href="https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_cleanse.html" title="`OPENSSL_cleanse`"><em>https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_cleanse.html</em></a></li>
<li>Reimplement non-asm <code>OPENSSL_cleanse()</code> #455 — <a href="https://github.com/openssl/openssl/pull/455" title="Reimplement non-asm `OPENSSL_cleanse()` #455"><em>https://github.com/openssl/openssl/pull/455</em></a></li>
<li>How to zero a buffer — <a href="http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html" title="How to zero a buffer"><em>http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html</em></a></li>
<li>Hacker News: How to zero a buffer (daemonology.net) — <a href="https://news.ycombinator.com/item?id=8270136" title="Hacker News: How to zero a buffer (daemonology.net)"><em>https://news.ycombinator.com/item?id=8270136</em></a></li>
<li>Mac OS X equivalent of <code>SecureZeroMemory</code> / <code>RtlSecureZeroMemory</code>? — <a href="https://stackoverflow.com/questions/13299420/" title="Mac OS X equivalent of `SecureZeroMemory` / `RtlSecureZeroMemory`?"><em>https://stackoverflow.com/questions/13299420/</em></a></li>
<li>Optimising away <code>memset()</code> calls? — <a href="https://gcc.gnu.org/ml/gcc-help/2014-10/msg00047.html" title="Optimising away `memset()` calls?"><em>https://gcc.gnu.org/ml/gcc-help/2014-10/msg00047.html</em></a></li>
<li>Bug 15495 - dead store pass ignores memory clobbering asm statement — <a href="https://bugs.llvm.org/show_bug.cgi?id=15495" title="Bug 15495 - dead store pass ignores memory clobbering asm statement"><em>https://bugs.llvm.org/show_bug.cgi?id=15495</em></a></li>
<li>Bug 82041 - <code>memset</code> optimized out in <code>random.c</code> — <a href="https://bugzilla.kernel.org/show_bug.cgi?id=82041" title="Bug 82041 - `memset` optimized out in `random.c`"><em>https://bugzilla.kernel.org/show_bug.cgi?id=82041</em></a></li>
<li>[PATCH] random: add and use memzero_explicit() for clearing data — <a href="https://lkml.org/lkml/2014/8/25/497" title="[PATCH] random: add and use memzero_explicit() for clearing data"><em>https://lkml.org/lkml/2014/8/25/497</em></a></li>
<li>N1548 — C11 draft — <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf" title="N1548 --- C11 draft"><em>http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf</em></a></li>
<li><code>memset</code>, <code>memset_s</code> — <a href="https://en.cppreference.com/w/c/string/byte/memset" title="`memset`, `memset_s`"><em>https://en.cppreference.com/w/c/string/byte/memset</em></a></li>
<li>Test for <code>memset_s</code> in gcc 8.2 at Godbolt — <a href="https://godbolt.org/g/M7MyRg" title="Test for `memset_s` in gcc 8.2 at Godbolt"><em>https://godbolt.org/g/M7MyRg</em></a></li>
<li>Test for <code>memset_s</code> in clang 6.0.0 at Godbolt — <a href="https://godbolt.org/g/ZwbkgY" title="Test for `memset_s` in clang 6.0.0 at Godbolt"><em>https://godbolt.org/g/ZwbkgY</em></a></li>
<li>Test for <code>memset_s</code> in MSVC 19 2017 at Godbolt — <a href="https://godbolt.org/g/FtrVJ8" title="Test for `memset_s` in MSVC 19 2017 at Godbolt"><em>https://godbolt.org/g/FtrVJ8</em></a></li>
<li>Test for <code>memset_s</code> in icc 18.0.0 at Godbolt — <a href="https://godbolt.org/g/vHZNrW" title="Test for `memset_s` in icc 18.0.0 at Godbolt"><em>https://godbolt.org/g/vHZNrW</em></a></li>
<li>N1967 (WG14) — Field Experience With Annex K - Bounds Checking Interfaces — <a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm" title="N1967 (WG14) --- Field Experience With Annex K - Bounds Checking Interfaces"><em>http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm</em></a></li>
<li><code>SecureString</code> Class — <a href="https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring" title="`SecureString` Class"><em>https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring</em></a></li>
<li><code>securemem</code>: abstraction to an auto scrubbing and const time eq, memory chunk. — <a href="https://hackage.haskell.org/package/securemem" title="`securemem`: abstraction to an auto scrubbing and const time eq, memory chunk."><em>https://hackage.haskell.org/package/securemem</em></a></li>
<li><code>secstr</code>: Secure string library for Rust — <a href="https://github.com/myfreeweb/secstr" title="`secstr`: Secure string library for Rust"><em>https://github.com/myfreeweb/secstr</em></a></li>
<li>Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…) — <a href="https://proteancode.com/wp-content/uploads/2017/06/ae2017_final3_for_web.pdf" title="Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…)"><em>https://proteancode.com/wp-content/uploads/2017/06/ae2017_final3_for_web.pdf</em></a></li>
<li>Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…) — <a href="https://link.springer.com/chapter/10.1007%2F978-3-319-60588-3_3" title="Sanitizing Sensitive Data: How to get it Right (or at least Less Wrong…)"><em>https://link.springer.com/chapter/10.1007%2F978-3-319-60588-3_3</em></a></li>
<li>P1315R1 minutes at Kona 2019 — <a href="http://wiki.edg.com/bin/view/Wg21kona2019/P1315" title="P1315R1 minutes at Kona 2019"><em>http://wiki.edg.com/bin/view/Wg21kona2019/P1315</em></a></li>
<li>CppCon 2018: Chandler Carruth “Spectre: Secrets, Side-Channels, Sandboxes, and Security” — <a href="https://www.youtube.com/watch?v=_f7O3IfIR2k" title="CppCon 2018: Chandler Carruth “Spectre: Secrets, Side-Channels, Sandboxes, and Security”"><em>https://www.youtube.com/watch?v=_f7O3IfIR2k</em></a></li>
<li>The SECURE Project and GCC - GNU Tools Cauldron 2018 — <a href="https://www.youtube.com/watch?v=Lg_jJLtH7R0" title="The SECURE Project and GCC - GNU Tools Cauldron 2018"><em>https://www.youtube.com/watch?v=Lg_jJLtH7R0</em></a></li>
<li>The SECURE project and GCC — <a href="https://gcc.gnu.org/wiki/cauldron2018#secure" title="The SECURE project and GCC"><em>https://gcc.gnu.org/wiki/cauldron2018#secure</em></a></li>
<li>The Security Enhancing Compilation for Use in Real Environments (SECURE) project — <a href="https://www.embecosm.com/research/secure/" title="The Security Enhancing Compilation for Use in Real Environments (SECURE) project"><em>https://www.embecosm.com/research/secure/</em></a></li>
<li>What you get is what you C: Controlling side effects in mainstream C compilers — <a href="https://www.cl.cam.ac.uk/%7Erja14/Papers/whatyouc.pdf" title="What you get is what you C: Controlling side effects in mainstream C compilers"><em>https://www.cl.cam.ac.uk/~rja14/Papers/whatyouc.pdf</em></a></li>
<li>P1315R1 <code>secure_val</code>: a secure-clear-on-move type — <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1315r1.html" title="P1315R1 `secure_val`: a secure-clear-on-move type"><em>http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1315r1.html</em></a></li>
<li>Portable password input — <a href="https://docs.python.org/3.7/library/getpass.html" title="Portable password input"><em>https://docs.python.org/3.7/library/getpass.html</em></a></li>
<li>P1315R2 minutes at Cologne 2019 — <a href="http://wiki.edg.com/bin/view/Wg21cologne2019/P1315" title="P1315R2 minutes at Cologne 2019"><em>http://wiki.edg.com/bin/view/Wg21cologne2019/P1315</em></a></li>
<li><code>secure_clear</code> Example implementation — <a href="https://github.com/ojeda/secure_clear/tree/master/example-implementation" title="`secure_clear` Example implementation"><em>https://github.com/ojeda/secure_clear/tree/master/example-implementation</em></a></li>
</ol>
</div>
</div>
</div>
<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>
<script>
var allCodeBlocks = document.getElementsByTagName("pre");
for (var i = 0; i < allCodeBlocks.length; ++i)
allCodeBlocks[i].innerHTML = PR.prettyPrintOne(allCodeBlocks[i].innerHTML, "cpp");
</script>
</body>
</html>