packages feed

crypton-2.2.0: cbits/bearssl/README.md

# BearSSL

Constant-time AES and GHASH from [BearSSL](https://bearssl.org/), vendored
here.  `VERSION` holds the upstream release these files came from, and
`import.sh` fetches them again.

## Why

crypton's portable AES and GHASH are table-driven, and both index their
tables with a secret: `cbits/aes/generic.c` with a byte of the state, in
every round and in the key expansion, and `cbits/aes/gf.c` with a nibble of
the GHASH accumulator.  Both are variable-time by construction, and the
cache-timing attacks on that shape of code are old and well documented.

The processors that have AES instructions do not run any of it -- crypton
asks them first.  What runs it is everything else: ppc64le and s390x, where
the instructions exist but crypton has no path to them; 32-bit ARM, where
the same is true; riscv64 and loongarch64; and the boards that genuinely
have no AES instructions at all, of which the Raspberry Pi 3 and 4 are by
some distance the largest population.

BearSSL's answer is bitslicing.  `aes_ct64` holds four blocks interleaved
across eight 64-bit words and computes the S-box as boolean algebra, so
there is no table and no address derived from a secret; `ghash_ctmul64`
builds the GF(2^128) multiply out of shifts, masks and integer multiplies
rather than a table of H.  Both are plain C99 and assume nothing beyond
`uint64_t`.

## What is here

| file | from |
| --- | --- |
| `aes_ct64.c` | `src/symcipher/aes_ct64.c` |
| `aes_ct64_enc.c` | `src/symcipher/aes_ct64_enc.c` |
| `aes_ct64_dec.c` | `src/symcipher/aes_ct64_dec.c` |
| `ghash_ctmul64.c` | `src/hash/ghash_ctmul64.c` |
| `dec32le.c` | `src/codec/dec32le.c`, for `br_range_dec32le` |
| `LICENSE` | `LICENSE.txt` -- MIT, (c) 2016 Thomas Pornin |

`inner.h` is **crypton's, not upstream's**.  Each of those five opens with
`#include "inner.h"`, and upstream's is some two thousand lines declaring
the whole library; these five want six things from it.  So this one gives
those six and nothing else, which is what lets the five stay byte for byte
what upstream ships.  `import.sh` does not overwrite it.

The byte-order helpers in it are written rather than copied, in their plain
portable form without upstream's unaligned-access fast paths, so that no
platform configuration comes with them.

## Keeping it honest

`cbits/tests/bearssl_diff.c` checks this against the implementation it
replaces: the FIPS-197 vectors first, so that agreement means AES and not
merely that both sides compute the same wrong thing, then a run of random
keys and blocks, then GHASH against the 4-bit table.  Given any argument it
corrupts three results on purpose and the comparison has to notice -- a
differential test that cannot fail has said nothing.