<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Oct 31, 2015 at 11:50 AM, Alessandro Ghedini via RT <span dir="ltr"><<a href="mailto:rt@openssl.org" target="_blank">rt@openssl.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">In any case memset_s is not available anywhere anyway, so that doesn't really<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
matter.<br></blockquote><div><br></div><div>Is it available in some places, e.g. <a href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/memset_s.3.html" target="_blank">https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/memset_s.3.html</a>.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span><br>
> * Otherwise, SecureZeroMemory, when SecureZeroMemory is available.<br>
> * Otherwise, if a flag OPENSSL_REQUIRE_SECURE_ZERO is set, fail.<br>
<br>
</span>In 99% of the cases (e.g. Linux with glibc or any *BSD) that would fail, so I<br>
don't see the point in that.<br></blockquote><div><br></div><div>The point is to let the person building OPENSSL say "I want the build to fail if there isn't a secure way to zero memory, because I'm expecting there to always be one in my configuration." Alternatively, there could be an OPENSSL_USE_MEMSET_S flag that says "always use memset_s and never anything else."</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>> Note in particular that the C compiler is allowed to completely defeat the<br>
> purpose of the function unless SecureZeroMemory or memset_s is used, even<br>
> if you use "volatile" or other tricks.<br>
<br>
</span>I don't think that is true (regarding the volatile pointer). But assuming that<br>
a broken compiler decided to optimize that call away, what's stopping it to<br>
optimize the call to the asm implementation as well? Also, such broken compiler<br>
probably wouldn't know about C11 either, so even if memset_s() was available it<br>
could optimize that as well.<br></blockquote><div><br></div><div>Such optimizations are legal. Otherwise, C11 wouldn't have defined |memset_s|. And, the entire purpose of |memset_s| is to disable such optimizations.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">I don't know how compilers are supposed to treat memset_s(), but if I define a<br>
memset_s() function which just calls memset() internally, GCC (v5.2.1 20151028)<br>
optimizes that away just as it does with plain memset(), so libc<br>
implementations would probably need to adopt "tricks" to avoid the optimization<br>
as well.<br></blockquote><div><br></div><div>Right. It has to be built into the compiler.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">FWIW OpenSSH implements the portable explicit_bzero() using the volatile<br>
pointer as well (unless memset_s() is detected at build time).</blockquote><div><br></div><div>That is similar to what I'm suggesting.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On OpenBSD it<br>
just uses OpenBSD's explicit_bzero() which is implemented using memset() and a<br>
weak function pointer.</blockquote><div><br></div><div>It is a good idea to detect OpenBSD at compile time and use |explicit_bzero|, just like for |SecureZeroMemory| on Windows.</div><div><br></div><div>Don't pay much attention to what tricks OpenBSD's |explicit_bzero| uses. Those tricks are not guaranteed to work for anything other than that one function on OpenBSD.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">But that (as used in LibreSSL) seems to have problems in<br>
relation to LTO, unless optimizations are specifically disabled:<br>
<a href="https://github.com/libressl-portable/openbsd/issues/5" rel="noreferrer" target="_blank">https://github.com/libressl-portable/openbsd/issues/5</a></blockquote><div><br></div><div>Right, this is more evidence that the only correct implementation is to use a compiler-provided |memset_s|, |explicit_bzero|, |SecureZeroMemory|. It is not possible to implement your own in a way that is guaranteed to work. If you need to implement your own.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On the other hand BoringSSL uses memset() with an explicit memory barrier<br></blockquote><div><br></div><div>The explicit memory barrier is bad for performance.</div><div><br></div><div>And, it also isn't guaranteed to work. I don't speak for the BoringSSL team, but in correspondence with them, they don't seem to care much if OpenSSL_cleanse works or if it is used.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>> The primary purpose of the assembly language implementations is to reduce the<br>
> possibility that the C compiler will do the weird things that C compilers love<br>
> to do.<br>
<br>
</span>According to the changelog and git log, the primary purpose of the asm<br>
implementations was to improve performance (see commit b2dba9b). Using the<br>
volatile pointer implementation would IMO make these optimizations useless,<br>
hence the proposal to drop them and make things simpler.</blockquote><div><br></div><div>Sorry. Instead of "primary purpose" (which implies intent), I should have said 'primary advantage".  An assembly language implementation is more likely to work than a C implementation because the C compiler generally won't analyze externally-assembled code, so it has to assume that the externally-assembled code has side effects, so it must call the externally-assembled code. In theory, it is possible for the assembler, C compiler, and the linker to work together during LTO and figure out that the assembly language implementation doesn't have any side effects other than zeroing memory, but that seems unlikely--much less likely than the C compiler subverting any trick.</div><div><br></div><div>Note that sometimes I notice places that OpenSSL doesn't call OPENSSL_cleanse when it seems like it would be warranted to be consistent with other code. ecdh_compute_key [1] is one example. Generally, I don't expect OpenSSL to (securely) zero memory, so it doesn't matter much to me. But, if it matters to others, then this is something that would require an substantial amount of auditing and fixing.</div><div><br></div><div><div>[1] <a href="https://github.com/openssl/openssl/blob/965a1cb92e4774ca2f74dad9e060aa7b2d80c77d/crypto/ecdh/ech_ossl.c#L82" target="_blank">https://github.com/openssl/openssl/blob/965a1cb92e4774ca2f74dad9e060aa7b2d80c77d/crypto/ecdh/ech_ossl.c#L82</a></div><div><br></div></div><div>Cheers,<br></div><div>Brian</div></div>-- <br><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><a href="https://briansmith.org/" target="_blank">https://briansmith.org/</a></div><div><br></div></div></div></div></div></div></div>
</div></div>