
How to prevent cryptographic pitfalls by design [video] - MrXOR
https://fosdem.org/2019/schedule/event/crypto_pitfalls/
======
beefhash
(I apologize if I'll be glossing over something; I've just read the slides and
haven't gotten around to the presentation yet. These issues might actually be
addressed in the talk.)

Some of the problems that invariably crops up with libraries that hide
implementation details:

a. If the algorithms ever need swapping, you might not even find out because
your code compiles cleanly (assuming you don't obsessively read changelogs for
libraries); only when you go live after the update you see that suddenly all
data is garbled and spend a few hours debugging in your own code. How do you
replace what's inside something like _crypto_box_ while also breaking existing
implementations so that they don't even build?

b. Interoperability across programming languages becomes difficult.
AES-256-CTR with HMAC-SHA256 authentication is something you can scramble to
get algorithms together because you know them. But _crypto_box_ is just
opaque; you'll be stuck reading source code and shoddily porting it to
$language_that_you_must_use because policy or technical requirements or
whatever dictate you must not use native extensions to bind to your library of
choice. If your library of choice is also not written in C (though libsodium,
which is what the presented library wraps, _is_ ), but rather in Java or some
other even higher level language, you'll be completely locked in a monoculture
and dependent on that particular library.

They mean well, but the interoperability problem seems to a very unsolved
problem. The modern non-FIPS world appears to slowly be gravitating towards
de-facto standardizing libsodium, though.

~~~
tptacek
Problem (a) is pretty silly. If you use a library with a vulnerability in it,
you need to be prepared to upgrade the library. How many people using (for
instance) Markdown libraries understand how their library handles memory
management or recursion? Meanwhile, the alternative in cryptography is hand-
hacked direct-to-primitives coding that is likely to create _more_ bugs.
Further, the primitives that are most likely to "need swapping" aren't
algorithms (AES and SHA2 may never fall, just like 3DES, but for its block
size, still hasn't) but constructions, which are hidden in hand-rolled crypto
code.

If you "scramble to get algorithms together because you know them" and use
AES-256-CTR with HMAC-SHA256, in my experience auditing crypto code, you're
very likely to have scrambled together at leave two game-over crypto flaws
that libraries like Tink and libsodium avoid for you.

~~~
throwawaymath
While I agree with your second paragraph, I don't think you need it to justify
the position that

    
    
        crypto.secret_box.encrypt
    

is almost always better to use than a combination of

    
    
        crypto.primitives.aes.ctr
    

and

    
    
        crypto.primitives.hmac.sha256
    

Aside from the obvious argument that rolling your own cryptography is
dangerous, at a more abstract level you just generally don't want to work with
raw primitives in _most_ types of software. Specialization isn't just the
lifeblood of the economy, it's also the way software productivity works. If
your core competency isn't _X_ , why should you be re-implementing _X_ using
its raw primitives? You should _generally_ be importing known-good library
implementations if possible. Even in adversarial scenarios (like cryptography)
this principle remains the same.

Given that I don't really understand the parent commenter's point. You touched
on this a little with your example of a Markdown library - as software
engineers we use things which are substantially black boxes all the time. It
seems strange to me that you'd want to do surgery on the raw primitives of a
library instead of updating it to suit your needs. In this case, that means
just use a reputable crypto library and update it when there's a reported
security vulnerability.

You don't even need to buy into, "Don't roll your own crypto" to lean into
this.

~~~
tptacek
I took the original argument to be "if you use secret_box, you don't even know
that you're using Salsa20, so if a cryptanalysis of Salsa20 is published, you
might not realize and know to fix that problem".

Which is, I think, a silly argument; if someone finds a stack overflow in a
Markdown library, I still need the maintainers of that library to tell me
about it --- nobody is going to tell me about it directly. I have _more_
information to act on in the secret_box scenario, not less.

But I was a little confused by the argument too, so maybe I'm not making that
much sense either.

------
edwardr
Helping developers avoid the pitfalls of cryptography is the main problem we
at Tozny ([http://tozny.com](http://tozny.com)) are trying to solve.

We found that there is so much mis-information available online it's too easy
to shoot yourself in the foot with cryptography so we're trying to make tools
that make strong crypto easy to implement.

------
qrbLPHiKpiux
Cryptography is so very easy to get wrong. This is the kind of thing that
should be outsourced to someone who only does this and is known to do it well
and with known and trusted algorithms.

~~~
DennisP
Designing cryptographic libraries should definitely be left to cryptographers.
However, the information here also seems pretty useful for the programmers
using those libraries.

------
ape4
Yeah most programmers should not code "AES" or other algo. The should be an
option to use the current best.

~~~
DennisP
This is not about coding AES, it's about designing APIs for cryptographic
libraries. If you're a programmer using those APIs, it would be helpful to
know whether they're well-designed, and what pitfalls might be there if
they're not.

~~~
CiPHPerCoder
I often quote Avi Douglen here:

"Security at the expense of usability, comes at the expense of security."

Misuse-resistant cryptography API design is a particular hobby horse of mine.
(My other hobby horse is software update security.)

A lot of the arguments in favor of cipher agility (a.k.a. runtime negotiation
and risk of downgrade attacks) come from well-intended people who haven't
internalized the past few decades of real world cryptographic failures.

I liken it to building a brick wall that's expected to hold up a roof.

Would you rather have a wall made by carefully placing bricks and mortar in
place _once_ , and if need be, rebuild the brick wall later with better
materials?

Or would a lattice of mortar that lets you hot-swap bricks as needed be a
preferable design?

The first one is _versioned protocols_. The latter is what keeps people typing
AES into their code.

