Cryptography in OpenBSD
Cryptography in OpenBSD: An overview
Theo de Raadt, Niklas Hallqvist, Artur Grabowski, Angelos D. Keromytis, Niels Provos
USENIX June 1999
The motivation for this talk is a paper that was presented at USENIX 16 years ago. As the title implies, Cryptography in OpenBSD: An overview, is a survey of the many places OpenBSD uses cryptography. Good stuff. The only problem is that OpenBSD is now 20 years old. How relevant is a paper that was written only 20% of the way through the project's current history? Mostly relevant, actually, but with quite a few caveats and footnotes. Through the years, various presentations have been made about updates to one area or another, but it can be hard to piece it all together. So I'm here today to collect them all in one place and present a sort of appendix or epilogue.
Before we jump into the paper, though, let's talk about cryptography. As my friend Crypto Cat here says, we need something to keep our secrets safe. Cryptography is the science, and art, that keeps our secrets secret. For many people, this means encryption and ciphers, but cryptographic principles can be applied in a variety of ways and places.
cryptoparty like it's 1999
PGP - 1991
DES (or three)
It's perhaps easy to forget, but the cryptographic landscape was quite different in 1999. A lot has changed since then. Cryptographic software was available, but not always widespread, in part due to US export controls. International users either had to smuggle it out printed on dead trees, or reimplement everything, or settle for the 40 bit limited edition of their favorite software. Many operating systems originated in the US, so it was difficult to integrate cryptography top to bottom because there needed a way to build the export version without it. OpenBSD had the advantage of originating in Canada, without such concerns. The goto public key algorithm of choice, RSA, was encumbered by a patent for commercial use. The primary symmetric algorithm was still DES. You could use blowfish, of course, but it wasn't officially blessed as a standard.
For the rest of this talk, I'm going to follow the same outline as the original paper. First, all the code included to secure network communications, such as SSL and IPsec. Second, the random number generator system and all the things that get randomized. Finally, storage security, keeping data at rest secure.
For network security, there's a few protocols to cover. Some are more or less relevant these days, but in particular the cipher selection available today is quite different.
RSA in base
SHA-2 AES AES-GCM
As mentioned before, RSA was patented and therefore only available by adding a support library after the fact. Fortunately, this situation was resolved some time ago. OpenBSD also supports a number of new standards not available in 1999: SHA-2 and AES. We've also moved to supporting more authenticated ciphers that combine encryption and authentication, notably AES-GCM and chacha20 combined with the poly1305 MAC. RSA itself is somewhat deprecated now in favor of one of several elliptic curves that have been added. Since skipjack support was worth mentioning as supported in 1999, I figure it's worth mentioning that it was removed entirely a few years ago.
"telnet will be converted to use TLS"
OpenBSD continues to ship libssl for TLS support, however SSL v2 and v3 support has been removed, along with some other code as well. I'm not quite sorry to say that TLS enabled telnet never made it into OpenBSD. But ftp did! Kinda. https support was added to the ftp tool. Currently we're focusing our efforts on the LibreSSL project and a libtls that provides a simplified TLS API.
isakmpd (v1) still here
iked (v2) the future
IPsec is complicated. To summarize the state of the art in 1999, "look at all these moving parts we have." Not much has changed since then, but support for the old photuris protocol was removed long ago, and iked supporting IKE v2 has been added. Things are a little easier to configure these days. And as of about three days ago, iked now works with the latest iPhone IPsec. But never fear, there is ongoing work to make the IKEv2 RFCs much more complicated. Although there was talk of making applications request IPsec, this never happened. IPsec remains the responsibility of the sysadmin. Proposed integration with DNSSEC for opportunistic encryption also remains an idea.
version IV then V
OpenBSD used to support Kerberos, using the KTH developed libraries from right here in Stockholm. At some point, these were upgraded to support Kerb V as well, but support has been removed from base. The code was too large and growing larger with every update.
"no free implementation"
There is now
There was very little to say about ssh in 1999. It wasn't part of OpenBSD yet. At the time, the original free versions of ssh had been forgotten, but then an older codebase was found, which led to the creation of OpenSSH. The initial import of ssh into cvs was in September 1999, a few months later. Obviously a lot of work has happened here, which subsumed some of the earlier plans like encrypting telnet. From its early days supporting only protocol version 1, ssh quickly added version 2, followed by an ever expanding cipher selection. Recently, we've started trimming the supported set back in order to encourage people to use more modern, safer ciphers.
Our next major topic is randomness. This includes the kernel side entropy gathering and wrangling, the common arc4random C interface, and the many applications thereof.
multiple /dev entries
pick desired "quality"
-> all the same today
/dev/random follows a similar design today as it always has, but it's been simplified quite a bit. Some of the entropy estimation code has been paired down, the entropy pool itself is hashed with SHA-512 instead of MD5, and most importantly, all the userland device nodes return the same thing. Never ending, never blocking random bits that are the output of a chacha20 stream seeded by the entropy pool. All the old names remain in /dev for compat reasons, but we've dropped the nonsensical distinction between good and bad entropy. For seeding of userland RNGs, a new system call getentropy was added so that programs don't even need to open a file. Random bits are always available at any time.
RC4 -> chacha20
The primary interface to actually getting random numbers remains arc4random. We've been much more aggressive about using it everywhere, however. Even old random() is now backed by arc4random in many cases. The internals have changed as well. Weaknesses in the RC4 cipher meant that it's been replaced by chacha20. Some of the API, such as the stirring and seeding functions, have been stripped out as unnecessary. And the code was refactored to make it easier to port to other operating systems.
non repeating random
TCP ISN RFC 1948
In many cases, we want random IDs but we don't want them to repeat, which truly random numbers would. Randomly incrementing TCP ISNs was found to be insecure, and truly random ISNs were found to cause connection problems when values repeated. We have since moved to a system based on RFC 1948, which provides for a unique, but still monotonic, sequence for each peer. Of course, instead of MD5, we use SHA512 now, just because. For 16-bit IDs, the 1999 paper used a linear congruential generator seeded by arc4random. In userland, this algorithm has been tweaked to make it harder to predict the next number. In the kernel, we use a randomly shuffled array of possible values, which is even better, at the cost of some increased setup overhead and space.
Our next big topic is secure storage.
vi, ed, bdes -> dead
syslog TLS support
Several utilities used to support DES encryption. It was generally pretty bad, and so it's been removed. There are no good tools for general purpose file encryption, at least not in base. The planned support for Core SDI's secure syslog never materialized, but recently TLS support was added to syslogd.
not much changed
There's not much to say about bcrypt. It's held up pretty well I think, and even found success outside OpenBSD. OpenBSD systems are probably outnumbered by Ruby on Rails sites running on Linux, though of course they don't have bcrypt in libc. Why would you want to use bcrypt for a system account? We've increased the default round count slightly, and have added support for auto tuning based on system speed.
CFS -> dead
vnd -> ok
softraid -> yes
A couple of options have existed to support filesystem or disk encryption over the years. CFS is long dead now. vnd supports blowfish encryption, but much better support is now available in softraid. It uses AES-XTS, CPU accelerated if possible, and can encrypt the entire disk including boot partition.
And now to talk about a few things that weren't even on the horizon in 1999.
I would be remiss if I didn't at least mention signify, but it's been covered elsewhere. Anyway, it seems to be working.
keyed hash function
all the hash tables
siphash is a fast, keyed hash function. It was developed to help protect against algorithmic attacks where bad people flood you with requests that land in the same hash bucket. It was imported into OpenBSD a short while ago, and we've since converted many, many poor hash functions to use it. It's a good middle ground between something heavyweight like HMAC-SHA512 and simply xoring a few bytes together. And now a few words about ping. You want ping to include a timestamp in the packets so you know how long a round trip is. But you don't want to leak your host time to the network. Solution: add an arc4random offset to the timestamp. But you also don't want people to reply with fake packets that lie about the timestamp. Solution: include a siphash MAC of the timestamp in the packet too. It's pretty ridiculous really, but why not?
You have reached the end.