
Making sure crypto remains insecure [pdf] - zorked
http://cr.yp.to/talks/2014.10.18/slides-djb-20141018-a4.pdf
======
jvehent
Bernstein on a "thought experiment", analyzing how government could have
deliberately weakened cryptographic standards through various means. It's
actually quite compelling, given that we know DES key size was weakened by the
NSA back in the 70s, against IBM's will, and that we know Dual_EC_DRBG was
backdoored also by the NSA a few years ago.

Bernstein's main point is that we need independent, peer-reviewed,
cryptography that doesn't depend on government standardization. This talk is
mostly a justification for his own work on ChaCha20/Poly1305 and DNSCurve,
that were designed to be fast, constant-time and padding resistant. But the
talk doesn't make mention of alternatives, except for Serpent that should have
been a better cipher than Rijndael in the AES competition.

A good read. I would love to see broader adoption of ChaCha20 in OpenSSL and
its standardization in TLS1.3. Google already supports it and it needs more
attention from cryptographic before we start using it everywhere. It also
seems that SHA-3 has failed to convince, and everyone is standardizing on
SHA-2 instead, despite the computational cost. Maybe here too we need an
alternative...

~~~
higherpurpose
I would also like to see Curve25519 (as well as others) supported in _all_
browsers. It really bothers me that while at least websites are making an
effort to default to ECDHE encryption with PFS, they have to resort to using
the low-performance, insecure and probably NSA-backdoored P-256 curve, because
most browsers aren't supporting anything else right now.

~~~
jvehent
If anyone has the time and skills to implement these curves in NSS, I'm sure
that the Firefox and Chrome security teams would be more than happy to enable
them!

~~~
tptacek
Very smart crypto implementors are already working on this codebase, aren't
they?

~~~
jvehent
Not being one of them myself, I can only notice that their time is limited,
and many much wanted improvements sit on the backburner waiting for a smart
crypto implementor to work on them.

NSS and OpenSSL are difficult codebases to work with, which may also explain
why it's so hard to find people to work on them.

------
Animats
He's right about the low entropy of many crypto random number generators.
There are so many cases of this that it can't be by accident.

2013: Android random number flaw exploited for Bitcoin theft.

[http://arstechnica.com/security/2013/08/google-confirms-
crit...](http://arstechnica.com/security/2013/08/google-confirms-critical-
android-crypto-flaw-used-in-5700-bitcoin-heist/)

Backdoor in RSA?

[http://arstechnica.com/security/2014/01/how-the-nsa-may-
have...](http://arstechnica.com/security/2014/01/how-the-nsa-may-have-put-a-
backdoor-in-rsas-cryptography-a-technical-primer/)

Linus Torvalds insists on accepting Intel patch to use their hardware random
number generator directly instead of just using it as one of multiple sources
being XORed together.

