|
|
Subscribe / Log in / New account

Offload-friendly network encryption in the kernel

By Daroc Alden
July 9, 2024

The PSP security protocol (PSP) is a way to transparently encrypt packets by efficiently offloading encryption and decryption to the network interface cards (NICs) that Google uses for connections inside its data centers. The protocol is similar to IPsec, in that it allows for wrapping arbitrary traffic in a layer of encryption. The difference is that PSP is encapsulated in UDP, and designed from the beginning to reduce the amount of state that NICs have to track in order to send and receive encrypted traffic, allowing for more simultaneous connections. Jakub Kicinski wants to add support for the protocol to the Linux kernel.

The protocol

PSP is a fairly minimal protocol. It completely avoids the topic of how to do a secure key exchange, assuming that the applications on either end of a connection will be able to exchange symmetric-encryption keys somehow. This is not an unreasonable design decision, since IPsec does the same thing. There are several existing protocols for securely exchanging keys, such as Internet Key Exchange or Kerberized Internet Negotiation of Keys. Usually, those protocols are indifferent to the source of the symmetric keys. PSP is a bit different. To support hardware-offload, PSP requires that the NIC itself generate the keys for a PSP connection. The PSP architecture specification goes into detail about how NICs should do that.

The main requirement is that the NIC should be able to rederive the key for a session from a fairly limited amount of information — specifically, from a 32-bit "Security Parameter Index" (SPI) value and a secret key stored on the device. That key is generated by the NIC and used to derive the session-specific encryption key for each connection as needed, using a secure key-derivation function. Therefore, the SPI alone is not enough to decrypt a packet; this allows SPIs to be included in PSP packets, letting the NIC rederive the encryption key for a packet on the fly. In turn, this means that the NIC does not actually need to store an encryption key in order to receive and process a packet, greatly reducing the amount of memory necessary on the device.

Unfortunately, this requirement to rederive keys comes at a price — PSP connections are unidirectional. For real use cases where bidirectional communication is required, the application needs to set up a separate PSP connection for each direction. Since rederiving the key requires access to a device key stored on the NIC, only the receiving NIC can rederive it, so the transmitting device still needs to store the key somewhere. While that could be on the NIC, the PSP specification leaves open the possibility of a hardware implementation that requires the computer to send the encryption key to the NIC alongside any transmitted packets.

To encrypt packets, PSP uses AES-128-GCM or AES-256-GCM. These are both authenticated encryption with associated data (AEAD) schemes — they guarantee that the received data has not been tampered with (authentication) and bundle some encrypted data alongside some associated plain-text data. In PSP's case, this is used to implement an offset that allows the sender to leave the headers of a protocol encapsulated in PSP unencrypted, while still protecting the contents. Supporting only two modes of AES keeps the implementation complexity of PSP low.

PSP also has a packet layout designed to make parsing the packet in hardware more efficient, by providing explicit lengths in the header and using fewer optional headers than IPsec does. In combination with the unique key-derivation scheme, PSP ends up being more hardware-implementation-friendly than other encryption protocols like IPsec or TLS.

While Google is both the originator and largest current user of PSP, the protocol could potentially be useful to other users. Compared to other encrypted protocols, PSP requires a lot less on-device memory, letting it scale to larger numbers of connections. Because the protocol doesn't mandate a key-exchange standard, PSP is probably a good choice for an environment where the user controls both ends of the connection, but still wants to ensure that traffic can be encrypted.

The discussion

Despite how useful Google finds the protocol, kernel developers were dubious about adding yet another encryption protocol to the kernel, which already handles IPsec, WireGuard, TLS, and others. Paul Wouters expressed surprise that Kicinski wanted to add PSP to the kernel, when the IETF had declined to standardize the protocol on the basis that it is too similar to IPsec.

Steffen Klassert shared a draft that the IPsecME working group has been putting together that covers some of the same use cases as PSP. That may not be as helpful as it sounds, however, because there are already hardware devices implementing PSP, Willem de Bruijn pointed out. "It makes sense to work to get to an IETF standard protocol that captures the same benefits. But that is independent from enabling what is already implemented."

That answer didn't satisfy Wouters, who asked: "How many different packet encryption methods should the linux kernel have?" He said that waiting for protocols to be standardized provides interoperability, and chances to make sure a protocol is actually useful for more than one use case. PSP and IPsec can also use a lot of the same NIC hardware, he pointed out.

"I don't disagree on the merits of a standards process, of course. It's just moot at this point wrt PSP", de Bruijn replied. Klassert agreed that existing PSP users need to be supported, but thought that it was still important to work on standardizing a modern encryption protocol that meets everyone's needs. He invited Google to send representatives to the IETF IPsecME working group meeting to discuss the topic. De Bruijn said that the company would.

