As you might know, [I left Google in spring]() to try and make the concept of a [professional Open Source maintainer]() a thing. I’m staying on as a maintainer of the Go cryptography standard library, and I am going to seek funding from companies that rely on it, want to ensure its security and reliability, and would like to get a direct line to the maintainers of their critical business infrastructure. (If this sounds like you, reply to this email!)
In the meantime, though, the [Go development cycle]() progresses inexorably, with the Go 1.20 feature freeze coming at the beginning of November. Once the main Go tree freezes, I plan to work on `x/crypto/ssh` and `age`, but in the meantime I have a few things I am excited about for Go 1.20.
## crypto/ecdh
The most visible change will be the landing the new [`crypto/ecdh` package]() I [proposed]() and [implemented]() earlier this year. The package provides a safe, `[]byte`-based, easy to use API for Elliptic Curve Diffie-Hellman over Curve25519 and NIST curves (P-256 and company, but no P-224 if we can get away with it).
`crypto/ecdh` was made possible by a long-running refactor of the elliptic curve implementations in the standard library. Between Go 1.17 and Go 1.19, most critical code was moved to safer low-level APIs under `crypto/internal/nistec` and `crypto/internal/edwards25519`, large pieces were replaced with code generated from [fiat-crypto]()’s formally verified models, making every curve constant time, most group logic was replaced with modern complete formulas, and even [the assembly was massaged to implement the same functions on all architectures]() and fit the nistec API. [Some assembly is gone](), actually!
([Here are all the changes.]() [A couple nifty uses of generics in there if you’re curious.]())
The goal of the package is to replace the major use case for the **now-deprecated** `crypto/elliptic` API, which has a hardcoded dependency on the variable-time, large, and complex `math/big` package. `crypto/elliptic` is now no more than a compatibility wrapper. Any more advanced uses of `crypto/elliptic` can switch to [filippo.io/nistec]() which is an exported version of `crypto/internal/nistec`, or [filippo.io/edwards25519]() which is an exported version of `crypto/internal/edwards25519`.
What’s left to do in Go 1.20 then?
First, actually landing the new package, [which is already submitted]()! Then, adding and reviewing new tests (including [Wycheproof integration]() by Roland), which actually revealed there are [fewer (!!) edge cases than I had originally documented](). Finally, reviewing [the BoringCrypto integration by Russ]().
## math/big out of the security perimeter
There is an even broader goal behind this work: moving `math/big` out of the security perimeter entirely, meaning making it unreachable from attacker-exposed cryptographic APIs and protocols.
`math/big` is a general-purpose big integer library, it’s not constant time, and it’s full of complex code that while unnecessary for cryptography has **repeatedly led to security vulnerabilities in crypto packages**. While it was a convenient way to bootstrap the Go crypto standard library, `math/big` does not belong in crypto code in 2022.
`crypto/ecdh` lets us deprecate `crypto/elliptic`, which lets us bypass `math/big` in `crypto/tls`’s ECDHE implementation.
The next step is modifying `crypto/ecdsa` to use `crypto/internal/nistec` for the group operations on known curves, deprecate the use of custom curves, and replace the scalar field operations with… something. That something might be fiat-crypto field implementations for each scalar field (P-256’s, P-384’s, and P-521’s) with the [wide reduction trick we talked about in Cryptography Dispatches](), or using a minimal bigint implementation shared with `crypto/rsa`.
Speaking of, `crypto/rsa` unavoidably needs a lightweight bigint implementation to replace its dependency on `math/big`. The good news is that we can make that one constant-time, simple, and tightly scoped for its purposes, which should make it much easier to maintain and keep secure. [Lucas contributed one]() that needs review, and Thomas Pornin offered a Go port of [BearSSL’s one](). This will be a significant amount of assessment, review, and testing work, but it’s the last real hurdle.
Finally, we need to worry about the places where `big.Int` is exposed in public APIs, mainly `crypto/rsa` and `crypto/ecdsa` key types. An idea is making the `(*Int).SetBytes`/`(*Int).FillBytes` round-trip constant-time so it can be used as just an annoying way to carry around the `[]byte` encoding of the key values. The problems with that are how to handle (or check in constant time) any manual modification to the `big.Int`, and how to store zero-padded values (which we can’t unpad in constant time) without breaking the normalization invariant of `big.nat`. I welcome suggestions!
If we do go the route of keeping a select subset of `math/big` exposed, we’ll want to lock it in to ensure we can keep it constant time and well reviewed. For that I have a [WIP test that does static analysis to ensure only expected functions are reachable from crypto packages]().
## More elliptic curves
Aside from the `math/big`-related efforts, there are a couple other Go 1.20 tasks that have to do with elliptic curves.
First, [landing a rewrite of the edwards25519 scalar field]() that replaces the last bits of unreadable ref10 code with fiat-crypto generated code. You can read more on [a previous Cryptography Dispatches issue](), and there’s an overview of the overall edwards25519 rewrite in [the CL that landed it after years out-of-tree]().
Second, finally [landing support for Ed25519ph (the pre-hashed variant of Ed25519)]() in `crypto/ed25519`.
## crypto/tls
Finally, as a stretch goal in case elliptic curve work leaves some space for other things, I collected a couple batches of `crypto/tls` work. (I find it more efficient to work in topic-scoped batches, so I can load context on a protocol and codebase once and use it to land multiple changes.)
One batch revolves around session resumption: exposing a way to provide external PSKs in TLS 1.3 (which are the underlying mechanism of session tickets in TLS 1.3), maybe implementing PSK modes, implementing Session IDs, making sessions serializable/exportable.
Here’s a list of related issues. (The one about forward secrecy by default was already mostly addressed by [work we landed somewhat quietly with Katie in Go 1.15](), which I’m hoping to write about for the Go blog, as it sets Go significantly apart from any other TLS stack I know about.)
* [crypto/tls: TLS session resumption re-verifies the client’s certificate chain]()
* [crypto/tls: make ClientSessionState serializable]()
* [proposal: crypto/tls: implement Session IDs resumption]()
* [proposal: crypto/tls: SessionTicketWrapper and Forward Secrecy by default]()
* [crypto/tls: add PSK support]()
* [proposal: crypto/tls: expose a session identifier]()
The second batch is a miscellaneous list of crypto/tls work. If you have anything else TLS-related you care about, now is a good time to ping me on it.
* [crypto/tls: customisable max TLS record size]()
* [crypto/tls: improve default performance of SupportsCertificate]()
* [crypto/tls: add VersionName function to return a string version of the TLS Version]()
* [crypto/tls: expose all presented certs in error type on handshake failure]()
* [crypto/tls: support ECDHE key exchanges when ec_point_formats is missing in ClientHello extension]()
* [crypto/tls: make maxHandshake larger or configurable]()
* [crypto/tls: run BoringSSL test suite (BoGo)]()
* [proposal: crypto/tls: implement RFC7627]()
## The picture
DEF CON was a blast (we won a Black Badge with the Scavenger Hunt!) and systematically eating outdoors and wearing a P100 respirator spared me from COVID. Las Vegas is hell but pretty.
![A night-time picture of the Las Vegas skyline taken from a high floor. In the foreground a large road, mostly empty, and two blocks of low buildings and empty space with a couple billboards with bright lights. Mid-frame, a string of high-rise casinos covered in sparkly lights. In the background, pitch black sky.](https://words.filippo.io/content/images/2022/09/Newsletter—1–1–1.jpeg)
If you want to stay up to date with my Open Source work, consider [following me on Twitter]() or [subscribing to this newsletter]() if you haven’t already! **If your company depends on Go and its cryptography libraries**, or any other of my Open Source projects, consider sponsoring my maintenance work. Reply to this email, introduce me to the right people, and I’ll work with your accounting department to make it happen!Read More
References
Back to Main