
Nonce misuse resistance 101 - lvh
https://www.lvh.io/posts/nonce-misuse-resistance-101.html
======
sdrapkin
Nonce-exposing high-level crypto APIs are flawed by design. Most developers
believe that they need low-level crypto APIs - in fact they get a kick out of
coding against low-level crypto APIs. This is a dangerous fallacy/hubris. Most
developers, in fact, should never touch low-level crypto APIs, and should only
use high-level crypto APIs (or not touch crypto at all, which would make the
digital world a safer place).

SecurityDriven.Inferno library is nonce-misuse-resistant by design
([http://securitydriven.net/inferno/](http://securitydriven.net/inferno/)).

~~~
KMag
Thanks for the link! I was expecting something not well thought out, but the
front page has a good answer to "Why not NaCl?" ... the short answer is that
Inferno is a bit more conservative with choice of algorithms.

My main criticism would be that it supports AES256-CBC-HMAC. Encrypt-then-MAC
should protect against CBC padding oracles, but CTS mode instead of CBC mode
would be more conservative. I understand using CBC instead of CTR mode if
you're afraid you might possibly have a flaw that reuses nonces (CBC and CTS
modes leak less information than CTR if you have a nonce reuse bug). CTS mode
is a slight tweak on CBC mode that modifies the final two blocks in a way that
makes it immune to padding oracle attacks. Encrypt-then-MAC should also
protect against padding oracle attacks, but CTS mode fits better with the
belt-and-suspenders philosophy of Inferno.

~~~
tptacek
Encrypt-than-MAC _precludes_ padding oracle attacks, and if you're not
checking MACs, you have bigger problems than padding oracles, so I do not
understand what the win would be from CTS --- which is itself little-used, and
something I mostly associate with bad disk cryptography.

~~~
KMag
You're much more qualified than I am, but I was talking about cases where
there are bugs in the MAC layer. For instance, t's possible that the constant-
time comparison code is well tested on a processor with constant time
comparison of a 64-bit register with zero, but ends up being run on some
oddball ultra-low power processor that uses one cycle for each leading zero
byte in the register, or something. Using CBC potentially allows an attacker
to leverage a timing attack against the MAC into a plaintext disclosure via
padding oracle.

Granted, this scenario requires multiple cascading bugs, but that's kind of
the point of Inferno. In general, one is well advised to use the most well-
tested and standard algorithms, but CTS is very close to CBC. Have you
specifically seen any CTS implementation bugs?

------
triplesec
I found this useful, this not being an area of expertise for me
[https://en.wikipedia.org/wiki/Cryptographic_nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce)

------
amluto
> Nonce-exposing high-level crypto APIs are flawed by design.

No, and please don't encourage people to use bad crypto.

If you build an encryption (or authenticated encryption or whatever) function
E(K, M) that deterministically turns a key K and a plaintext message M, you
_will_ leak information. Specifically, if you send the same message twice, an
eavesdropper can tell.

If you use a nonce-misuse resistant function E(K, M, N) where N is a nonce,
then, if the nonces are unique, you don't leak anything but the lengths of the
messages and, if it's maximally nonce-misuse-resistant, then, with repeated
nonces, all you leak is the fact that repeated messages are repeated.

But if your non-misuse-resistant cipher function is streaming, then you
unavoidably leak repeated prefixes when nonces are misused.

The strongest mode out there is AEZ (assuming it's as strong as the authors
claim), and it still lets you specify a nonce as part of the associated data.

~~~
andrewflnr
Nonce- _exposing_ , not nonce- _using_. If I understand correctly, the idea is
to have the api securely generate nonces behind the scenes; that is, E(K,M) is
not deterministic. In a high-level api for people who just need to move data
from Alice to Bob securely, this seems reasonable.

~~~
amluto
I goofed with this comment -- it was supposed to be a reply to a sdrapkin's
comment, not a reply to the article. Not quite sure how I did that.

Inferno, which sdrapkin cited as an example of crypto done right, offers this
API:

public static byte[] Encrypt(byte[] masterKey, ArraySegment<byte> plaintext,
ArraySegment<byte>? salt = null)

The docs suggest:

The "salt" parameter can include Additional Data (AD) or its hash - which will
also be authenticated.

This is, in my opinion, not okay as a high-level easy-to-use primitive, as it
leaks information if you don't properly use the salt.

EDIT: I read the source
([https://github.com/sdrapkin/SecurityDriven.Inferno/blob/mast...](https://github.com/sdrapkin/SecurityDriven.Inferno/blob/master/EtM_CBC.cs#L62)),
and Inferno's primitive is randomized. This avoids the info leak, but it's
likely to be a decent amount slower as a result, and the primitive needs a
good RNG. As a result, it might be vulnerable to failure if the application
uses fork(), it's awkward to implement on some embedded platforms, etc.

The point of nonce-misuse-resistant encryption is to reduce the damage from
nonce reuse, not to give you an excuse to ignore nonces entirely for
encryption of arbitrary data.

~~~
sdrapkin
I've read the source too. You are strangely looking at EtM_CBC, which is not
Inferno's primary mode. Inferno uses EtM_CTR for the "Encrypt" signature you
cite. The raw CBC mode is already nonce-misuse-resistant (reveals common
prefix), and thus is better than raw CTR from NMR perspective. If you want to
critique Inferno's NMR properties, you should target its primary EtM_CTR
primitive, rather than EtM_CBC.

"vulnerable to failure if the application uses fork()" \- I strongly suspect
that your comfort-zone is c/c++/Linux/*nix, and not .NET framework and
Windows. You failure scenario does not apply to Inferno.

If CSRNG is "awkward to implement on some embedded platforms" then it is a
platform problem, not Inferno's. Inferno is designed to take full advantage of
plentiful (ie. high-quality/cheap/fast) cryptographically-strong randomness
available to .NET framework on Windows.

You question Inferno's speed - performance is in the eye of the benchmark
beholder - but I doubt you have run any (ie. this is likely FUD). Based on the
benchmarks I've run, Inferno is very fast.

Inferno does not ignore nonces - it force-randomizes them internally to the
maximum extent (320 bits of entropy). This creates a nonce-misuse-resitant
design which eliminates user-supplied nonces, and does not break even under a
faulty CSRNG producing a lot less entropy than it should.

