Skip to content

crypto::sha256

SHA-256, from FIPS 180-4.

The workhorse of WPA2/WPA3: the PRF that derives the pairwise key, the HMAC that authenticates each handshake message, and the PMKID all reduce to SHA-256. It is written as a streaming [Sha256] rather than a one-shot, because the supplicant hashes several non-contiguous pieces — a nonce, two MAC addresses, a label — and copying them into one buffer first would be both slower and an extra place for a length bug to hide.

SHA-256 is entirely data-independent: the same sequence of operations runs for every input of a given length, so there is no timing side channel to reason about and no branch that depends on a secret. What remains is whether the arithmetic is right, and that is what the FIPS vectors in the tests settle — the empty string, the one-block “abc”, the two-block case that exercises the length padding across a boundary, and a millon-‘a’ case that exercises many blocks.

struct Sha256 { /* private fields */ }

A streaming SHA-256 hasher.

Feed it with update as many times as needed, then take the digest with finish. The value is consumed, because the padding makes finishing a one-way step: there is no meaningful state to keep afterwards.

Implements: Hash, Clone, Default

const DIGEST_LEN: usize;

The digest is 256 bits.