<div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Den tis 20 juli 2021 20:21Peter Gutmann <<a href="mailto:pgut001@cs.auckland.ac.nz" target="_blank" rel="noreferrer">pgut001@cs.auckland.ac.nz</a>> skrev:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Patrick Chkoreff <<a href="mailto:pc@fexl.com" rel="noreferrer noreferrer" target="_blank">pc@fexl.com</a>> writes:<br>
<br>
>I believe in the case of NaCl, "knowing what you're doing" is simply this:<br>
><br>
>0. Do not reuse a nonce.<br>
<br>
And that, along with telling people "don't write code that's vulnerable to<br>
buffer overflows", "dont write code that facilitates SQLI and XSS", and "don't<br>
write code that gets access control wrong" is all we need to do to ensure<br>
things are completely secure.  QED.<br>
<br>
>Does one have to be a genius to read 24 bytes from /dev/urandom?<br>
<br>
To do that, you first have to know what a nonce is.  Then you have to know why<br>
it's important.  Then you have to know how to use it and how not to use it.<br>
Then you have to be able to design and implement something where an attacker<br>
can't force nonce reuse in some way.  And finally you have to design and<br>
implement everything 100% flawlessly and perfectly (see my previous comment<br>
about the expert cryptographer and the 1-character typo).<br>
<br>
Overall, it's about the same level of difficulty as avoiding buffer overflows<br>
or SQLI.  Meaning that in real life people get it wrong over and over and<br>
over, just look at the history of (mis)use of RC4 to see this.<br></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Even if a given program does try to do exactly the right thing with randomness handling, it will still be dependent on its environment. And even the OS RNG might not be trustworthy in many environments.</div><div dir="auto"><br></div><div dir="auto">For example when old Android versions used to have an insecure RNG exposed by default in its Java environment, which led to loss of funds via Bitcoin wallets (ECDSA k value reuse). Or embedded devices with no hardware RNG which generates keys on first boot, where most of them end up generating identical device keys.</div><div dir="auto"><br></div><div dir="auto">In these circumstances it doesn't even matter that the programmer knew what they were doing. </div><div dir="auto"><br></div><div dir="auto">Or for a more modern variant of this problem, why not consider virtualized code running in containers or VM:s. These frequently don't have a real RNG exposed from the host (the option may exist but isn't always enabled), or where a running application's state may be snapshotted and replicated into multiple instances, including the creation of multiple instances of "single use" secrets.</div><div dir="auto"><br></div><div dir="auto">If you insist on using a stream cipher for anything but an actual stream of data (like a TLS connection) for which you can make a plausible argument for why a key/IV is unlikely to be reused, then the only robust option is a SIV construction or equivalent MRAE modes (for example AES-GCM-SIV). SIV like modes uses the message and key as inputs to derive the IV (so it's two-pass), so different messages encrypted under the same key are highly unlikely to get the same IV even if you have a bad RNG. But at this point you start to lose some of the simplicity and performance advantages of stream ciphers anyway. </div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>