@soatok once again. good read! The ending is 🧑🍳 👌
The silver lining to the worst issue I’ve disclosed here is we finally have a solution for “Unable to decrypt message”: Just set your public key to zero.
🫳 🎤
@soatok Calling matrix privacyslop will continue until encryption improves!!!
@soatok lol @ the table where you try to estimate the velocity of volozemak usage at the end of the post. All the "unchanged" are all dead projects. You cant seriously write this in full honesty right ? That's quite ridiculous.
@soatok
> 5 PoCs
Oh shit…
> What happens if you set one of the inputs to zero?
I seriously felt a chill down my spine.
Like the ghost of Bobby Tables just sat next to me.
> <version downgrade shenanigans>
/me checks his sundial to see what year is this
@soatok One of the worst parts of matrix's popularity is how they stained the reputation of E2EE: People _expect_ E2EE to be inherently buggy and user unfriendly, so they tend to delay or avoid trying alternatives that are E2EE.
@soatok really get the feeling even I as a crypto noob could do better, sure still won't be good, but better than what matrix has done here. (E.g. rust type system is strong enough that you could make a type that can't be zero, and you can enforce the use of that)
@soatok Didn't they "go down the Venture Capital" road end of 2021? I'm sure that's not related at all.
@soatok I’m absolutely gobsmacked that the famously finicky, complicated to self-host, federated chat software with encryption slapped on after the fact has any security vulnerabilities in it at all. Surely the code base hasn’t grown too messy for the famously cocky devs to properly understand and maintain, has it?
@soatok lol. The closing line is a banger! Well done. =)
@soatok its impressive how many levels of smell test they keep failing at
@soatok thank you! This is very informative.
@soatok For a dhole, you sure do like dogging on people. 
@soatok@furry.engineer really said "I'm about to end this platform's whole career!"
I'm aware that, much like how this ID debacle isn't going to "kill Discord," this is hardly going to kill Matrix. It probably won't even stop the evangelists. But this was satisfying to see~
Those closing thoughts... chefs kiss
@soatok Do you know if this is exploitable? I wasn't clear on whether you traced it that far.
@varx Setting your own key to all zeroes sure sounds exploitable by a participant to me (and in a group chat it would seem to make a third party actor's work given access only to ciphertext much easier); and truncating a HMAC sounds like something a malicious party along the network data path could do.
So I would put both of those in the category of "plausibly exploitable" at least.
That is just the basics of development: test your input. When coding, we have to think of that all time. What the hell they do? And they don't want to add a simple test? Why? That's just nonsense! @soatok
@soatok once again I’m reminded that you should never implement your own crypto. When you’re in a situation where you must implement crypto you always should assume you’re an idiot, that you will get things wrong, and plan the protocol to be able to shut off the versions where you screwed up. Then find people who can tell you how you screwed things up and believe what they say.
@soatok what is it about these types that make them fuck up exponents like it’s a hazing ritual? nevermind them then doubling down with their fingers in their ears, going “nuh-uh-uh can’t heaaaaar youuuuu”…
I want to include this excerpt from the Matrix response:
Your PoC correctly demonstrates that the Olm 3DH implementation in vodozemac does not currently perform the all-zero DH output check. As we're sure you're aware, the check for contributory behaviour in X25519 is a contentious topic among cryptographers, with some calling for it, but others like RFC 7748[1] calling it optional or even arguing against it (e.g. Trevor Perrin[2]). We've previously considered adding it but ultimately avoided it due to the conclusion that there's no practical security impact on Matrix. In other places like SAS/ECIES we explicitly reject non-contributory outputs because those handshakes can be used in unauthenticated contexts where an all-zero DH output could directly collapse channel security.
The [2] points to https://moderncrypto.org/mail-archive/curves/2017/000896.html
Which is talking about the Diffie-Hellman primitive, not what protocols building atop ECDH should do.
@soatok I'm also baffled about their response to your note on Olm V2. "V2 is an experiment" - yes? That's what you were talking about?
@soatok why didn't you post the full reply?
To sketch out an argument, it's helpful to consider two possible cases of where it might matter. One, an active attacker, Mallory, trying to manipulate a handshake between two honest parties Alice and Bob. Two, a dishonest participant, Malice, taking the place of Bob.
In the first case, the handshake is protected from Mallory on the Matrix level, by the fact that Matrix requires all key inputs used in the Olm 3DH handshake (except for the "base key") be signed by the long-term Ed25519 identity keys of the participants. Inbound session establishment is only accepted when the sender identity key matches a signature-verified device key for the claimed sender, and outbound uses signature-verified key bundles.
Thus, a third party like Mallory cannot replace any of the bundle keys (the X25519 identity key or the signed pre-key, be it an OTK or the fallback key). The only key that can be replaced is the base key Ea (i.e. Alice's ephemeral "base" key, assuming Alice is the one opening a channel with Bob) which, if replaced with a small order subgroup element, would result in an all-zero DH(Ib, Ea) output on Bob's side. But even then, the attacker cannot influence the corresponding term on Alice's side, so Alice and Bob would still derive different shared secrets and therefore the session would not be viable.
The second case is outside our threat model, given that Malice doesn't gain any additional advantage from using this attack compared to the things she can already do by virtue of being one of the conversation endpoints.
We believe this covers all threat scenarios relevant for Matrix. If our reasoning is flawed and you see a practical attack, can you please sketch it out?
That said, given that vodozemac could potentially be used outside the context of Matrix, we will consider adding the all-zero DH output rejection check in the 3DH path as a defence-in-depth. As a nice side effect, this stops further confusion on whether this is an issue and makes X25519 handling consistent across the entire crate. At the very least, the behaviour should be documented so the user can make an informed decision.
@me Because I have 1000 characters to work with on my Fedi instance and wasn't going to squander it parroting them missing the point.
@soatok As a cryptography noob I'm astonished how easy it is to shoot yourself in the foot, even relying on supposedly secure libraries.
Just following x25519-dalek's docs would lead you to implement exactly this vulnerability. Imo, the DH function should either be marked as unsafe (forcing me to read up why this is the case), or perform the suggested check and return a Result.
Echoed for emphasis:
We've previously considered adding it but ultimately avoided it due to the conclusion that there's no practical security impact on Matrix.
Once again, they are insisting "We already knew about this risk but decided it's okay to not fix it or tell anyone about it".
Which is FUCKING BONKERS for a so-called secure messaging product!
@soatok which clearly shows that even if they could do cryptography, they sure as hell can not do security. sadly, it's a rather common mix of incompetence and arrogance.
I added more info to the blog post about what an attack would actually look like, because I'm tired of trying to explain it in parallel to dozens of people and doing a bad job as a result:
@soatok
Sigh.
The author of a cryptography system should be the kind of paranoid who ensures that even the formatting of the whitespace in the source code is verifiably secure.
Bumbling muppets.
@soatok as someone with no deeper understanding of cryptography I am wondering: even if they are right, how bad would it have been to just do the fucking check anyway?
@HorayNarea If you do it right (i.e., using a constant-time compare)? It's basically free. There is no downside.
Other protocols explicitly require it as a MUST.
@soatok downside of doing things right: no fun fun fun fuuuuuun blogposts 😵💫
@HorayNarea Nah, doing things right can still yield fun blog posts:
https://soatok.blog/2026/01/15/software-assurance-that-warm-and-fuzzy-feeling/
@HorayNarea (The was_contributory() check does this securely.)
@soatok your bottom line for the first misc issue…
> But there’s no way anything important relies on this, so who cares?
…reads like a "The monkey's paw curls"-type of sentence 🫣
@soatok saddened but also not surprised :')
@soatok oh my god that really is a 10/10 on the stupidity scale for a vuln.
lol. lmao even. this is ridiculous. HOW.
(I mean I know how, they don't care as much as they want folks to believe they do, but STILL)
@soatok the fact that both this and your 2024 findings were done pretty casually is also very worrying from a "the fuck else is wrong in there" perspective - not just in their crypto, at least for me personally. Not all of it is probably going to be as "what the fuck how did this ship" levels of bad as these two (incl. how they handled the disclosures) but like...
These seem like somewhat trivial things to not do? I'm not a cryptographer by any means - I fuck with power systems controls bullshit, not this, I get the joy of working with a very... unique language and ecosystem - but seeing these seemingly-obvious flaws not only a. exist but also 2. not be addressed (or acknowledged to be a Concern) does not inspire confidence in their design.
@soatok nice post, reading it now…
My understanding is that
the identity element for addition is zero
the identity element for multiplication is one
…?
@marshray Yeah it's also called the point at infinity, but in X25519 it's a 32-byte sequence of NUL.
@project1enigma @mei @marshray Please don't read too much into the notation I'm using.
The entire point of that mess was to communicate "x * 0 = 0" in a generic way that vaguely describes Diffie-Hellman-shaped protocols.
@soatok if I read this right... a server / home hub in matrix could MITM users,
and possibly(?) a malicious group client could MITM the group?
@risottobias There's an Ed25519 in the middle of the end-to-end protocol that mitigate the MITM, but the identity element can leak the group key to the server lol
@soatok so I can read the juicy, spicy data in a private group. neat.
So, you're missing a couple of things:
The severity is high because it leads to a total loss of confidentiality and integrity.
I didn't say likelihood was high or difficulty was low. That would have been critical :P