What does HackerNews think of libsodium?

A modern, portable, easy to use crypto library.

Language: C

#3 in C
Thanks, both are good general tips, but in this specific case

https://github.com/jedisct1/libsodium

I would guess that the author of the library has full control both over optimal parallelization of a build and minimal autoconf, but he can still observe a huge speedup, so I'd still like to read his answer.

TL;DR: this code should've never passed audit. I've found numerous problems, but I'll focus on the attack that lets someone successfully manipulate a ciphertext and have it successfully decrypt as something else. While the audit report says "Boxcryptor is not enforcing integrity [of ciphertexts]," this attack can let an adversary decrypt a (short) ciphertext, given a padding oracle. This company should've never rolled their own crypto in response to Authenticated Encryption, which has been solved, if you just use a pre-existing library.

I'm surprised that this code has a "successful" audit. The cryptography _protocol_ that is implemented in the linked github repo (https://github.com/secomba/boxcryptor-single-file-decryptor) has several flaws (in addition to having some bad code practices that I'll skip over since this repo is supposed to only document the encryption protocols).

First, the authors' problems appear to stem from their choice to manually implement an unusual (and inefficient) construction of the Authenticated Encryption primitive. Authenticated Encryption is the most common crypto primitive that people when they say "they want encryption." It's placed front-and-center in libsodium, ring, mundane, tink, monocypher, and every modern cryptography library that I've seen, since it is such a common operation. Modern Authenticated Encryption constructions include: AES-GCM, (X)ChaCha20-Poly1305. While there exist others, the industry has converged on these two as the standard.

These block cipher modes did not emerge for no reason. The cryptography community has steadily iterated on what the default should be when somebody asks, "how can I encrypt my file." We've arrived at these constructions, in particular, because previous constructions have had security flaws.

The authors of this repo have chosen to use the following protocol (for decryptDataPBKDF2):

1. Derive two keys (KE, KH) from a password string using PBKDF2. KE is the encryption key used with AES, and KH is an HMAC key (used for multiple purposes, which is problematic). 2. Read the AES-CBC initialization vector, IV. Read the AES-CBC ciphertext, C. 3. Check HMAC(KH, C) == the tag in the file. 4. Output AES-CBC-DECRYPT(KE, IV, C) with PKCS#5 padding.

The core of the problem is that, while they use the HMAC to check that the ciphertext is authentic (which is a bit odd, given that they seem to claim that authenticity shouldn't matter), they never check that the IV is authentic (it's never computed in the HMAC).

The way that AES-CBC decryption works, for first 16-bytes of the decryption is AES-BLOCK-DECRYPT(KE, first 16 bytes of C) XOR IV. As a result, if the IV isn't authenticated (which it's not), then any bit that the attacker flips in the IV will flip the corresponding bit in the ciphertext. Because PKCS#5 padding is used, given a padding oracle, an adversary could decrypt messages under 16 bytes in length.

The moral of the story is DO NOT ROLL YOUR OWN CRYPTO! Rolling your own crypto can be fun and educational and informative, but DON'T DEPLOY IT!

This bug should not have arisen, because the GitHub link in this blog post should've been to https://github.com/google/tink or https://github.com/jedisct1/libsodium or some library like them.

>I of course agree with all of this, but as someone pretty much at the bottom of the food chain who just wants to encrypt some data, there's often no libraries that safely glue the primitives together in the way that I require.

>I hope this doesn't come off as entitled, but I feel like the best way to get people to stop rolling their own crypto is to provide more/better libraries.

Author here. I mentioned libsodium [1] and Tink [2]. We started Tink because we want to provide more/better libraries.

>Granted, this is getting better, for example NaCl's crypto_box[0] is awesome and very hard to misuse. But say you want forward secrecy now. chirp, tumbleweed.

It looks like you want to build an interactive protocol. I'm not sure if libsodium has a solution, but Tink doesn't. So far we've been focusing on encryption at rest. Can you tell me more about your use case?

[1] https://github.com/jedisct1/libsodium

[2] https://github.com/google/tink

I would personally recommend libsodium.js as the default choice for a JS crypto library: https://github.com/jedisct1/libsodium.js

