negative zero

Matrix's new Rust crypto library, vodozemac, has been audited

2022 May 18

[crypto] [info] [matrix] [messaging] [tech]

The Matrix team has been working on a reimplementation of its crypto library, this time in Rust. The team announced two days ago that this new library, vodozemac, has been audited by a third-party, Least Authority. vodozemac should be both more secure and more performant than libolm, and excitingly, now that it has been audited, vodozemac is the new reference implementation for Matrix's end-to-end encryption!


Matrix's C/C++ libolm library was audited in 2016. The audit was funded by Open Technology Fund (which may be cause for concern, but that's not the point of this post) and conducted by NCC Group. You can read the libolm audit here. It's a good read which is useful if you're trying to understand Matrix's security model and how its crypto works.

One thing you might notice if you read the libolm audit is that the Matrix team only actually fixed one of the issues raised within libolm itself. Five of the nine issues were addressed in the client software development kits (SDKs), rather than solving them in the underlying crypto library.

Table of Findings from the libolm audit. There are 9 identified issues. One is marked "Fixed", one "Risk Accepted", and two just "Not Fixed". The other five are "Not Fixed" with an asterisk which explains, "While these findings are addressed in matrix-js-sdk, the Olm library does not address the issues."

from "Olm Cryptographic Review" by NCC Group

This is particularly concerning, since libolm is used by a number of applications that don't use the reference SDKs, including not only independent Matrix clients like nheko but also unrelated applications, like Mastodon (which plans to implement end-to-end encrypted direct messages and recommends using libolm).

vodozemac, a rewrite of libolm in Rust, should be faster, more secure, and just generally better than its predecessor. The Matrix team is also working on matrix-sdk-crypto, "an SDK-independent Rust library which abstracts away the complexities and risks of implementing E2EE, designed to plug into existing SDKs in any language". This should also help solve the finding-addressed-in-SDK-not-libolm issues by providing a standard SDK everyone can use. According to this announcement, matrix-sdk-crypto will be independently audited at some point in the future.

vodozemac audit

vodozemac was audited by Least Authority. This audit was paid for in part by gematik, the German national agency which is creating a Matrix-based national healthcare communication network. You can read the vodozemac audit here.

I read the audit this morning, and I'll share my notes on it below.

This is considered a comprehensive audit of the vodozemac library. Overall, the audit was not very interesting, which is a good thing.

Least Authority identified 10 issues and made 8 suggestions. Of those, Matrix addressed 8 issues and implemented 7 of the suggestions. This leaves 2 issues and 1 suggestion:

Issue I: Keys in Memory Not Secure Against Swap Access and Side-Channel Attacks

An attacker with swap access or the ability to do side-channel attacks (e.g., Spectre/Meltdown) could steal keys.

Least Authority recommends encrypting keys while not in use, as OpenSSH does.

The Matrix team intends to do this but has not yet.

Issue J: MAC Tag Truncated to Insufficient Length

vodozemac uses (32-byte) HMAC-SHA256 tags for authentication, but these are truncated to 8 bytes. The minimum recommendation is half the length of the digest (16 bytes), meaning vodozemac provides weaker authentication than recommended.

The Matrix team intends to fix this, but it requires an update to the Matrix Protocol, and it is considered lower priority.

Suggestion 8: Make Number of Chain and Message Keys Configurable

Each message is encrypted with a different key, for forward secrecy. If messages are skipped (as when delivered out-of-order), the keys to decrypt those messages are stored so that when the message is received it can be decrypted. vodozemac will store up to 40 keys for skipped messages. If more than 40 messages are skipped, the user will not be able to decrypt future out-of-order messages.

Least Authority recommends making this number of stored keys configurable.

The Matrix team decided not to make this number configurable:

Exposing such an option would increase the probability of misuse among client authors and, from their practical experience, it is extremely unlikely to encounter a larger number of skipped messages.


vodozemac, Matrix's replacement for libolm, underwent a comprehensive security audit by a third-party. Most of the issues identified were fixed, and the Matrix team plans to address the remaining two issues in the future. matrix-sdk-crypto will be audited next.