Nonce misuse resistance 101
lvh.io
lvh.io
SecurityDriven.Inferno library is nonce-misuse-resistant by design (http://securitydriven.net/inferno/).
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.
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?
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.
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...), 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.
"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.