[http://cryptome.org/2013/07/intel-bed-
nsa.htm](http://cryptome.org/2013/07/intel-bed-nsa.htm)

Then there are "features" in SSL/TLS which make little sense, such as the
ability to change the cryptosystem during the connection. This includes
changing it to "None". That's been exploited.

[http://www.praetorian.com/blog/man-in-the-middle-tls-ssl-
pro...](http://www.praetorian.com/blog/man-in-the-middle-tls-ssl-protocol-
downgrade-attack)

~~~
tptacek
Regarding Android: not only could it be an accident, it almost certainly is an
accident. For instance: the Android RNG flaw didn't stem from a single
coherent design flaw, but rather from the meta-flaw of relying on application-
layer (or in this case runtime-layer) randomness, and not nailing the order of
initialization in all the components. It's easy to see why this would have
happened by accident: (a) the belief that runtime-layer randomness is better,
more performant, more reliable on mobile platform and (b) the lack of
understanding that a single central kernel-level RNG is superior to app-layer
RNGs (which is a relatively modern idea).

Regarding RSA: that's not a backdoor in RSA. That's a supposed backdoor in
BSAFE, a library sold by RSA. The story pertains to BSAFE's support for the
Dual-EC PKRNG. (Of the supposed backdoors propagated by the NSA, by the way,
this is probably the most credible).

I'm not sure what your allusion to Torvalds was meant to indicate.

The SSL/TLS downgrade attack you linked to didn't have anything to do with the
"None" ciphersuite, or re-negotiation.

~~~
Animats
_I 'm not sure what your allusion to Torvalds was meant to indicate._

This. Right here is where Linus Torvalds sold out:

[https://lkml.org/lkml/2012/7/5/425](https://lkml.org/lkml/2012/7/5/425)

FreeBSD didn't:

[http://arstechnica.com/security/2013/12/we-cannot-trust-
inte...](http://arstechnica.com/security/2013/12/we-cannot-trust-intel-and-
vias-chip-based-crypto-freebsd-developers-say/)

~~~
acqq
Read carefully what Linus actually wrote, not what you believe he writes. Here
he suggests an even better implementation than the one actually implemented
afterwards: feeding hwrng to the pool just like the all other sources. The
last time I've checked (a year or a two ago) the hwrng was there but had the
special treatment, not passing the same path as the other sources.

So it's more "why wasn't hwrng treated as the other sources later" than why he
wrote what he wrote here.

~~~
tptacek
I think Bernstein agrees with this, for what it's worth. I could be
remembering wrong.

~~~
JoachimSchipper
IIRC, Bernstein actually disagrees with (almost) any use of rdrand. Consider,
as a toy example, an rdrand that poisons a register, so that xor'ing it with
anything results in a known value; this might be worse than useless.

([http://blog.cr.yp.to/20140205-entropy.html](http://blog.cr.yp.to/20140205-entropy.html):
"imagine RDRAND microcode that's looking at the randomness pool that it's
about to be hashed into")

I'm not sure I agree with Bernstein here.

~~~
tptacek
I feel like I remember him saying something about how as long as it's just
another thing hashed into the randomness pool, it's not that big of a deal.
But I haven't seen that in writing anywhere. I could just be wrong.

~~~
JoachimSchipper
I cannot find anything like that for "rdrand site:cr.yp.to"; it is a
reasonable position, but I don't think it's Bernstein's.

~~~
tptacek
No, I mean, this is something I thought I heard him say in person.

------
tptacek
This is a fun slide deck, but if you'll forgive me for sucking some of the
mystique out of it: it's just a reframing of DJB's hobby horses:

* The group that standardized AES rejected cache timing as a viable attack vector: [http://cr.yp.to/antiforgery/cachetiming-20050414.pdf](http://cr.yp.to/antiforgery/cachetiming-20050414.pdf) \--- more generally, that constant-time algorithms and constructions (a feature of virtually all of Bernstein's work for the last 15+ years) aren't taken seriously in industry. Also helpful to know: there's a defensible argument that Bernstein more or less started AES cache timing research.

* Side-channel attacks weren't taken seriously by TLS, and Bernstein is affiliated with one of the research groups that found a TLS side-channel attack: [http://www.isg.rhul.ac.uk/tls/Lucky13.html](http://www.isg.rhul.ac.uk/tls/Lucky13.html)

* Application-layer randomness is a bad idea, and, like Nacl does, everyone should just use a single, carefully audit kernel RNG: [http://blog.cr.yp.to/20140205-entropy.html](http://blog.cr.yp.to/20140205-entropy.html)

* Protocols and constructions should be designed to minimize dependence on randomness, the way DJB's EdDSA does: [http://ed25519.cr.yp.to/ed25519-20110926.pdf](http://ed25519.cr.yp.to/ed25519-20110926.pdf)

* Crypto performance is both not taken seriously as a research goal and an excuse for the deployment of terrible cryptography. This isn't so much a hobby horse of DJB's as it is _his entire research career_ : [http://cr.yp.to/cv/research-net-20070115.pdf](http://cr.yp.to/cv/research-net-20070115.pdf)

* DNSSEC, with its core design goals of "sign-only", "sign offline", and "sign from the root down" is a terrible idea. A sane design would look more like DNSCurve: [http://dnscurve.org/](http://dnscurve.org/) (helps also to know that DJB has a longstanding feud with both the design team for BIND, the flagship DNSSEC implementation, and with Namedroppers, the IETF DNS standardization list).

Unsurprisingly, considering the source, these are all really great important
ideas. Bernstein is one of my heroes, and I'm certainly not trying to take him
down a peg here. I just thought it might be interesting for people to know
that this deck is less a revelation about cryptography than it is a survey of
DJB's research over the last 15 years.

I'm surprised he didn't take more time on RC4, which he was closely involved
with breaking. The story about how something as dazzlingly broken as RC4 could
have gotten so entrenched in the industry is much more interesting than the
story about how AES was standardized despite its performance relying so much
on table lookups.

~~~
jeffreyrogers
> Application-layer randomness is a bad idea, and, like Nacl does, everyone
> should just use a single, carefully audit kernel RNG

In Linux we already have this with /dev/random, right?

~~~
tptacek
Yes, modulo "carefully audited", but the problem isn't that it's not possible;
the problem is that so few applications rely on it, and that there's folklore
encouraging people not to use it.

[http://sockpuppet.org/blog/2014/02/25/safely-generate-
random...](http://sockpuppet.org/blog/2014/02/25/safely-generate-random-
numbers/)

~~~
wyager
Are you saying that that article is wrong? I was under the impression that
/dev/random and /dev/urandom on Linux were exactly the same thing, but with
urandom not being limited by the (very questionable) entropy counter.

I'm pretty sure they are _exactly_ the same on many of the BSDs.

~~~
Perseids
The thing is, /dev/urandom is not even limited by the entropy counter when
there is _no_ entropy in the system at all. That was the reason for the RSA
factor collisions: The software just used /dev/urandom during boot time when
the embedded systems did not have enough entropy available. As a remedy the
libreSSL team asked for a Linux syscall with the feature to block if and only
if the random pool has not been seeded with at least 128bit of randomness:
[https://news.ycombinator.com/item?id=8049180](https://news.ycombinator.com/item?id=8049180)

~~~
tptacek
That's a Linux bug with a universally-deployed userland workaround. There's no
question that urandom should work on Linux the way it does on FreeBSD, but
that's not a reason to avoid urandom in userland software. The death toll from
avoidance of urandom is enormous; the death toll from this bug... isn't.

~~~
nwmcsween
I would say it was both a Linux and a application bug, you could just open an
fd on both random and fallback onto urandom or even better supplement random
with a prng such as haveged.

~~~
tptacek
"Supplementing" random(4) with a userspace PRNG is exactly the anti-pattern
that Bernstein is talking about.

------
pdkl95
Re: timing attacks - can these be protected against by simply inserting into a
protocol a mandatory random sleep that is strictly larger than the worst case
run time of the crypto implementation? For example, if it takes up to 1s to
run the crypto, would a protocol that required a usleep() of
uniform_random(5s..10s)?

Such a scheme would obscure any variations in timing, right?

I ask because I have been thinking recently about the cost of "realtime", when
many use-cases don't actually need it. Bittorrent exploits this idea -
multicast is hard and most methods never really worked well enough to become
popular. Then bittorrent comes along and gives up on the idea preserving an
_ordered_ , realtime-streamable transmission. In return, bittorrent got a lot
of other features and became a very useful tool.

As these slides mention - it is easy to be blinded by a supposed need to make
everything fast.

(brainstorming) Perhaps something like a modern variation on the batched
store-and-forward used in the old FidoNet could be useful for non-interactive
needs; instead of trying to save on long-distance fees it tries use ideas like
the usleep("many seconds or more") and much larger (slower) key sizes.

/* Given the tone of those slides, I would guess that DJB just saw PHK's
amazing "Operation Orchestra" talk? BULLRUN? "PSYOPS for nerds"? The lesson is
important either way. */

~~~
tptacek
Apart from the fact that adding noise just increases the measurement cost, the
"add random sleeps" solution has two other problems, one small and one big.

The big one: it implies that you actually know what the side channel is, so
you can sleep at a useful point. The virtue of relying solely on constant-time
operations is that they're constant time by design. You don't have to worry
about how the variable-time operations are implemented, because there aren't
any.

The smaller problem is that you have to make sure that your noise function is
not itself a target of attack, which can be a little tricky because your noise
function must be extremely, extremely cheap to compute.

There's also the obvious "non-problem" that reducing a function to it's lowest
common denominator of performance defeats the purpose of high-speed
cryptography and variably-timed implementations in the first place.

~~~
kragen
_Random_ sleeps, as you say, have the problem that they don't eliminate the
timing side channel, but just add noise to it. However, as robryk points out
below, you can _eliminate_ the timing side channel entirely, assuming you know
what it is, by sleeping until a predetermined point. In pdkl95's example, you
could sleep until 1.1 seconds after the cryptographic operation was initiated,
then sending your response. The predetermined point could be determined
randomly as long as the random number generator is constrained not to return a
point that's so early that the crypto might still be running. But randomness
does not help in this case.

~~~
tptacek
You addressed the "apart from the fact" point in my comment, but not the meat
of it. I point that out because someone else already brought up the
measurement cost issue; my point was that there are other concerns.

Also, my comment directly addressed the notion of a lowest- common-
denominator sleep.

I think maybe you meant to respond to a different comment?

~~~
kragen
No, my response is attached to the correct comment of yours. I directly
responded to the two "problems" you brought up, but I will now attempt to do
so in more detail, in case the problem is that my comment was not clearly
expressed.

You say that adding sleeps only helps if you know what the side channel is.
That's true; for example, adding sleeps won't help at all against power
analysis, acoustic analysis, or cache timing attacks. But that's also true of
other side-channel countermeasures. For example, using constant-time
operations (as Bernstein suggests and you endorse) probably won't help against
attacks using those other side channels either. Most side-channel
countermeasures are only effective against the side channels they're intended
to protect, or not even those.

But pdkl95 was specifically talking about over-the-network timing side-channel
attacks on a protocol. Adding sleeps _will_ defend against that, even if you
don't know which part of your code has variable timing. For example,
Futoransky–Saura–Waissbain 2007 published "ND2DB", a feasible over-the-network
timing side-channel attack on database indices. Sleeping so that the time in
between network transactions does not depend on any of the data being
transmitted will defend against ND2DB as well as any timing attack against
your cryptosystems, while reimplementing your cryptosystems to use only
constant-time operations will not defend against Futoransky's attack.

TheLoneWolfling pointed out correctly that you can only do this imperfectly in
the presence of concurrency and caches, because the network response may take
longer to send if, for example, your data has been swapped to disk in the
interim. That is true, but I think that you can still reduce the information
leakage by two to five orders of magnitude with this approach. For example, if
you choose 1100ms as the time interval between receiving the request and
sending the response, and 0.1% of the time your response is delayed until
1108ms because of paging in a single disk page, you are leaking about 0.01
bits to the attacker per transaction. If your timing varied over about a 50ms
range and the attacker can measure latency to within 50μs, you would have been
leaking about 10 bits to the attacker per transaction.

Second, you say that you have to make sure that your noise function itself is
not a target of attack, which I take to mean that you must ensure that it
doesn't leak information either; for example, the predictable cycling of the
low-order bits of old "rand()" implementations could tell an attacker whether
the process they connected to had handled transactions from other clients in
between transactions to the attacker.

While this is true, I agree with you that it is not a big problem. Here's why.
As I said, randomness does not help in this case, so you can simply pick a
constant time interval, or one that only depends on data the attacker can
already observe, such as the response size; or you can use any CSPRNG to
generate a time to add to the constant time interval.

I didn't say anything about this before, but I also agree that it's (usually)
a non-problem to make a transaction's average-case time the same as its worst-
case time, but I don't agree that doing so "defeats the purpose of high-speed
cryptography", because high-speed cryptography generally reduces the worst-
case time to an acceptable time.

Is that better? Please correct me if I've said something incorrect above.

~~~
tptacek
That's much clearer to me. I think we probably agree more than we disagree.

My point, as you've acknowledged, is simple. I think, for a bunch of reasons
which are more and less easy to mitigate depending, it's a good rule of thumb
to just avoid key-dependent side channels altogether. If you know what you're
doing, you can shrink the risks. I'm dubious about whether they can be
eliminated.

But even if one is the kind of person who can argue eloquently and accurately
about those risks on a mailing list (nb: not alluding to you here), one is
unlikely in my experience to be the kind of person who can actually implement
countermeasures to these problems reliably. I've reviewed lots of expertly
developed cryptosystems and found exploitable problems. My experience suggests
that even good implementors do not tend to design systems from the vantage
point of attackers, which squares with my experience of every other kind of
software security as well.

A caveat to all of this is that it's easy for me to opine about what I think
good conservative rules of thumb are because my technical depth doesn't extend
to safely implementing variably-timed crypto operations. A subject matter
expert might be able to refute a lot of what I think.

Because this is a fluffy comment, a quick shotgun blast of technical
responses, none of which beg for rebuttals (but feel free):

* I can think of cases where randomized delays on one code path failed to eliminate timing leaks on other code paths that turned out to be relevant to attackers.

* I'm skeptical about exploitation of microscopic timing leaks; I don't even worry about memcmp timing, really. Other people are less skeptical, and there's a line of research pursuing statistical filtering and heuristics to bring those timing channels into reach. Also, there are some secrets that are attackable essentially indefinitely.

* My thoughts about worst-case timing are probably poisoned by client reactions to the idea of slowing down crypto operations at all.

~~~
kragen
I agree, except that I'm not skeptical about exploitation of microscopic
timing leaks.

------
cryptolect
So subtlety and obfuscation to make good ideas sound bad (serpent), and bad
ideas attractive (in the interest of performance and practicality).

So when any standards body recommends a particular cryptographic approach, we
should ask why, and then why again.

~~~
tete
Currently they say performance and performance again. Sometimes they say
nothing. Sometimes there is a good reason, sometimes there isn't. Sometimes
they want to protect, sometimes they want to attack. That's the problem when
you give one institution the job to do both.

------
pflanze
A previous version of this slide set has been published and discussed here:

[https://news.ycombinator.com/item?id=8023812](https://news.ycombinator.com/item?id=8023812)

I did put up a version of those older slides in markdown format on Github
here:

[https://github.com/pflanze/slides-
djb-20140710/blob/master/s...](https://github.com/pflanze/slides-
djb-20140710/blob/master/slides.md)

(Perhaps someone feels like forking and merging in the changes?)

------
larssorenson
Very eerie. Scary to imagine that the very systems we rely on are
fundamentally flawed even more so than generic "NSA back doors," but down to
policy of implementation.

~~~
goalieca
They keep saying China is a big enemy, so it would not be surprising if they
have growing resources to start exploiting these kinds of vulnerabilities as
well. Should stop backdooring stuff in the name of terrorism because the
economic and political damage of enemy states with growing IT resources is far
worse IMHO.

------
higherpurpose
Dan, your sliders are hard to read online, because you make us read the same
slide four times, just for an extra sentence on each. It's distracting. So
please just put together the "full" slides when you put them online.

~~~
tptacek
The supposition here is that maybe Bernstein didn't consider that raw
presentation foils were harder to read online than slideshows?

------
jstalin
In other words, all crypto is broken?

~~~
a1369209993
Technically, I think it is only saying that all crytpo _you know is not
broken_ is broken.

------
Taek
I don't think that most of the problems stem from the NSA, most of the
problems stem from the fact that security is hard, and we don't culturally
have a proper appreciation of this.

We love complexity, we love adding features and wrappers and creating
libraries, and when it comes to security this complicates things very quickly.
You end up with massive specifications, layers of dependencies, and lots of
code. And in many cases a single bug in the code can compromise the entire
system.

In security, complexity is very much the enemy and we don't apply that
mentality forcefully enough.

The crypto world is evolving quickly, and new vulnerabilities appear.
Backdoors appear, ciphers get compromised, this or that RNG is shown to be
flawed, etc. And when something that your application uses gets broken, are
you going to know? If you do know, are you going to be able to swap it out for
something more secure, or is that going to cause a lot of pain and dev time?

Lots of applications are going to prefer the single patch hotfix to the system
redesign. And this introduces more weaknesses, because often the hotfix only
addresses the single attack, and not the core vulnerability that made the
attack possible. Future attacks may be harder, but they haven't been made
impossible. (But... it's good enough, right? It'd be like, way harder now to
create an attack... right?)

Building properly secure applications is hard, because it requires you to be
minimalist, modular, and it requires you to pay attention to the latest
security problems and be aware of the types of problems you can introduce when
you implement something. Security is incredibly nuanced and you have to be
properly aware of all the nuances. A single weakness in your entire stack can
affect your whole system if you haven't carefully configured your
applications.

Crypto is broken because crypto is hard, and application builders will take
the easy way out, often without realizing that they're taking the easy way
out. Although the NSA has been shown to be an issue, most of the problems seem
to come from our own ignorance when trying to build secure applications, and
there's no silver bullet.

Creating reliably secure systems is only possible when working with simple
systems. Right now, the Internet is built with a ton of complexity. Operating
systems are built with a ton of complexity. There are many libraries with
different implementations and they all interact together in ways that are
difficult to track. (IE shellshock... who would have thought that _Bash_ would
be vulnerable?). We aren't going to have real security until we melt all of
this complexity away, and until we train ourselves to view complexity as an
enemy, and until we culturally appreciate how difficult and nuanced security
is. And that's going to take a long time and a lot of effort.

------
meshy
Does it seem ironic to anyone else that this was served over HTTP?

------
switch33
Crypto insecurity is just one of many concerns and it is missing somewhat of
the point. There will always be debate over it.

There is a chilling effect that big tech companies in the US have been working
on side channels for nearly any protocol that is ever developed. There needs
to be research into side channel resistant crypto as well.

But what about the bigger growing trend in computing that is causing more
troubles (dependency growing system wrappers)?:

Has anyone else noticed the trend for wrappers over increasingly larger and
larger parts of operating systems? For example systemd
([https://en.wikipedia.org/wiki/Systemd](https://en.wikipedia.org/wiki/Systemd))
while good for providing automation provides even more system administration
power by controlling package managers.

Docker contains configuration information for the full app that is being
deployed contained within that container as well. It will take quite some time
to make docker more secure, and using it may contain some level of attacks.

And hypervisors as well are larger and larger in size as well. There is
becoming an increasing standard for the amount of code in frameworks,
platforms, operating systems and more for interoperability.

While these are good things that need to happen as fixes need to be quicker,
they are also bad things in that they provide newer larger attack surfaces.
Cloud computing is also becoming more and more rewarding for heavyset
computation and sharing of resources. The ambiguity in choice of it all means
that there will inevitably be a plethora of choices in the cloud.

The dependencies in frameworks and how we develop software has continously
grown over the years as well to the point that people are using things like
versioneye: [https://www.versioneye.com/](https://www.versioneye.com/) to sort
changes in it all.

While diversity is good and the cloud ecosystem is becoming more profitable.
Why is there almost no security company focused on making the "cloud" tamper
resistant? (i.e. monitoring docker containers and looking for
misconfigurations etc even on github) There definitely should be a working
effort in that retrospect.

It is also equally problematic that cloud software will be ambiguous in
design. Cloud software that is built to be fast may use a custom in-house
Just-In-Time code engine for faster database or code execution which may be
harder to really address security wise.

In retrospect there are many security companies that are working towards
securing the appstores, why should they not be working towards
securing/integrating with cloud providers?

There should also be more opensource security anti-viruses besides just
clamav. For people to be secure there should be a newer trend into
opensourcing specific security modules and working towards a functioning
operational level of configuration/management security as well as malware
detection.

------
jamesfisher
> Try to scare implementors away from constant-time software. e.g. “It will be
> too slow.” “It’s too hard to write.”

More generally, try to scare implementors away entirely. "Never roll your own
crypto." Leave it to the experts -- i.e., NSA.

~~~
Nursie
Erm, no.

There are good reasons not to roll your own and none are to do with the NSA.
One is that your own is likely full of flaws that you can't see but an
attacker will spot in seconds.

It's easy to write crypto you can't break yourself.

~~~
tptacek
Not so much "easy" as "inevitable". _Everyone_ can write crypto they can't
break themselves.

