Quantcast
Channel: Dhole Moments
Viewing all articles
Browse latest Browse all 54

Introducing Alacrity to Federated Cryptography

$
0
0

There are two mental models for designing a cryptosystem that offers end-to-end encryption to all of its users.

The first is the Signal model.

Predicated on Moxie’s notion that the ecosystem is moving, Signal (and similar apps) maintain some modicum of centralized control over the infrastructure and deployment of their app. While there are obvious downsides to this approach, it allows them to quickly roll out ecosystem-wide changes to their encryption protocols without having to deal with third-party clients falling behind.

The other is the federated model, which is embraced by Matrix, XMPP with OMEMO, and other encrypted chat apps and protocols.

This model can be attractive to a lot of people whose primary concern is data sovereignty rather than cryptographic protections. (Most security experts care about both aspects, but we differ in how they rank the two priorities relative to each other.)

As I examined in my criticisms of Matrix and XMPP+OMEMO, they kind of prove Moxie’s point about the ecosystem:

  • Two years after the Matrix team deprecated their C implementation of Olm in favor of a Rust library, virtually all of the clients that actually switched (as of the time of my blog post disclosing vulnerabilities in their C library) were either Element, or forks of Element. The rest were still wrapping libolm.
  • Most OMEMO libraries are still stuck on version 0.3.0 of the specification, and cannot communicate with XMPP+OMEMO implementations that are on newer versions of the specification.

And this is personally a vexing observation, for two reasons:

  1. I don’t like that Moxie’s opinion is evidently more correct when you look at the consequences of each model.
  2. I’m planning to develop end-to-end encryption for direct messages on the Fediverse, and don’t want to repeat the mistakes of Matrix and OMEMO.

    (Aside from them mistakenly claiming to be Signal competitors, which I am not doing with my E2EE proposal or any implementations thereof.)

Fortunately, I have a solution to both annoyances that I intend to implement in my end-to-end encryption proposal.

Thus, I’d like to introduce Cryptographic Alacrity to the discussion.

Note: The term “crypto agility” was already coined by people who never learned from the alg=none vulnerability of JSON Web Tokens and think it’s A-okay to negotiate cryptographic primitives at run-time based on attacker-controllable inputs.

Because they got their foolish stink all over that term, I discarded it in favor of coining a new one. I apologize for the marginal increase in cognitive load this decision may cause in the future.

Cryptographic Alacrity

For readers who aren’t already familiar with the word “alacrity” from playing Dungeons & Dragons once upon a time, the Merriam-Webster dictionary defines Alacrity as:

promptness in response cheerful readiness

Alacrity Definition & Meaning – Merriam Webster

When I describe a cryptography protocol as having “cryptographic alacrity”, I mean there is a built-in mechanism to enforce protocol upgrades in a timely manner, and stragglers (read: non-compliant implementations) will lose the ability to communicate with up-to-date software.

Alacrity must be incorporated into a protocol at its design phase, specified clearly, and then enforced by the community through its protocol library implementations.

The primary difference between Alacrity and Agility is that Alacrity is implemented through protocol versions and a cryptographic mechanism for enforcing implementation freshness across the ecosystem, whereas Agility is about being able to hot-swap cryptographic primitives in response to novel cryptanalysis.

This probably still sounds a bit abstract to some of you.

To best explain what I mean, let’s look at a concrete example. Namely, how I plan on introducing Alacrity to my Fediverse E2EE design, and then enforcing it henceforth.

Alacrity in E2EE for the Fediverse

One level higher in the protocol than bulk message and/or media attachment encryption will be a Key Derivation Function. (Probably HKDF, probably as part of a Double Ratchet protocol or similar. I haven’t specified that layer just yet.)

Each invocation of HKDF will have a hard-coded 256-bit salt particular to the protocol version that is currently being used.

(What most people would think to pass as the salt in HKDF will instead be appended to the info parameter.)

The protocol version will additionally be used in a lot of other places (i.e., domain separation constants), but those are going to be predictable string values.

The salt will not be predictable until the new version is specified. I will likely tie it to the SHA256 hash of a Merkle root of a Federated Public Key Directory instance and the nickname for each protocol version.

Each library will have a small window (probably no more than 3 versions at any time) of acceptable protocol versions.

A new version will be specified, with a brand new KDF salt, every time we need to improve the protocol to address a security risk. Additionally, we will upgrade the protocol version at least once a year, even if no security risks have been found in the latest version of the protocol.

If your favorite client depends on a 4 year old version of the E2EE protocol library, you won’t be able to silently downgrade security for all of your conversation participants. Instead, you will be prevented from talking to most users, due to incompatible cryptography.

