Page MenuHomeFreeBSD

Fortuna: Add Chacha20 as an alternative stream cipher

Authored by cem on Mar 6 2019, 5:58 AM.



Chacha20 with a 256 bit key and 128 bit counter size is a good match for an
AES256-ICM replacement.

In userspace, Chacha20 is typically marginally slower than AES-ICM on
machines with AESNI intrinsics, but typically much faster than AES on
machines without special intrinsics. ChaCha20 does well on typical modern
architectures with SIMD instructions, which includes most types of machines
FreeBSD runs on.

In the kernel, we can't (or don't) make use of AESNI intrinsics for
random(4) anyway. So even on amd64, using Chacha provides a modest
performance improvement in random device throughput today.

This change makes the stream cipher used by random(4) configurable at boot
time with the 'kern.random.use_chacha20_cipher' tunable.

Test Plan

The diff is somewhat clearer with whitespace changes hidden:

Some rough throughput numbers on an amd64 bhyve VM; using pv </dev/random >/dev/null for 30 seconds. The VM host was mostly idle. The same build was used for both tests, switching only the tunable:

Baseline revisionkernelStream cipher modeThroughput (pv)
r344844GENERIC-NODEBUGChacha20~400 MB/s

Diff Detail

Lint OK
No Unit Test Coverage
Build Status
Buildable 22911
Build 21997: arc lint + arc unit

Event Timeline

Nice work! Out for interest, why make the output generator selectable? Why not switch completely to Chacha20?


What happens if somebody changes the sysctl after the key is set?

Nice work! Out for interest, why make the output generator selectable? Why not switch completely to Chacha20?

Thanks! I think it could be done in a later step, but I wanted to add the option conservatively to avoid push-back and "astonishment."


It's a tunable — it is set once at boot time. The sysctl node is read-only and cannot be changed. Allowing run-time mode switching would complicate the code for (I felt) little benefit.

Fix a 'doh!' copy/paste error on archs without a uint128 type.

This revision is now accepted and ready to land.Mar 7 2019, 12:06 PM

Need secteam blessing to touch dev/random. Thanks!

Looks good to me in principle and I like the fact that fortuna.c no longer cares about the keystream context internals.

One request -- Could you please make test of random_chachamode not negative? It would be nice if you could also give union randomdev_key's AES portion a name, but that's optional.


Could you please rearrange the code to avoid negative logic, e.g.:

if (random_chachamode) {


} else {

(AES code block)


? This makes the code easier to follow.


Similar to above.


(Optional) - maybe give the AES context a name?

cem planned changes to this revision.Mar 7 2019, 10:07 PM
cem added inline comments.

Sure, will do.


I tried to leave existing AES-ICM mode alone as much as possible — it is visibly unmodified with 'diff -w'. Naming the AES structure here would break that.

cem marked 2 inline comments as done.

Put non-negative logical case first, for clarity. Thanks delphij@

LGTM, thanks!

(Note that randomdev_getkey() have similar issue and should be fixed too, feel free to fix it prior to commit)

This revision is now accepted and ready to land.Mar 7 2019, 11:19 PM
This revision was automatically updated to reflect the committed changes.