But some reviewers also had technical objections to Kicinski's patch set. The API he proposed allows user space to set a PSP encryption key on a socket, after which data transmitted through that socket will be encrypted. The problem is how exactly this interacts with retransmissions. PSP is encapsulated in UDP, and has no guarantee that data will arrive intact or in order, leaving that detail up to higher-level protocols. But Kicinski is mainly interested in PSP as a TLS replacement — which of course runs on top of TCP. PSP supports wrapping TCP, but just by encrypting individual packets, not by participating in TCP's retransmission logic.

Together, this creates some edge cases, de Bruijn pointed out. How is the kernel supposed to handle retransmissions of plain-text data after a PSP key has been associated with a socket? "Like TLS offload, the data is annotated 'for encryption' when queued. So data queued earlier or retransmits of such data will never be encrypted", Kicinski explained.

De Bruijn wasn't completely satisfied with that, pointing out that it still leaves edge cases. What happens if one peer upgrades the connection at the same time the other peer decides to drop it? "If (big if) that can happen, then the connection cannot be cleanly closed." In response, Kicinski suggested "only enforcing encryption of data-less segments once we've seen some encrypted data". De Bruijn agreed that might help, but was still worried that the kernel API could still be used in ways that break the correctness of the protocol, and suggested that some more thorough documentation might be appropriate.

In response, Kicinski put together some sequence diagrams showing how a PSP-secured socket is set up and torn down. De Bruijn thought that was a substantial improvement, but remained unconvinced that all of the edge cases had been handled.

Lance Richardson raised some questions about the kernel API as well, noting that there didn't seem to be any real support for rekeying a socket, something that PSP mandates every 24 hours. In a follow-up message, Richardson suggested that it might be as simple as keeping an old key around for a minute or two after rekeying. Kicinski agreed that made sense, and promised to add it to the next version of the patch set.

While there are lots of reasons to use PSP, and the presence of hardware that supports it is a good sign, the lack of a standard and questions around the implementation suggest that it may be some time before support is finalized. Still, in the future we could see yet another encryption protocol come to the kernel. The exact details of how that happens remain to be seen.



to post comments

How did we get here

