david wong

Hey! I'm David, the author of the Real-World Cryptography book. I'm a crypto engineer at O(1) Labs on the Mina cryptocurrency, previously I was the security lead for Diem (formerly Libra) at Novi (Facebook), and a security consultant for the Cryptography Services of NCC Group. This is my blog about cryptography and security and other related topics that I find interesting.

Quick access to articles on this page:

more on the next page...

Encrypting a file posted September 2018

eureka

Encrypting a file is hard. I often need to do it to protect confidential data before sending it to someone. Besides PGP (yerk) there doesn't seem to be any light tools to do that easily. The next best option is often to have a common messaging app like Signal. So I made my own. It's called Eureka and it's available in binaries or if you have Golang installed on your device, directly by doing this:

$ go get github.com/mimoo/eureka

It's also 100 LOC. It's just doing a simple job that seems to be missing from most default tooling.

2 comments

Want to implement something fun today? posted September 2018

You should try to implement Disco!

Disco is a specification that once implemented allows you to encrypt sessions (like TLS) and encrypt, authenticate, hash, generate random numbers, derive keys, etc. (like a cryptographic library). All of that usually only needs less than a thousand lines of code.

Here's how you can do it:

1. Strobe. The first step is to find a Strobe implementation (Disco uses Strobe for all the symmetric crypto). Reference implementations of Strobe exist in C and Python, unofficial ones exist in Golang (from yours truly) and in Rust (from Michael Rosenberg). but if you're dealing with another language, you'll have to implement the Strobe specification first!

2. Noise. Read the "How to Read This Document and Implement Disco" section of the Disco specification. What it tells you is to implement the Noise specification but to ignore its SymmetricState and CipherState sections. (You can also ignore any symmetric crypto in there.) You can find Noise libraries in any languages, but implementing it yourself is usually pretty straight forward (here you only really have to implement the HandshakeState).

3. Disco. Once you have that (which should take 500 LOC top), implement the SymmetricState specified by Disco.

4. Tada!

PS: if you want to write one in python, that'd be really great! You can take a look at the already existing implementations here.

comment on this story

Tamuro meetup in London tonight posted August 2018

I will be at Tamuro tonight. It's a security/crypto meetup where we mostly drink beers and chat.

To know the location you need to solve one of the challenges there summarized here as well:

comment on this story

Advances in permutation-based cryptography posted August 2018

I will be talking about modern session encryption at the Advances in permutation-based cryptography workshop in Milan in October. The program looks quite interesting with talks on Xoodoo, Gimli and others.

I'll personally introduce sponge constructions, Strobe and Disco:

Today, SSL/TLS is the de-facto standard for encrypting communication. While its last version (1.3) is soon to be released, new actors in the field are introducing more modern and better designed protocols. This talk is about the past, the present and the future of session encryption. We will see how TLS led the way, how the Noise protocol framework allowed the standardization of more modern and targeted protocols and how the duplex construction helped change the status quo.

1 comment

Facebook's TLS 1.3 library posted August 2018

Facebook has released their TLS 1.3 library Fizz in open source. In their post they mention early data (0-RTT):

Using early data in TLS 1.3 has several caveats, however. An attacker can easily replay the data, causing it to be processed twice by the server. To mitigate this risk, we send only specific whitelisted requests as early data, and we’ve deployed a replay cache alongside our load balancers to detect and reject replayed data. Fizz provides simple APIs to be able to determine when transports are replay safe and can be used to send non-replay safe data.

My guess is that either all GET requests are considered safe, or only GET requests on the / route are considered safe. I'm wondering why they use a replay cache on the other side as this overhead could nullify the benefits of 0-RTT.

They also mention every state transitions being stored in one place, this is true:

FIZZ_DECLARE_EVENT_HANDLER(
    ClientTypes,
    StateEnum::Uninitialized,
    Event::Connect,
    StateEnum::ExpectingServerHello);

FIZZ_DECLARE_EVENT_HANDLER(
    ClientTypes,
    StateEnum::ExpectingServerHello,
    Event::HelloRetryRequest,
    StateEnum::ExpectingServerHello);

FIZZ_DECLARE_EVENT_HANDLER(
    ClientTypes,
    StateEnum::ExpectingServerHello,
    Event::ServerHello,
    StateEnum::ExpectingEncryptedExtensions);

I think this is a great idea, which more TLS libraries should emulate. I had started a whitelist of transitions for TLS 1.3 draft 18 here but it's probably outdated.

comment on this story

Problems that UDP and only UDP has posted August 2018

You sometimes don't want or can't use TCP, and you thus have to deal with UDP.

To Simplify, TCP is just a collection of algorithms that extend UDP to make it support in-order delivery of streams. UDP on the other hand does not care about such streams and instead sends blocks of messages (called datagrams) in whatever-order and provides no guarantee what-so-ever that you will ever receive them.

TCP also provides some security guarantees on top of IP by starting a session with a TCP handshake it allows both endpoints of a communication to provide a proof of IP ownership, or at least that they can read whatever is sent to their claimed IPs. This means that to mess up with TCP, you need to be an on-path attacker man-in-the-middle'ing the connection between the two endpoints. UDP has none of that, it has no notion of sessions. Whatever packets are received from an IP, it'll just accept them. This means that an off-the-path attacker can trivially send packets that look like they are coming from any IP, effectively spoofing the IP of either one of the endpoint or anyone on the network. If the protocol built on top of UDP does not do anything to detect and prevent this, then bad things might happen (from complex attacks to simple denial of services).

This is not the only bad thing that can happen though. Sometimes (meaning for some protocols) a well-crafted message to an endpoint will trigger a large and disproportionate response. Malicious actors on the internet can use this to perform amplification attacks, which are denial-of-service attacks. To do that, the actor can send these special type of messages pretending to be a victim IP and then observe the endpoint respond with a large amount of data to the victim IP.

Intuitively, it sounds like both of these issues can be tackled by doing some sort of TCP handshake, but in practice it is rarely the case as the very first message of your protocol (which hasn't been able to provide a proof of IP ownership yet) can still trigger large messages. This is why in QUIC, the very first message from a client needs to be padded with 0s in order to make it as large as the server's response. Meaning that an attacker would have to at least spend as much resources that is provided by the attack, nullifying its benefits.

Looking at another protocol built on top of UDP, DTLS (TLS for UDP) has a notion of "cookie" which is really some kind of bearer token that the client will have to keep providing to the server in relevant messages, this in order to prove that it is indeed the same endpoint talking to the server.

1 comment

TLS 1.3 is out! posted August 2018

TLS 1.3 has been released as RFC 8446. It took 28 drafts and more than 4 years since draft 0 to come out. Cloudflare has a long blog post about it. Some questions about the deployment of 1.3:

  • Will we see a fast deployment of the protocol? It seems like browsers are ready, but web servers will have to follow.
  • Who will use 0-RTT? I'm expecting the big players to use it (largely because they've been requesting it) but what about the small ones?
  • Are we going to see vulnerabilities in the protocol? It seems highly unlikely, TLS 1.2 itself (with AES-GCM) has remained solid for more than 10 years.
  • Are we going to see vulnerabilities in the implementations? We will see about that. If anything happens, I'm expecting it to happen around 0-RTT, PSKs and key exports. But let's hope that libraries have learned their lessons.
  • Is BearSSL going to implement TLS 1.3? It sounds like it.
comment on this story