Awesome
bugsalsa
Investigating a 32-bit overflow bug in SUPERCOP-derived salsa20 implementations.
Background
cryptofuzz revealed a vulnerability in the Go x/crypto
implementation of salsa20. A misimplementation of the counter increment in assembly causes the counter to cycle shortly after 2^32
blocks.
Since the asssembly version was ported directly from SUPERCOP, it seemed probable that the bug was also present in the upstream and other derived libraries. This repository contains some adhoc code used to test whether the bug is also present in NaCL and libsodium.
The bug was fixed by the Golang team on March 20, 2019. It is now clear that the bug was known by others some years ago; it was patched in libsodium, but an empty file called warning-256gb
was deemed sufficient for SUPERCOP and no action was taken to NaCL.
Environment
Tested on Ubuntu 18.04 with
sudo apt-get install libnacl-dev libsodium-dev
Note that these tests will allocate over 256 GiB of memory!
NaCL and libsodium Comparison
The test.c
program was compiled against NaCL and libsodium and run to produce
two keyfiles. Comparing them we see a difference shortly after 256 GiB:
$ cmp key.nacl key.sodium
key.nacl key.sodium differ: byte 274877907073, line 1073727201
Note this offset is (1<<38) + 129
. This is to be expected, since even with
the incorrect high 32-bit counter increment, the first two blocks after the
overflow will still agree. Therefore the first bad block should be the third,
which starts at byte 128 after the overflow. (It's 129 in the cmp
output
because it reports offsets starting at 1.)
Keystream Cycle
Example output from cycle.c
$ ./cycle.nacl
2019-03-02T15:25:34Z compare_size=33554432
2019-03-02T15:25:34Z length=274911464192
2019-03-02T15:25:34Z buffer allocated
2019-03-02T15:34:22Z keystream written
2019-03-02T15:34:22Z key repeat: [2752, 33557184) == [274877909696, 274911464128)
2019-03-02T15:34:31Z finish