Posted Jul 9, 2024 15:21 UTC (Tue) by jgg (subscriber, #55211) [Link] (2 responses)

There is some case study here with PSP on the new way the industry seems to be working. PSP is a great technical achievment, very inventive and a smart solution to a particular problem.

However the community engagment side is really troubled. PSP started life as a secret design shared by Google with their partners under a special NDA. The cases I am aware of information was kept tightly compartmentalized at Google's request.

Eventually they published enough details to define what the NIC should do, but this did not include any information the software integration. It was just enough that 3rd parties could reasonably implement NIC HW that Google could consume. Today, all the existing SW implementations today seem to be propritary code inside Google.

Now that supporting HW is fairly widely available, and just enough information is public to figure out how to use it, we are seeing a fragmentation. Different ideas about how to use PSP from a SW perspective are coming up and this series is one of them.

This patch series talks about support in fizz, a TLS library created by Meta, but the code hasn't been published (see the email from Sasha), nor it seems has any IETF draft RFC proposal on how to combine TLS and PSP together been released. Yet we see kernel uAPI being proposed based on this currently propritary design.

It is hard not to look at this and conclude that none of the parties have any serious interest in standardization. Sure there is a token "we will talk to the IETF", but stuff will go into proprtiary software and full deployment without that. Once deployed we've seen that networking protocols rarely get replaced.

It is really distressing to see that innovative new ideas are brought to market and implementation in this way. I'm seeing more and more of this every day, I have a stack of NDA'd specs on my desk and all driven by the giant hyperscale companies.

In my view this is creating some stress in our community as there are many arguments now around when is it appropriate to add support to the kernel, with frankly, some rather inconsistent positions and outcomes.

How did we get here

Posted Jul 9, 2024 19:57 UTC (Tue) by Paf (subscriber, #91811) [Link] (1 responses)

I think you hit on a key point - the hyperscalers are now large enough to justify the creation of entire protocol and HW designs. They've become a large enough piece of the infrastructure that this works for them, so they don't have a lot of incentive to standardize. Frankly for them, what do they get from standardization?

How did we get here

Posted Jul 12, 2024 5:43 UTC (Fri) by LtWorf (subscriber, #124958) [Link]

> Frankly for them, what do they get from standardization?

Perhaps they could get inclusion in the linux kernel, so they don't have to keep patches?

Bad practices all around

Posted Jul 9, 2024 19:17 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link] (10 responses)

Ugh. PSP looks like a terrible pile of bad practices, recapitulates all the issues of IPSec:

- Mixed secure/insecure packets? Check.
- Bad crypto decisions? Check (modern crypto shouldn't need rekeying!).
- No care given for signaling traffic? Check (no authenticated PMTU, fragmentation, etc).

At this point, please just use Wireguard or TLS.

Bad practices all around

Posted Jul 9, 2024 22:58 UTC (Tue) by wahern (subscriber, #37304) [Link] (4 responses)

> Check (modern crypto shouldn't need rekeying!).

Wireguard rekeys and it's quiet young still as protocols go. What are typically considered modern AEAD algorithms (e.g. as used in Wireguard or TLS) are actually a limitation in this regard on account of their parameter sizing.[1] One could in theory do better with older HMAC-based schemes. There are *more* modern AEAD schemes, such as XChaCha20-Poly1305 with extended nonces, but they haven't seen much uptake as of yet. Anyhow, there are other benefits to rekeying, especially functional, that simply can be addressed by better primitives or APIs.

The big lie was that primitives like AES-GCM and Chacha20-Poly1305, or protocols like Noise and Double Ratchet conclusively solved most technical crypto problems. They didn't. Features like cryptographic agility that were decried 10+ years ago as patently stupid have in some cases returned as lauded features as newer, better primitives appear and people rediscover age-old dilemmas upgrading infrastructure.

What's old is new again, albeit slightly improved, fortunately. Cryptographic "best practices" will continue to evolve, sometimes circling back, just as they always have.

[1] Relatedly, the 32-bit SPI in PSP raises suspicion as a premature space optimization still encountered in "modern" crypto.

Bad practices all around

Posted Jul 9, 2024 23:17 UTC (Tue) by Cyberax (✭ supporter ✭, #52523) [Link] (2 responses)

In case of Wireguard rekeying is justifiable because its connections can last for years, and symmetric keys are not persisted. PSP is more like TLS, so there should be no _need_ to do rekeying.

Bad practices all around

Posted Jul 10, 2024 14:14 UTC (Wed) by anmoch (subscriber, #85760) [Link] (1 responses)

Can't HTTP2 connections be useful for days, perhaps longer? Especially if you use them for RPCs, as with (AFAIU, haven't used it) gRPC for example.

Bad practices all around

Posted Jul 10, 2024 19:47 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link]

Yes? I kinda don't understand the point?

The only problem with long-lived connections in TLS/PSP is that AES-GCM is weak against nonce reuse. If you can find two different messages encrypted with the same nonce, then you will be able to forge GCM signatures, although you won't be able to decrypt messages.

This is mostly a theoretic attack. The nonce length is just 96 bits, so if you use random nonces, you start having an appreciable risk of collision after around 2^48 messages transmitted (so at least around after 2^56 bytes, in reality even more). And if you use incremental nonces instead of random ones, you are not at risk at all.

Bad practices all around

Posted Jul 9, 2024 23:33 UTC (Tue) by atnot (subscriber, #124910) [Link]

I think there's an important difference between "cryptographic agility" and the ability to upgrade a protocol? Cryptographic agility as an idea is, to me, very much still dead. And it keeps getting deader with more robust primitives and complex cryptosystems where you absolutely could not just swap out a primitive without a complete reevaluation of the whole system.

However that is different from not giving yourself any way of upgrading a protocol in the future, which is always a bad idea regardless of cryptography. You can still just have a version 2 which swaps out the crypto for another construction you've decided you like better. You don't need to make every client create a tier list of their favorite hash functions or play spot-the-difference in a list of block cipher modes for that.

Bad practices all around

Posted Jul 10, 2024 1:16 UTC (Wed) by mirabilos (subscriber, #84359) [Link] (4 responses)

Why not OpenVPN? It works and more widely than Wireguard, too.

Bad practices all around

Posted Jul 10, 2024 2:02 UTC (Wed) by atnot (subscriber, #124910) [Link] (3 responses)

As someone who operated it at scale for a while, there is so much wrong with it, here's the gist:
- vast amounts of complexity, mostly from bad design decisions that they really don't have the resources to fix
- no data plane/control plane separation. Both in the code and the network. One channel is used for everything. A lot of downstream issues ultimately stem from this.
- single threaded
- lots of obsolete and broken modes and features. Because there's no good layer separation nor plugin system, these end up infecting the whole program with weird code paths that were necessary to fulfill some companies weird requirement at some point and can never be removed because nobody knows who even uses any of it (we contributed at least two of those to the list, oops)
- not really a protocol as much as a client and a server that happen to be bug compatible with each other. There is little to no information about how anything is actually supposed to work, at any level.
- the configurations suck, auth sucks, there is no way to reconnect without reauthenticating, and lots of other annoying papercuts.
- openvpn3 solves some of this except it doesn't and you can't use it

To the stuff that actually matters for this use case:
- It is completely infeasible to implement a protocol as weird and complex as openvpn in hardware
- it is barely feasible to implement it in the kernel. There is openvpn-dco but it has tons of asterisks and is extremely unlikely to ever be accepted upstream.
- it is not particularly fast, or built to be able to be made fast
- it's also just way overkill. The niceties of openvpn are mostly in the management features. If you're just going to be using a custom system to ship around all of the keys anyway, you may as well just use wireguard which doesn't have any of these disadvantages.

More OpenVPN drawbacks

Posted Jul 10, 2024 12:13 UTC (Wed) by mbunkus (subscriber, #87248) [Link] (2 responses)

With two decades of professional experience using it in a lot of settings, I fully agree with everything atnot has written. If you're not convinced yet, here a couple more fun facts:

- with a lot of setups establishing the connections takes quite a lot of time, as in upwards of ten seconds, often enough more like 20 (with Wireguard connections are instant as there simply is no handshake/establishing of a connection necessary before sending data)

- most companies chose to run OpenVPN in TCP mode, severely tanking the performance of any kind of data transfer over it (tunneling TCP over TCP is really bad due to how scaling works in TCP); the argument is that it's easier to get through middleboxes. This gets much, much worse if you're running over higher latency links. Not that OpenVPN-via-UDP is the fastest thing out there: in pretty much all speed comparisons I've seen OpenVPN always comes in after Wireguard & IPSEC.

- if you want to change several of the protocol options on the server side, you must re-deploy all client configs (think of using different compression methods, changing the MTU etc. etc.). Same goes when you have to re-create the certificate CA you're using, e.g. due to having chosen poorly earlier in your life when you created your CA with SHA-1 digest. This cannot be done incrementally. It's a "everyone must upgrade at once" situation.

- OpenVPN relies on the OS's SSL library (most often: OpenSSL) for encryption. In practice this means that upgrading your machine's OS might suddenly make your OpenVPN tunnel not work anymore, as new OpenSSL versions often disable/deprecate older digests or encryption methods. Sometimes you can insert some arcane options into your OpenVPN options to make your OpenSSL still accept them ("tls-cipher "DEFAULT:@SECLEVEL=0""). If not, see above: changing protocol options on the server side, re-create & re-distribute all client configs.

- OpenVPN sometimes changes their configuration format in incompatible ways. As the provider of config files for your clients/customers/co-workers, you suddenly have to offer several different ones that work on certain ranges of OpenVPN clients.

The whole _management_ side of OpenVPN is what really sucks for me.

More OpenVPN drawbacks

Posted Jul 10, 2024 16:02 UTC (Wed) by mirabilos (subscriber, #84359) [Link]

Thanks you two for the responses. My use case is mostly me connecting a couple of dynamic-IP boxen to one of my servers and having a way to access them from my laptop when travelling as well.

I used to have a full setup of this and want to put it up again, so I know it works and how it works and how I have to configure it, and it’s compatible enough.

As far as I can tell, for this use case, it’s just possible annoyances, not something that absolutely speaks against it. Speed is also not much of an issue, given German internet.

But I can see how that would be more than annoying at company scale, yes.

More OpenVPN drawbacks

Posted Jul 11, 2024 9:50 UTC (Thu) by hkario (subscriber, #94864) [Link]

> Sometimes you can insert some arcane options into your OpenVPN options to make your OpenSSL still accept them ("tls-cipher "DEFAULT:@SECLEVEL=0""). If not, see above: changing protocol options on the server side, re-create & re-distribute all client configs.

that's just something that comes with the territory, if you're on market for something like two decades, the cryptographic best practice will change under you. If you want to continue to use configurations from 20 years ago that means you have to tell OpenSSL that you want to use long obsolete crypto.

Same with ipsec, just because you can use it with IKEv1, doesn't mean you should.

Once wireguard is on the market for 20 years, it will have arcane configuration options too, or it won't be used any more.

In my experience, I did try setting up IPsec tunnels in two completely different environments (though both with static public IP to a dynamic IP behind a not-forwarded NAT, all with resolvable DNS names though), and the IPsec tunnels were super unreliable, reconnecting worked once every 10 times or so. If the connection went down it basically stayed down. After switching both to OpenVPN they just were rock solid.

Dual homed servers?

Posted Jul 14, 2024 3:16 UTC (Sun) by faramir (subscriber, #2327) [Link]

If I understand this correctly, packets have to always go through the same NIC in order to be encrypted/decrypted. Having redundant NICs in a host is going to give you flaky connections. So only useful if you treat your servers like cattle rather than pets even at the hardware level.


Copyright © 2024, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds