1. 27
  1. 19

    I would take this request more seriously if cryptographers* wrote safer C code, or even better, used [a small subset of] C++. As it is, this comes off as a request for the compiler to save them from their highly dangerous coding styles. In C crypto APIs and internals I see a lot of:

    • Functions that declare key and digest parameters as void*. This completely guts the compiler’s ability to type-check, or even to verify the length of the input data.
    • Closely related, a lack of data types. Why isn’t there a struct AES256? Every time I have to declare a char key[32] it’s an opportunity to get the length wrong, and having an AES_256_KEYLEN macro isn’t a big improvement.
    • Returning values as untyped “out” parameters, e.g.void *out_digest. This obscures the API and has the same lack of typing. Why not just return a SHA256 struct?
    • Lack of “non-null” parameter annotations. GCC and Clang have supported these for years, and with the static analyzers and runtime sanitizers they have saved my butt many times. Even better, why not use C++ references, which strictly enforce this at compile time?
    • Overly general functions that support multiple types/algorithms, making it impossible for the machine to verify type mismatches. Stuff like “if you pass kAES256CTR as the algorithm, then the key must point to an AES256 key and the padding must be XX bytes; or if you pass kRot13 as the algorithm…” (I’m looking at you, Apple: your execrable Keychain API takes this to insane degrees, with functions that take 2 parameters that can be interpreted in dozens of ways. Not making this up. Trying to use SecItemCopyMatching is like playing a sadistic escape-room game where you spend hours clicking everything in sight trying not to crash, then throw the computer at the wall.)

    I’m not just whining about this stuff. I wrote a whole C++ wrapper around Monocypher that demonstrates what I think a safer, idiomatic, hard-to-misuse crypto API should be like.

    * Forgive the hyperbole, I can only speak of the authors of the C crypto APIs I’ve looked at, which include NaCl, libSodium, Monocypher, Intel’s CDSA, and Apple’s Security framework.

    1. 3

      What are your thoughts on meeting these folks in the middle? It seems like the whole cryptostack has this stockholm syndrome going on with unsafe languages.

      • A subset of C++ that is checked by some tool for correctness, etc. I don’t know exactly how this would work, but yeah, why not.
      • Use a tool like Coq and emit C/C++
      • Use Rust.
      • Use Rust, but convert it to C. Maybe Rust -> Wasm -> C. Alon Zakai has been exploring using Rust in this way with WasmBoxC
      • Please
      1. 6

        Fiat-Crypto is “Use Coq and emit C”. It is in production: Firefox uses it since Firefox 69 (2019). We should complete verified cryptography stack and encourage everyone to switch from OpenSSL to it.

        1. 3

          Everything that expects “Rust will make everything safe” misses the point: Rust eliminates universal vulnerabilities, but it doesn’t prevent information leakage through timing. Nor does Coq. There are a whole series of issues Rust eliminate, but information leakage based off of timing is not one of them. It may accidentally eliminate a subset of timing issue by flagging them at compile time, but not for anything that’s unbound.

          Safety is a spectrum. Maybe Rust will get a decorator at some point that will require fixed-time loops for any functions used within a certain boundary, but that’s not something that can be done right now.

          1. 8

            Doesn’t C and Rust both have issues when it comes to side channels? How is Rust different in this regard than C? I was addressing /u/snej ’s points.

            I see points like this brought up when it comes to using something better and feels like the bar to replace C is higher than the bar for C itself. That unless something solves all the problems, even the ones that the original system doesn’t even address, that it cannot be used as a replacement. Does this have a name?

            Are you saying that we shouldn’t use Rust or Coq to change the position on the spectrum of crypto software?

            1. 9

              Does this have a name?

              “Letting the perfect be the enemy of the good” is the most general form of the phenomenon of refusing an improvement on the original simply because it doesn’t solve every possible problem with the original

            2. 8

              That’s the difference between safety and privacy/security. Rust claims to be neither private nor secure; that is, I recall no claim that Rust code is inherently secure, or that data used by a Rust program is thereby kept private. Respectfully, that’s a straw-man argument, and I reject the notion that any of these exist on the same spectrum. Rather, Rust’s claim is to make as yet unsafe things safe, and at that it largely succeeds.

              Now, all that being said, I’m sure there are formal methods projects out there that do aim for that.

          2. 2

            It isn’t just cryptographers that would benefit from sane semantics.

            1. 2

              Here is a more direct link for your “not making this up” reference.

            2. 6

              All of the implemented options are already in clang as well, so the same thing applies there. MSVC also has much more boring volatile behaviour, which should probably be added to the list. Clang’s UBSan provides a bunch of extra checks and in fast-fail mode is generally a good idea.

              The desired behaviour for array accesses is very ABI disruptive. Because C doesn’t know the difference between an array and a pointer, this would require representing pointers as a slice type (base, offset, length) or performing some look-aside checks dynamically.

              1. -1

                To be frank, no project that uses the GPL post-GPL2 will ever be the ‘boring’ variant. Not because it can’t, but because you need to convince lawyers that it’s boring.

                And GCC has done little to create a situation where it might be. clang/LLVM breaks the compiler in two, with a frontend and a backend that can evolve independently. Can you even do that with gcc? And I mean, in a practical sense. I know that the frontend and backend of gcc can technically be decoupled, but technically != plausibly.

                1. 9

                  What does a compiler’s choice of license have to do with its approach to undefined behaviour? Maybe just being dense, but I don’t understand what point you’re making here.

                  1. 5

                    Your information is outdated. You can use GCC backend without GCC frontend, and it is an option supported by upstream. Since GCC 5. See https://gcc.gnu.org/wiki/JIT.

                    1. 4

                      Since the compiler’s license has no effect on the license of your code, nor does GPL3 change anything much vs GPL2 (in reality, I understand there is a lot of spin to the contrary), this seems like an axe to grind more than a contribution

                      1. 3

                        We couldn’t use gcc post-GPL3 when I was at Amazon (or recent versions of emacs for that matter). Do GOOG/MSFT/FB treat gcc differently?

                        1. 4

                          Are you saying that Amazon engineers are not allowed to use Emacs as a text editor?

                          1. 1

                            There were many engineers using emacs, but the official line was that you weren’t allowed to install any GPL3/AGPL software on a work machine for any purpose, and that explicitly included recent versions of emacs (and also recent versions of gcc, which meant the build system was stuck with obsolete versions of gcc). I suspect everyone just ignored the emacs restriction, though. I’m sure a lot has changed since I left in 2014 (I bet the build system has moved to clang), and I don’t know the current policy on GPL software.

                            1. 1

                              Okay, that sounds bad. Thanks for the clarification! 👍🏽

                          2. 3

                            At Microsoft, the policy is surprisingly sane: You can use any open source program. The only problems happen when you need to either:

                            • Distribute the code.
                            • Include it in something customers can use.
                            • Incorporate it into a product

                            There are approvals processes for these. There’s no blanket ban on any license (that I’m aware of) but there are automatic approvals for some licenses (e.g. MIT), at least from the lawyers - the security folks might have different opinions if upstream has no coordinated disclosure mechanism or even a mechanism for reporting CVEs.

                            1. 2

                              That sound unsustainable. Do you not already need new builds of GCC to build Linux? Surely if not, then you will eventually. And I can’t see Amazon ditching Linux any time soon

                              1. 2

                                Keep in mind my information is 7 years out of date (I left in 2014, when Amazon was just starting to hire Linux kernel developers).