BUUUUUT I can't help reading these and being reminded of Vernor Vinge's "Net of a Million Lies", where people looking for shortcuts end up getting traps. We know that state actors have haunted academic and industry efforts to disseminate info and implementations of cryptography, inserting weaknesses -- resulting confusion is part of why we need guides like this.
How do we know when we can trust a "new media" guide like this one? Can non-practitioners adopt tests that inexpensively verify validity of suggestions like these? Is HN (now with "fight me" threads!) state of the art social proof, or are there other ways to incentivize expert review (without exposing those same experts to centralized influence)?
For clarity, I'm explicitly NOT suggesting this guide is a trap -- I sure has heck wouldn't know, but I don't think so and will be using it :) Just getting meta.
No-one is trustworthy enough to outsource the whole industry's security to - not tptacek, not djb, not AWS, and certainly not me. I think the key is to take not just the recipe but also the rationale. Someone who tells you "Don’t use RSA." might as well be working for the NSA. Someone who tells you "RSA has too many knobs. In modern curve systems, like Curve25519, everything is pre-set for security." is at least making a coherent argument that others can criticize - they might still be wrong, but the fact that they're being substantive is a positive step.
Even the dumbest of us know tptacek is not infallible, though I do hope cperciva and tptacek revisit this thread.
I did bring them up in the threads they occurred in. Not wanting to reopen those old discussions is precisely why I didn't talk about specific examples or give links.
Disclaimer: I'm a co-editor of the new version of the document and also a principal at Latacora and therefore clearly an NSA stooge ;-)
All could be amplified.
I've loved the CryptoPals series, even just reading the challenges for the more advanced parts while I poke at the easier stuff. Please keep them up, and hopefully I'll get all the way through "Shackling the Masses with Drastic Rap Tactics" someday!
So we're not just trusting DJB here. We're trusting a sizeable community that reviewed his work.
happy to answer any questions.
I'm working on some open source hardware, and I'm considering embedding the SSL keys into a cheap hardware crypto element[1]. The element I'm considering [2] only offers ECDH and ECDSA with the NIST P256 curve.However, this article says "Don’t do ECDH with the NIST curves" and "really, especially avoid conventional DSA and ECDSA".
How bad is it really? I mean, the article's pretty unequivocal, it sounds like using that crypto element isn't a very good idea?
[1] Motivation: Users can completely reprogram application processor without wiping (or being able to extract) the private key. [2] https://www.microchip.com/wwwproducts/en/ATECC508A
Really bad.
Invalid curve attacks will leak your secret key, which most old implementations (i.e. the ones likely to end up in your hardware) don't protect against.
If you reuse an ECDSA nonce, you will leak your secret key.
If you have even the smallest timing leak, guess what.
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-7056
https://web-in-security.blogspot.com/2015/09/practical-inval...
Essentially, a bunch of ECC implementations didn't do proper bounds checking and leaked data. ECC still offers a lot of benefits in terms of key size, performance, and security, however, so do your research carefully.
If you're doing ECDSA or ECDH over P256, it might be fine. It might also be a complete disaster. So, we don't recommend it -- and if you must, you should have someone audit it for you, because you're not in the safe zone anymore.
(Examples of disastrous failures: P256 off-curve attacks, unsafe k choices for ECDSA.)
What's bad about cipher cascades?
(No, I don't current encourage people to use them and I tell people that there's some expert sentiment discouraging them; I want to remember the basis of that sentiment.)
Cascading ciphers does nothing to address the dangerous part of encrypting (order of operations for authenticating, authenticating all the security-sensitive components of the message, validating authenticators safely, randomizing encryption, safely handling truncation of authentication tags, providing adequate headroom for nonces, &c &c). In fact, since the best modern authenticated encryption constructions tend to be built up from a single cipher core (usually AES), cascades make encrypting safely harder.
You could "cascade" authenticated constructions, but different constructions have different failure modes. The poly MAC constructions fail and cough up authentication keys. Some gracefully handle truncation and some don't. Some constructions fail somewhat resiliently if nonces get repeated; some explode; some purport not to seriously fail at all. Some of them can reliably be implemented in software on any platform, but the binary field stuff really wants hardware extended carryless multiplication or you get new side channels. These things aren't designed to snap together in cascades and smushing them together doesn't make a lot of design sense.
It's hard to get this stuff right even when you're making the conventional, boring choices. Cascades involve a lot of "not boring" stuff, and the payoff for that not-boringness is arguably homeopathic.
Beyond that: developers aren't normally tasked with building systems out of cryptographic primitives. Those that do are typically (hopefully!) experienced enough to pick a solid primitive.
Those who need to look-up which primitive to use need to know that the security of the final system is primarily going to pass or fail on the _composition_ of those primitives rather than the particular choices.
What would be really cool would be a document that takes common use cases and describes how best to build in the cryptographic aspects of the security. Edit: e.g. a good list of OpenSSL ciphersuites and SSL_CTX_config() blah calls for server auth and mutual auth is probably the biggest bang for buck you can get.
I don't want to come across as critical of the effort or correctness --- but I do I think people really need to hear the danger klaxon when they're doing more than just editing a TLS configuration file. Composition of primitives is really hard.
FWIW I'm more hopeful that I can make mTLS work immanently as part of the environment than everyone getting it right in their app. Less httpd more caddy, if that makes sense :)
Maybe an quick example off the top of my head would be: you know you need to authenticate and perhaps additionally 'encrypt' something --- for say a software update, fancy over-Bluetooth authentication scheme etc.
You need to pick: symmetric or asymmetric schemes? Auth then encrypt? What does replay of an old signature or MAC mean for your system? Key usage limitations? Key re-use? Quite a few ways you can err where the choice of e.g Ed25519 over P-256 ECDSA pales in comparison.
Or in other words: most people are trying to build a secure system, and where security is only achieved by the combination of the protocols, primitives used.
W.r.t TLS, yeah, bake in default configs as part of an environment where you can, although there'll always be plenty of people developing directly against the software API, and compatibility issues will typically play a part.
General reco from your list: the answer is always symmetric unless you literally can not accomplish the same thing any other way. (And you probably can.)
If I remember correctly, hashes and symmetric crypto are generally safe, and so those recommendations shouldn’t change.
That’s a very, very big “only” :).
In any case, there are several compelling computational problems which are (as of current research) post-quantum resistant. They’re based on lattices, error correcting codes, hashes, multivariate polynomials and supersingular elliptic curve isogenies (the latter one being the hot new thing).
Each of those problems has at least a few (but generally many) viable contenders for actual cryptography. Hashes give us very nice signatures, from old-school Winternitz one time signature to merkle trees to current frontrunners like SPHINCS (and its variants). Unfortunately hash-based cryptography can only be used for signatures so far, but they really excel at that.
The ring-LWE problem (and more generally, module-LWE) in lattice cryptography is pretty versatile: we can get fast encryption, signature and encapsulation schemes. The tradeoff is that key sizes run larger. But there is a lot of research into provable security in average-case and worst-case lattice assumptions. The NTRU problem is the other large “school” of lattice cryptography, which mostly has the same problem: very fast, but with larger key sizes.
Error correcting codes give us fewer computational problems to work with than lattices (essentially general decoding and syndrome decoding), but they are extremely well-studied. McEliece remains secure (for binary Goppa codes), which is incredible because it was published only two years after the notion of Diffie-Hellman PKE. Unfortunately most types of error correcting codes are not suitable for cryptography because they have excessive structure. We’ve been mostly stuck with binary Goppa codes for 40 years, though there is exciting work on quasi-cyclic and quasi-dyadic codes in the NIST PQ CFP. Otherwise, similar story as lattices: relatively fast, but very large key sizes.
Isogenies are extremely new and only have a few credible cryptosystems based on them. The most prominent researchers leading this domain are Jao, Longa, de Feo, Plut and Galbraith. The two contenders are SIDH and the NIST proposal succeeding it, SIKE. These have the opposite advantage to lattices and codes, because their key sizes are incredibly small (the smallest among all post-quantum cryptosystems), but their key exchange time is commensurately slower. The additional benefit is that they use much of the same mathematics as traditional elliptic curves, which means you could design hybrid ECDH-like and SIDH-like schemes with a relatively small library.
There are some wonkier proposals (such as Joux’s Mersenne prime one), but these are the ones receiving the most research attention. I wouldn’t say it’s a solved problem, but I’m personally confident there will be mature cryptography available when quantum computers can practically break our current state of the art.
If I want to do asymmetric encryption/signatures and am terrified of the security implications of non-memory-safe languages and/or libraries written in them, do I have any good options? (i.e. is there something I could use from a JVM or an OCaml unikernel or the like?)
(I would ask the same thing about website security and transport encryption, but honestly I'm going to stick with ocaml-tls whatever you say)
- I get it. But libcrypto is less likely to have some insane UAF bug than, say, libtiff or whatever. If you're going to use unsafe code, libcrypto and libsodium are pretty great choices. I wrote a Clojure (so JVM) library that binds libsodium FWIW.
- I hear nice things about Rust's ring lib. Still gotta FFI from OCaml or the JVM though.
- A lot of the recommendations on this list are algorithms designed to be safe to implement. For example, it's unlikely that a JVM impl of XSalsa20 + Poly1305 is suddenly unsafe because of the environment you're running in. This is NOT TRUE for things like AES-GCM; firstly a lot of naive AES implementations are insecure, and good luck doing GHASH safely in software.
The rest of this should be fine in a native phone app.
Is this because you think the side channel isn't that important, or that getting the params for argon2 right is complex enough that you're cautious about recommending it more strongly, or is there something else that I'm missing? Apologies if you answered this elsewhere - I had a look and didn't find anything.
If you wanna do Argon2id that's fine too :-)
What is the rationale behind the assumption that this middle ground is better than straight up Argon2i for general purpose password derivation? I've never seen it explained anywhere.
I'm assuming you're familiar with the Argon2 RFC sections on Argon2id? I think it goes into quite a bit of detail between the two.
Assuming timing attacks breaks Argon2d entirely at relatively little cost, the attacker advantage for a 1-pass Argon2id would be twice that of a one-pass Argon2i: about 10. A three pass Argon2i with a third of the memory looks better: about 3. Not that it matters that much, but still.
Or is my threat model of timing attacks (which assumes they could recover whatever they can at little cost) too paranoid?
I recently ran into some HMAC-based crypto that I thought was pretty sketchy based on the "no custom crypto" principle, but I'm wondering if my concerns were overblown. I haven't found any obvious holes in it, but I'm not an expert so I don't know if that means much.
You can shoot yourself in the foot with HMAC but it won't be because of HMAC; for example: if your messages don't contain a nonce or timestamp they might be replayable or something. But that's not an HMAC flaw.
So to answer your question: maybe? You can get in plenty of trouble with HMAC, but it won't be HMAC's fault.
When you're setting up ELB today you're probably getting ELBv2, specifically an ALB (since we're discussing TLS termination here). There are a few things I like a lot about the way you do TLS configuration for an ALB, but notably:
* Instead of giving you the ability to configure literally everything, they have a handful of profiles. Even the worst profile you can pick is still great. There's just no way to misconfigure ALB TLS, and there are LOTS of ways to misconfigure TLS in general.
* It is _super easy_ to get a cert for your ALB with ACM. There's somehow even less to do than if you're setting up Caddy or whatever + LE normally.
Remember: the goal of that document is to make the common case as simple as it can be and ALB does a pretty bang-up job there. If you don't have a good reason to keep that infra in-house, ALB is fine.
I don't think we have any special info about the security of ALB, but I think it's fair to say that if someone had a serious vuln in ALBs that'd be News(TM). And, if someone had a serious vuln in nginx or whatever, AWS would fix its infra faster than everyone will patch their nginxs :)
I can get pretty deep on the TLS/SSL side if you have specifics; I'm also the main author of s2n, our Open Source implementation of TLS, and a participant in the TLS1.3 process.
Monocypher is portable (C99/C++), pretty fast, and has low memory footprint (generated binary between 30kB and 60kB). Problem: it isn't trusted yet. (I'd like to run a bug bounty, but I'm not sure how I should go about it.)
TweetNaCl is portable (C89), has low memory footprint, and is made by trustworthy professional cryptographers. Problem: it is slow.
Libsodium is blazing fast on modern processors, has portable implementations, and is trusted. Problem: it is pretty big, and I hate the auto tools.
Edit: of course, those recommendations only hold if you have a trustworthy RNG.
IOW, Cortex M0 territory.
Small IoT is about this size, so I think many will be interested in some answers... any answers.
Say, for securely transmitting sensor data to an x86 server (or similar) without hardcoding symmetric keys on the devices.
If speed doesn't matter, TweetNaCl is even smaller.
If those aren't enough still, you may want to dive in, learn a ton about crypto (starting with https://www.crypto101.io/), and investigate the sponge construction, whose versatility may allow you to shrink the code even more. Perhaps. I'm in over my head at this point.
Neither TweetNaCl nor 'loup-vaillant's library really addresses the low-footprint concern.
I've deployed TLS in 50 KiB flash and 6 Kb RAM. But I could rely on hardware support for some public key operations and could pick a single ciphersuite, and controlled the server end as well.
The boring answer is that you'll need to identify the set of primitives you need and then find a library that matches. I can't think of any single primitive that would break that budget, so it'll depend on how many you need!
1. How much of your flash budget is eaten up by the application?
2. What performance do you need for different use cases and operations?
Generally, RAM is often the least of your problems. And if you are into Cortex M0 or even M0+ territory, your MCU will quite probably sport an AES-128 core. Even if it is slow you should try and use that.(As for the original question, I don't know BearSSL enough to have an opinion. It does seem however to get even further than Monocypher on the constant time thing. Monocypher needs the platform to provide constant time 64-bit multiplication. Most do, but not all.)
Would you be willing to be personally liable for that data leak?
(Put aside the philosophical question of whether or not it's reasonably for developers to be personally liable for their software failures - I'm interested in how far your confidence in your cryptography goes).
Embedded crypto gets weird fast. General recommendations are a little tricky, but: is that device talking to the internet directly or some kind of IoT hub or whatever?
On smaller systems, things get weird. If you can't afford go/openssl, there aren't a lot of things I'm very confident in. BearSSL near the top of the list. That's still double-digits kilobytes of RAM though, so maybe I just ate all your budget. You might be in one of the cases where a NOISE protocol instance is in fact the right answer; depends a little on what else the box is doing and how frequently.
Sorry, I get that it's not a satisfying answer :-) It's complicated!
I would have told you something differently before NOISE and NaCl, particularly Curve25519. We could have done AESCTRHMACSHA256 a long time ago and be basically a good as XSalsa20-Poly1305, but Curve25519 was a huge leap compared to the DH2048 you were likely to do before.
Noise is potentially very interesting, particularly for the embedded space, but it'll be a while before it's safe to use.
IMO the interesting aspect with the development of Noise will be if it can avoid bloat. From the mailing list I can see that there's solid awareness of that risk (would assume Trevor is aware anyway), but it will be interesting to see how the simplicity of pattern API will handle things like signatures, when they're inevitably added. I see at least one Noise-using project has already made the leap on that front.
You’re right that they’ve gotten less scrutiny, but they also need less scrutiny. (I’m not saying more isn’t better.) TLS carries a lot baggage from phlogiston era crypto and is significantly more complex than a dumb NOISE impl.
Note that I qualified my suggestion to “you need to have someone around for that” and that I also mentioned low cost. Specifically, I imagine you’d instantiate NOISE with some boring primitives, ideally in a memory safe language, and spend some time and money pointing Tamarin at it, for example. If you don’t have that, fine, get a tiny TLS stack. I’m just saying that a priori I can’t tell you I have less faith in random mbedTLS-containing ROM vs NOISE-with-reasonable-implementor. (I appreciate that we’re comparing apples to oranges with a concrete ROM vs an abstract protocol.) I also happily appreciate that we’re in territory where the constraints are too restrictive to make blanket recommendations.
Let me rephrase: would you agree that there are platforms that actually shipped with garbage crypto where it’s plausible that they could’ve made NOISE work but didn’t embed a TLS stack because size/perf?
Comparing between those two options is a question of appetite for risk, your threat model, and the level of competency you have available. On the latter note, _at the moment_, I think the subset of people who are capable of taking advantage of Noise would be largely similar to the same subset you could safely task with designing and implementing a custom AKE+messaging protocol from scratch anyway. I think the level of competency you need available is on the very far end of the spectrum. Edit: and on the risk point, even if the library has been eyeballed less, at least you know with mbedTLS that if a bug drops you'll get a patch pretty quickly. If you goof up your Noise impl you're on your tod.
mbed TLS also doesn't seem to be particularly well vetted and has had a number of compromises due to implementation issues.
Cryptography and libraries/standards are gradually building towards a world in which higher-and-higher level abstractions let inexperienced web/high-level application developers build safe systems. The same isn't really true for the lower-end of the embedded space, and consequently you can't really produce an equivalent set of (reasonable) guidelines like the ones linked.
> you can use STROBE and a sound, modern, authenticated encryption stack entirely out of a single SHA-3-like sponge constructions.
Or I can go grab TweetNaCl. Is there any reason to use something else?
> Speaking of AKEs, there are, like, 30 different password AKEs you could choose from.
Each with it's own specific (often multiple) footguns. I haven't found any good AKE implementation that I trust for embedded devices.
We could do an elaborate embedded post but the answers diverge a lot more because constraints are tighter. If you’re doing embedded you need a security person around.
Also I <3 SPAKE2. More than I ought to.
I trust NaCl and, specifically, DJB-associated implementations thereunto. Lots of people have looked at it. I trust DJB and his cohorts to think about and mitigate footguns as much as practical.
STROBE is right about a year old. Maybe it's awesome, but it almost certainly hasn't been vetted sufficiently.
I seem to recall that most PAKE's relied on one of the nice properties that modular exponentiation has that doesn't work for ECC. IIRC, quite a few of the PAKE's tried to use ECC and fell into the trap and created a breakable PAKE.
The patent situation around PAKE's didn't help. Fortunately, those patents just expired.
> If you’re doing embedded you need a security person around.
Apple couldn't even get it right. They implemented an 3072-bit SRP that takes almost 15-20 seconds on Cortex M0/M3 series processors unless you have an exponentiation accelerator (Cortex-M4).
If Apple can't get it right, what chance do those with far less resource have?
A list like the parent article but tailored to embedded would be quite welcome.
Re: PAKEs: yes, some PAKEs and related protocols are hard to port to ECC. For example, SRP doesn’t port cleanly from FF to an elliptic curve group because it actually needs a field. But I called out SPAKE2 for a reason: porting SPAKE2 to ECC is easy.
RAMBUS got shafted by the DRAM manufacturers, but they pulled a LOT of shady crap of their own and Stanford was in the thick of it.
While I have no belief that Mike Hamburg was ever in the middle of that, I have some concerns about what might or might not be patented once RAMBUS's lawyers get done with it.
Also, deterministic signing nonces have NOTHING to do the DSA/ECDSA vs alternative signatures scheme. The library you recommend just uses its own deterministic signer internally, just as any ECDSA implementation can and should (e.g. bitcoin’s does).
There is more distinguishing Ed25519 from Deterministic ECDSA than deterministic nonce generation.
On the other point, then don’t list deterministic nonces as a comparative advantage since it is not actually distinguishing.
I'll think about a way to articulate that. Obviously, we can't really offer advice on doing state-of-the-art signature schemes in a couple paragraphs, and would not be interested in trying.
On the other point: the 2015 version of the document addressed the point you're making (and recommended deterministic DSA!). I just think it's kind of dumb to design new systems with a DSA dependency in 2018, and so rescinded the recommendation.
But that's not true: for both Curve25519 and in the Ed25519 signature scheme, which were designed with curves for which point validation is supposedly unnecessary and thus not performed, there are for a given curve point other points --- not valid ones, but ones for which the math will work --- that are equivalent.
For the kinds of things most developers use crypto primitives for, and most of the things everyone was using them for in 2009, these distinctions are --- I'll argue --- not that important. If your transport protocol handshake blows up because of cofactors, the problem probably isn't that you didn't check curve points; it's that you designed a bad key exchange.
But since I don't do cryptocurrency work, like, at all, it's easy to forget that the mainstream of what people do with signature schemes is a lot broader than it was before. I'll try to think of a way to word that and get it into the document.
RFC 2014 defines HMAC with different hash functions such as HMAC-MD5 and HMAC-SHA1. All are valid HMACs. There are other versions of HMAC with for example SHA-256, SHA-224, SHA-512/256 etc defined.
Advice/pointers? Here is our setup:
ECDSA sign/verify P-256;
ECDH enc/dec P-256;
PBKDF2 password + salt = extension, using SHA-256, 5000 iterations, 64 ks;
private key encrypted with PBKDF2 extension via AES-CBC
But it isn't like WebCrypto gives you access to much else. So given browser constraints, what are your thoughts?
Thanks!
I shall up it to 100K!
I think the TL;DR is "I'm not sure you can do this safely without having a security person on your team".
(there is also a web version, which of course could always be compromised, but we're encouraging users to download the app so they have full control and don't have to worry about that. But they need to be compatible.)
Telling our users not to use crypto isn't an option. Recommending our users not use a browser is possible, but forcing them not to use a browser isn't an option either.
I'll give it a shot though, some things that come to mind:
* RFC6979 ECDSA or bust
* Have you considered off-curve attacks for that ECDH?
* How do you authenticate your symmetric ctexts?
Then I have two basic questions (for either you and tptacek):
1) Given I just need to hash the contents of a file for content-addressed data (like in git), it seemed like sha2-256 would be sufficient. However, it seemed like on 64-bit machines, sha2-512 is faster, and I can just lop off the first 256 bits. Is that correct? And in what cases would you use sha3-256/sha3-512?
2) Given I need to build an API that authenticates through client tokens, I was thinking of using JWT (json web tokens) with HMAC256, and a payload with a randomly generated token for the at_hash claim, and send it over TLS. Do I need to include a nonce in the payload? If not, it's the same JWT on every client request. If so, how would you recommend generating a nonce?
In the article, under symmetric signatures, you talk about not doing anything complicated with the data you feed into the HMAC. But I'm not sure what the simple construction of this data is. Is it where you say "just concatenate the key and data and hash them and be secure"?
2) Are you entirely convinced you actually need client tokens? In particular, can you get away with a 256-bit random token and store the session in a database?
3) Re: HMAC input malleability: yep, concat and HMAC is fine. Serializing JSON or whatever is also fine. You're usually providing the tag (that's what the output of HMAC is called) verbatim next to the message, so you generally don't care about e.g. canonical serialization.
2) Hrm. I guess maybe? As I understand it, the reason for a client token is to have stateless servers, so the server doesn't need to look up a valid token upon every request--which scales better. In my case, the API endpoint is for something that doesn't (and won't) get a lot of traffic, so I can probably get away with a 256-bit random token over TLS? Since it's over TLS, there probably aren't MITM attacks to sniff the token and replaying it--so it's probably ok? Are there other considerations I'm not aware of?
Generally: don't do encrypted tokens. If you must: don't do JWT for this. Just secretbox a thing and be done with it, or use PASETO[0].
Can you point to a RTFM on why not? I'm sure it's a big list of reasons but where can I read about the biggest one?
A lot of the implementations _aren't even faster_, but the laundry list of security bugs they have caused is very real. Suddenly you get to worry about irrevocable tokens in order to solve scaling problems you don't have.
A good intro is: http://cryto.net/~joepie91/blog/attachments/jwt-flowchart.pn...
Just as a heads-up, SHA-512/256 isn't exactly just SHA-512 with 256 bits chopped off. It also uses a unique IV. This might not be a big difference in practice, but I'd lean toward using SHA-512/256 explicitly, and not SHA-512 truncated to 256 bits.
I mean, happy to answer any questions.
By the way: if you're interested in this, you might also be interested in the set of 9 (count them: 9) new cryptopals challenges we sold off to raise money for rural congressional races on Twitter:
https://twitter.com/search?f=tweets&q=set%208%20from%3Atqbf&...
This is Cryptopals Set 8, before this weekend available only on request and after swearing a solemn oath not to share.