Fundamental issues with JS/web crypto aside, that is. You would still need something like WebSign (https://www.cyph.com/websign) or a framework like Electron that allows shipping your application outside of the browser.

We looked at libsodium and its choices impacted our discussions on our system. We decided not to use it because it's not compatible with many browsers [0]

We also discussed using a modern asymmetric key algorithm. We decided on Diffie-Hellman because we were extremely confident it's secure (so long as we choose the right parameters and implement it correctly), and would be very simple to fit it into our architecture.

[0] https://github.com/jedisct1/libsodium.js/#compatibility

I had to do a little digging into where it was pulling its crypto methods from and it looks like the have a bit of their own library, but it uses libsodium via javascript wrappers underneath:

https://github.com/TankerHQ/sdk-js/tree/master/packages/cryp...

https://github.com/jedisct1/libsodium.js

So, I guess take that as you will. I haven't read much of the actual source yet.

edit: I sort of expected there would be a move to the server since it looks like they built their library to run on the server, even if it's running all of the libsodium methods in javascript but it's definitely pulling the browser version and running it all in the client: https://github.com/TankerHQ/sdk-js/blob/master/packages/file...

libsodium is written in c. "Pure javascript" is a supported compilation target[0] of the project. Emscripten is used to compile the c to javascript. There's also now a wasm compilation target, again via emscripten.

The c source code is really excellent[1]. It's worth browsing!

[0]-https://github.com/jedisct1/libsodium.js [1]-https://github.com/jedisct1/libsodium/tree/master/src/libsod...

That's a fun toy.. and a great example of how easy it is to get crypto wrong. I'm just guessing here, but you are probably missing some key derivation like PBKDF2.

Edit: For this something like tweetnacl is probably more foolproof, checkout: https://github.com/dchest/tweetnacl-js

Or libsodium which can also be compiled to pure js: https://github.com/jedisct1/libsodium.js

Yes, kind of. I use SJCL in Turtl (https://turtlapp.com) which is packaged as standalone browser app (nwjs on desktop, xwalk on android). I'd never publish the app as a web app (at least not without significant warnings to the user/an opt-in) but technically yes, we use client-side crypto in a browser.

SJCL is kind of a pain in the ass though, to be honest. It was built before Uint8Array was prevalent, meaning all your crypto data has to be encoded as a string, and you have to be extra cautious of UTF8 data (you have to decode/encode your data as ASCII strings). Someone please correct me if this is no longer the case.

Recently I've been playing with the emscripten port of libsodium (https://github.com/jedisct1/libsodium.js), which seems to be working quite well. I have yet to benchmark, but the nice thing is that eventually I can replace parts of the app with Rust (WIP) and use the exact same library for crypto as used in the js app.

So, I'd agree in general that javascript is a shitty language for crypto, or at least it was before Uint8Array et al. I'm looking forward to seeing what happens with Wasm...being able to replace a JS app with low-level code compiled from Rust or something is definitely a nice idea. My ultimate goal was to provide a comm layer between JS <--> Rust and embed the Rust portion of the app as a library (.dll/.so/etc) but perhaps it just makes sense to compile everything to Wasm and embed it that way.

Site is up on my end. Anyways, here's the GH page for anyone interested: https://github.com/jedisct1/libsodium
Far too many to list here. A small sample:

- https://github.com/mholt/caddy

Caddy is an HTTP/2 webserver written in Go that integrates with ACME and serves websites of TLS by default. It powers https://paragonie.com and manages our HTTPS certificates automatically.

- https://github.com/twigphp/Twig

Twig is one of the sane templating languages for PHP projects that I use extensively.

- https://github.com/composer/composer

Composer revolutionized PHP development.

A lot of the "PHP sucks" arguments focus on things that haven't been true about the language since 5.4 (or earlier), but one thing that truly did suck was dependency management (before composer came around).

Dependency management also sucks in other languages (and still sucks in those). I suspect that's why few used that as a criticism of PHP.

- https://github.com/jedisct1/libsodium

Libsodium: modern cryptography that you can likely find bindings for in your favorite programming language.

Gosh, to fix such a problem we'd almost need some kind of machine that can run a different program than its current one. Perhaps with evidence of that as a possibility, we could use a good crypto library instead, eg. https://github.com/jedisct1/libsodium
Well this particular project this comment thread is about does not actually implement any cryptographic operations, those are all done by libsodium[1] a project written in C.

Imagine now it is possible to construct an argument to those libsodium functions that satisfies the constraints of the Rust wrappers, but still manages to crash libsodium and execute some part of the argument, which is not unheard of since libsodium is written in C and it operates on blobs of data.

Now the only mistake the implementor of thrussh has to make is to allow for that input to be passed into the rust libsodium wrapper through the protocol implementation.

[1] https://github.com/jedisct1/libsodium

What about https://github.com/jedisct1/libsodium then?

Very high profile, no CVEs found to date.

EDIT: Can't respond to lambda below.

I was responding to THIS assertion, not proposing libsodium as a general purpose openssl replacement: "nobody can write secure C."

To which I said, here's a project that's written in C that's apparently secure.

Also: Don't implement chacha20-poly1305 or AES-GCM yourself, unless you're a crypto expert.

You'll more than likely make a mistake.

Libsodium offers both (but AES-256-GCM is only available if you have hardware support for constant-time implementations).

    crypto_aead_chacha20poly1305_encrypt()
    crypto_aead_chacha20poly1305_decrypt()
    crypto_aead_aes256gcm_encrypt()
    crypto_aead_aes256gcm_decrypt()
https://github.com/jedisct1/libsodium
That's really good news and I'm really excited about keybase's future. I'm curious though why they chose to use NaCl instead of libsodium [1]. I was thinking of doing a crypto app a while back and did some research and libsodium seems to be a more portable and recent (removed deprecated code) version of NaCl by the folks at dnscrypt. Maybe I missed something in my research?

[1] https://github.com/jedisct1/libsodium

Pardon my ignorance, but is the NaCl referred to in the gist this NaCl? http://nacl.cr.yp.to/ Or does it refer to libsodium here? https://github.com/jedisct1/libsodium

I realize that the library is probably available via my package manager, but it'd be nice if the install page (http://nacl.cr.yp.to/install.html) linked to an archive over HTTPS and had some signatures to compare hosted elsewhere.

Scrypt for key derivation, chacha20+poly1305 for authenticated secret-key encryption. In Javascript, https://github.com/jedisct1/libsodium.js provides them.
I noticed the inclusion of NIST curves and no modern ECC and decided I'd withhold judgment until someone else had a chance to look at it.

This is pretty terrible.

If anyone was looking forward to using this for creating browser extensions (do NOT deliver code from a webserver and assume it's safe!), you're better off using https://github.com/jedisct1/libsodium.js instead.

Tox is DHT/P2P based which means it does not rely on any type of centralized authority, and all traffic is encrypted using the sodium crypto library (https://github.com/jedisct1/libsodium).

Full disclosure: Tox has not yet been professionally audited.

Have you seen libsodium [1]? It's a "portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API, and an extended API to improve usability even further." I've been using it in a toy project of mine and so far I'm very impressed!

1. https://github.com/jedisct1/libsodium

DJB already wrote his own crypto library, NaCL:

http://nacl.cr.yp.to/

It's been packaged up as libsodium:

https://github.com/jedisct1/libsodium

That said, even DJB doesn't trust himself to write bug-free C code:

http://cr.yp.to/qmail/qmailsec-20071101.pdf

Reading about djbs primitive making its way in to TLS, and all the hacks being made to TLS, reminded me of CurveCP[0] and makes me wonder whether its an idea worth revisiting.

For those interested in playing with Salsa20 & poly1305 authenticated encryption outside of TLS there's Sodium[1] which has trivial C and C++ APIs and is based on djbs Nacl[2]

I'd also refer people to Matt Greens post 'How to chose an Authenticated Encryption mode'[3]. There are some interesting alternatives out there like OCB (0.7 - 0.8 cycles/byte, free for FOSS despite patents, and more understandable for mortals).

[0] http://curvecp.org/

[1] https://github.com/jedisct1/libsodium

[2] http://nacl.cace-project.eu/box.html

[3] http://blog.cryptographyengineering.com/2012/05/how-to-choos...

Most 3rd parties are building on libsodium, not the Nacl code:

https://github.com/jedisct1/libsodium

Probably the best KDF you'll get right now is scrypt[1]. NaCl did not see common adoption because until a relatively recent distribution called Sodium[2], it was not portable. And I mean really, not portable. Like, just to give an example, suppose you want to use NaCl in Node.js, which is pretty good about accepting C/C++ modules. You have two options today: one doesn't work on a 64-bit system[3] and one isn't C, it's JS which was transpiled with Emscripten[4]. I mean, don't get me wrong: the fact that we can now do this in pure JS via Emscripten is amazing, but yeah, NaCl was not universally buildable and therefore was not reliably deployable, and nobody really wanted to fix it until Sodium came along.

[1] https://www.tarsnap.com/scrypt.html

[2] https://github.com/jedisct1/libsodium

[3] https://github.com/thejh/node-nacl

[4] https://github.com/tonyg/js-nacl