-
Notifications
You must be signed in to change notification settings - Fork 5
/
N2599.html
468 lines (443 loc) · 47.2 KB
/
N2599.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
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
<!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 (update to N2505)</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`-like function (C) and a `secure_clear`-like 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/n2599.htm">
<meta property="og:type" content="website">
<meta property="og:title" content="secure_clear (update to N2505)">
<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`-like function (C) and a `secure_clear`-like 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 (update to N2505)",
"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`-like function (C) and a `secure_clear`-like function template (C++) that guarantee users that a memory area is cleared.",
"url": "http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2599.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" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABRUlEQVQ4y9XSP0iVURgG8N/5Pv9ccNVKbHERdXKqtWitXHKLmi+0iX/g2BB4h0KMyIaWWiNCcHBvcNOGloZaWsQhCAIH0Xvvcfi+C8e4tUbP+JzzPu/D87z8awQxBZRaoX3hJaYSSSt0a6ZAmf1oI/WXrUQrNL+GvxoQ06yYnvUReSSmuxkzj4/Yxztc7dmaxpKYbmbDM3ipc3YLlENNvMEWHuIQn3ClwCS+Yynb1sSRcqDKJXXW8AAf8AWLtZMnPQfP8UtMd8Q0iutYNhTGMEUYxm4WJuzgWoERHOMV7mM12zT+56QrbwUa6GqFPUxgUbu9gYZTl/CN0MXteqhX6z0cFBjLtmxixdPBhBPdzuWqrPAYb7GAObzALOIA3uMzaIXtzN6hotyylkrr4TV+1kE26hZu4Ef/48kxNf87P3jxkP57nAO+hlg6xexR1gAAAABJRU5ErkJggg==">
<style>
/*!
* Bootstrap Reboot v4.5.3 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
@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;
}
}
.container {
width: 100%;
max-width: 900px;
padding-right: 165px;
padding-left: 165px;
margin-right: auto;
margin-left: auto;
justify-content: center !important;
}
h1, h2, h3 {
font-weight: 500;
line-height: 1.2;
margin-top: 0;
margin-bottom: .5rem;
}
h1 {
font-size: 2.3rem;
margin-top: 2rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
code {
font-size: 87.5%;
color: #e83e8c;
word-wrap: break-word;
}
a > code {
color: inherit;
}
pre code {
font-size: inherit;
color: inherit;
word-break: normal;
}
pre {
background-color: #f5faff;
border-radius: 0.4em;
border-color: #c5c5c5;
border-width: 1px;
border-style: solid;
padding: 0.7em;
display: block;
font-size: 87.5%;
color: #212529;
}
blockquote {
background-color: #f5faff;
border-radius: 0.4em;
border-color: #c5c5c5;
border-width: 1px;
border-style: solid;
padding: 0.7em;
}
blockquote > h5 {
font-size: 0.9rem;
}
ol > li {
text-align: start;
font-size: .9rem;
}
p {
text-align: justify;
}
p:last-child {
margin-bottom: 0;
}
a {
word-break: break-word;
}
.hljs-keyword, .hljs-name {
color: #0070cc;
}
.hljs-number {
color: #b55600;
}
.hljs-comment {
color: #138600;
font-style: italic;
}
</style>
</head>
<body>
<div class="container">
<h1><code>secure_clear</code> (update to N2505)</h1>
<p>C Document number: N2599 <br />
C++ Document number: P1315 <a href="http://wg21.link/P1315">[latest]</a><br />
Date: 2020-10-20<br />
Author: Miguel Ojeda <<a href="mailto:m@ojeda.dev">m@ojeda.dev</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>-like function (C) and a <code>secure_clear</code>-like function template (C++) that guarantee users that a memory area is cleared.</p>
<h2>Changelog</h2>
<p><strong>N2599</strong> – Update to N2505:</p>
<ul>
<li>Added 3 wording alternatives.</li>
<li>Removed “Naming” section and integrated the rationale into each proposed alternative.</li>
<li>Minor modifications in other sections, including style changes.</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
get_password_from_user(password, size);
// Use it for some operations
use_password(password, size);
// Attempt to clear the sensitive data
std::memset(password, 0, size);
}
</code></pre>
<p>On top of that, <code>use_password</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>-like function that takes a memory range (a pointer and a size) to be erased, guaranteeing 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>-like function template for C++ that takes a reference to a non-pointer <code>trivially_copyable</code> object to scrub it entirely:</p>
<pre><code>std::secure_clear(password);
</code></pre>
<p>The precise names and interfaces depend on the semantics we want. Three main alternatives are proposed in a later section.</p>
<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 values</strong></em>” rather than “<em><strong>disposing of old data</strong></em>”. 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>Furthermore, 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>
<p>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 was seeked to decide this point.</p>
<p>Note: 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>
<h2>Proposal (C)</h2>
<p>This proposal suggests three main alternatives for the addition of a <code>secure_clear</code>-like function, sorted from least to most similar to the existing Annex K <code>memset_s</code> interface.</p>
<p>The proposed wordings are with respect to the N2573 draft.</p>
<p>The suggested names for each alternative have been selected to try to reflect the semantics closely as well as to differentiate between them to facilitate discussion. They have also been picked to be within the space of reserved identifiers within <code>string.h</code>.</p>
<h3>Alternative 1: <code>memerase</code></h3>
<p>Compared to the others, this alternative:</p>
<ul>
<li>Writes an indeterminate value.</li>
<li>Does <em>not</em> return the pointer.</li>
<li>Emphasizes the idea of erasing data, rather than overwriting with a particular value.</li>
</ul>
<p>Writing an indeterminate value gives freedom to the implementation to choose the best value (or values, or patterns, or randomized values, etc.) for the purposes of erasing the sensitive data, which may depend on the particular hardware or the placement of the memory (e.g. global memory, stack memory, etc.). It also gives freedom to choose a bit pattern that might be a trap representation, which might be useful under certain environments to detect errors.</p>
<p>Furthermore, in principle it allows implementations to write a trap representation that triggers the program to stop.</p>
<p>For the use case of clearing a buffer that will be freed/destroyed, the advantage is that the written value is not important:</p>
<pre><code>void f(void) {
char s[n];
// ...
memerase(s, n); // No value needed
}
</code></pre>
<p>However, if users <em>are</em> going to reuse the buffer, then they need to set a value explicitly, making such reuse more clear:</p>
<pre><code>memerase(s, n);
memset(s, 42, n); // Explicitly request a value
</code></pre>
<p>Making this case explicit is useful for implementations that may be able to print a diagnostic message if the buffer is read from without having being written again (e.g. similar to uninitialized variable warnings):</p>
<pre><code>memerase(s, n);
printf("%s", s); // Mistake
</code></pre>
<p>Furthermore, the function does not return the pointer as an attempt to prevent reuses of such pointer without careful consideration. It also prevents “hiding” the erasure in a single line like:</p>
<pre><code>memset(memerase(s, n), 42, n); // Error
</code></pre>
<p>which makes it harder to spot (e.g. during a refactor).</p>
<p>Finally, this alternative is the one where avoiding <code>_explicit</code> in the name may be reasonable, since <code>erase</code> feels like performs something different than just a clear/zero/set of memory.</p>
<h4>Proposed Wording</h4>
<p>After “7.24.6.1 The <code>memset</code> function”, add:</p>
<blockquote>
<h4>7.24.6.2 The <code>memerase</code> function</h4>
<h5>Synopsis</h5>
<pre><code>#include <string.h>
void memerase(void *s, size_t n);
</code></pre>
<h5>Description</h5>
<p>The <code>memerase</code> function copies indeterminate values (converted to <code>unsigned char</code>) into each of the first <code>n</code> characters of the object pointed to by <code>s</code> as a needed side effect (5.1.2.3) (Footnote 1). The purpose of this function is to make sensitive information stored in the object inaccessible.</p>
<p>(Footnote 1) The intention is that the memory store is always performed (i.e. never elided), regardless of optimizations. This is in constract to calls to the <code>memset</code> function.</p>
<p>The implementation may not clear other copies of the data (e.g. intermediate values, cache lines, spilled registers, etc.).</p>
<h5>Recommended Practice</h5>
<p>A call to the <code>memerase</code> function should have similar performance to a call to the <code>memset</code> function.</p>
<p>The implementation should produce a diagnostic message if the written characters of the object pointed to by <code>s</code> are read from before they has been written again (i.e. they can be regarded as uninitialized after the call).</p>
</blockquote>
<p>In “B.23 String handling <code><string.h></code>”, after the <code>memset</code> line, add:</p>
<pre><code>void memerase(void *s, size_t n);
</code></pre>
<p>In “J.6.1 Rule based identifiers”, after the <code>memset</code> line, add:</p>
<pre><code>memerase
</code></pre>
<h3>Alternative 2: <code>memclear_explicit</code></h3>
<p>Compared to the others, this alternative:</p>
<ul>
<li>Writes a <code>0</code> value.</li>
<li>Returns the pointer.</li>
<li>Emphasizes that a zero is being written and that it is always performed.</li>
</ul>
<p>For the use case of clearing a buffer that will be freed/destroyed, the advantage of unconditionally writing <code>0</code> is that no value needs to be passed:</p>
<pre><code>void f(void) {
char s[n];
// ...
memclear_explicit(s, n); // No value needed
}
</code></pre>
<p>However, at the same time, if users <em>are</em> going to reuse the buffer, it is common that they need it to be zero-filled, which means they don’t need to do anything else in that case:</p>
<pre><code>memclear_explicit(s, n);
printf("%s", s); // OK, initialized
</code></pre>
<p>Furthermore, since the memory is initialized, returning the pointer makes more sense to be used right away and also mimics the <code>memset</code> interface.</p>
<p>Finally, we add <code>_explicit</code> as a suffix because otherwise <code>memclear(s, n)</code> might be interpreted as just a shortcut for <code>memset(s, 0, n)</code> without the side effect guarantees.</p>
<h4>Proposed Wording</h4>
<p>After “7.24.6.1 The <code>memset</code> function”, add:</p>
<blockquote>
<h4>7.24.6.2 The <code>memclear_explicit</code> function</h4>
<h5>Synopsis</h5>
<pre><code>#include <string.h>
void *memclear_explicit(void *s, size_t n);
</code></pre>
<h5>Description</h5>
<p>The <code>memclear_explicit</code> function copies the value of <code>0</code> (converted to <code>unsigned char</code>) into each of the first <code>n</code> characters of the object pointed to by <code>s</code> as a needed side effect (5.1.2.3) (Footnote 1). The purpose of this function is to make sensitive information stored in the object inaccessible.</p>
<p>(Footnote 1) The intention is that the memory store is always performed (i.e. never elided), regardless of optimizations. This is in constract to calls to the <code>memset</code> function.</p>
<p>The implementation may not clear other copies of the data (e.g. intermediate values, cache lines, spilled registers, etc.).</p>
<h5>Recommended Practice</h5>
<p>A call to the <code>memclear_explicit</code> function should have similar performance to a call to the <code>memset</code> function.</p>
<h5>Returns</h5>
<p>The <code>memclear_explicit</code> function returns the value of <code>s</code>.</p>
</blockquote>
<p>In “B.23 String handling <code><string.h></code>”, after the <code>memset</code> line, add:</p>
<pre><code>void *memclear_explicit(void *s, size_t n);
</code></pre>
<p>In “J.6.1 Rule based identifiers”, after the <code>memset</code> line, add:</p>
<pre><code>memclear_explicit
</code></pre>
<h3>Alternative 3: <code>memset_explicit</code></h3>
<p>Compared to the others, this alternative:</p>
<ul>
<li>Writes a given <code>c</code> value.</li>
<li>Returns the pointer.</li>
<li>Emphasizes that a given value is being written and that it is always performed.</li>
</ul>
<p>The main advantage of this alternative is that it follows <code>memset</code>’s interface, semantics and naming. Users are accustomed to it, and the only difference is that optimizations are not permitted.</p>
<p>Another advantage is that any need for a specific value for the buffer reuse use case is covered.</p>
<h4>Proposed Wording</h4>
<p>After “7.24.6.1 The <code>memset</code> function”, add:</p>
<blockquote>
<h4>7.24.6.2 The <code>memset_explicit</code> function</h4>
<h5>Synopsis</h5>
<pre><code>#include <string.h>
void *memset_explicit(void *s, int c, size_t n);
</code></pre>
<h5>Description</h5>
<p>The <code>memset_explicit</code> function copies the value of <code>c</code> (converted to <code>unsigned char</code>) into each of the first <code>n</code> characters of the object pointed to by <code>s</code> as a needed side effect (5.1.2.3) (Footnote 1). The purpose of this function is to make sensitive information stored in the object inaccessible.</p>
<p>(Footnote 1) The intention is that the memory store is always performed (i.e. never elided), regardless of optimizations. This is in constract to calls to the <code>memset</code> function.</p>
<p>The implementation may not clear other copies of the data (e.g. intermediate values, cache lines, spilled registers, etc.).</p>
<h5>Recommended Practice</h5>
<p>A call to the <code>memset_explicit</code> function should have similar performance to a call to a <code>memset</code> function call.</p>
<h5>Returns</h5>
<p>The <code>memset_explicit</code> function returns the value of <code>s</code>.</p>
</blockquote>
<p>In “B.23 String handling <code><string.h></code>”, after the <code>memset</code> line, add:</p>
<pre><code>void *memset_explicit(void *s, int c, size_t n);
</code></pre>
<p>In “J.6.1 Rule based identifiers”, after the <code>memset</code> line, add:</p>
<pre><code>memset_explicit
</code></pre>
<h2>Proposal (C++)</h2>
<p>This proposal adds a <code>secure_clear</code>-like function template to C++. The name for the function template will be decided based on the one chosen for C.</p>
<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>
<p>The return value is <code>void</code>, regardless of the alternative that is chosen on the C side, given that we are taking a reference to an object rather than a pointer and a size.</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, David Keaton and Billy O’Neal for providing guidance about the WG14 and WG21 standardization processes. Thanks to Aaron Ballman, Peter Sewell, David Svoboda, Martin Uecker and others for their input on wording. 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 Philipp Klaus Krause for raising the discussion in the OpenBSD list. 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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.3.1/highlight.min.js" integrity="sha512-U12+KlhI3X2EY7U4NJZ+O0wujKcaMQZHABtaiZtE8UrPiK1O3Y4cjBe0mMFyyBptdaf+eh45hqNdsayeLQcneg==" crossorigin="anonymous"></script>
<script>hljs.initHighlightingOnLoad();</script>
</body>
</html>