Version Deprecation Schedule

Let’s pretend, for the sake of argument, that we launch the first protocol version on January 1, 2025. And that’s when the first clients start to be built atop the libraries that speak the protocols.

Assuming no emergencies occur, after 9 months (i.e., by October 1, 2025), version 2 of the protocol will be specified. Libraries will be updated to support reading (but not sending) messages encrypted with protocol v2.

Then, on January 1, 2026 at midnight UTC–or a UNIX timestamp very close to this, at least–clients will start speaking protocol v2. Other clients can continue to read v1, but they should write v2.

This will occur every year on the same cadence, but with a twist: After clients are permitted to start writing v3, support for reading v1 MUST be removed from the codebase.

This mechanism will hold true even if the protocols are largely the same, aside from tweaked constants.

What does Alacrity give us?

Alacrity allows third-party open source developers the capability of writing their own software (both clients and servers) without a significant risk of the Matrix and OMEMO problem (i.e., stale software being used years after it should have been deprecated).

By offering a sliding window of acceptable versions and scheduling planned version bumps to be about a year apart, we can minimize the risk of clock skew introducing outages.

Additionally, it provides third-party developers ample opportunity to keep their client software conformant to the specification.

It doesn’t completely eliminate the possibility of stale versions being used in silos. Especially if some developers choose malice. However, anyone who deviates from the herd to form their own cadre of legacy protocol users has deliberately or negligently accepted the compatibility risks.

Can you staple Alacrity onto other end-to-end encryption projects?

Not easily, no.

This is the sort of mechanism that needs to be baked in from day one, and everyone needs to be onboard at the project’s inception.

Retroactively trying to make Matrix, XMPP, OpenPGP, etc. have Cryptographic Alacrity after the horses left the barn is an exercise in futility.

I would like your help introducing Alacrity into my pet project.

I’d love to help, but I’m already busy enough with work and my own projects.

If you’re designing a product that you intend to sell to the public, talk to a cryptography consulting firm. I can point you to several that are reputable, but most of them are pretty good.

If you’re designing something for the open source community, and don’t have the budget to hire professionals, I’ll respond to such inquiries when my time, energy, and emotional bandwidth is available to do so. No promises on a timeline, of course.

How do you force old versions to get dropped?

You don’t.

The mechanism I mostly care about is forcing new versions get adopted.

Dropping support for older versions is difficult to mechanize. Being actively involved in the community to encourage implementations do this (if for no other reason to reduce risk by deleting dead code) is sufficient.

I am choosing to not make perfect the enemy of good with this proposal.

This isn’t a new idea.

No, it isn’t a new idea. The privacy-focused cryptocurrency, Zcash, has a similar mechanism build into their network upgrades.

It’s wildly successful when federated or decentralized systems adopt such a policy, and actually enforce it.

The only thing that’s novel in this post is the coined term, Cryptographic Alacrity.

Addendum – Questions Asked After This Post Went Live

What about Linux Distros with slow release cycles?

What about them?!

In my vision of the future, the primary deliverable that users will actually hold will most likely be a Browser Extension, not a binary blob signed by their Linux distro.

They already make exceptions to their glacial release cadences for browsers, so I don’t anticipate whatever release cadence we settle on being a problem in practice.

For people who write clients with desktop software: Debian and Ubuntu let users install PPAs. Anyone who does Node.js development on Linux is familiar with them.

Why 1 year?

It was an example. We could go shorter or longer depending on the needs of the ecosystem.

How will you enforce the removal of old versions if devs don’t comply?

That’s a much lower priority than enforcing the adoption of new versions.

But realistically, sending pull requests to remove old versions would be the first step.

Publicly naming and shaming clients that refuse to drop abandoned protocol versions is always an option for dealing with obstinance.

We could also fingerprint clients that still support the old versions and refuse to connect to them at all, even if there is a version in common, until they update to drop the old version.

That said, I would hope to not need to go that far.

I really don’t want to overindex on this, but people keep asking or trying to send “what about?” comments that touch on this question, so now I’m writing a definitive statement to hopefully quell this unnecessary discourse.

The ubiquitous adoption of newer versions is a much higher priority than the sunsetting of old versions. It should be obvious that getting your users to use the most secure mode available is intrinsically a net-positive.

If your client can negotiate in the most secure mode available (i.e., if we move onto post-quantum cryptography), and your friends’ clients enforce the correct minimum version, it doesn’t really matter so much if your client in particular is non-compliant.

Focusing so much on this aspect is a poor use of time and emotional bandwidth.


Header art also made by AJ.


Viewing all articles
Browse latest Browse all 54

Trending Articles