crypto::ccm
AES-CCM, from RFC 3610 / NIST SP 800-38C.
The cipher on the wire: CCMP protects every WPA2 data frame with AES-128 in
CCM mode — counter mode for confidentiality, CBC-MAC for integrity, both
from the one AES block operation. ccmp_encrypt/ccmp_decrypt in the
crypto table are this with the 802.11 nonce and additional-data framing on
top; that framing is protocol glue and lives with the supplicant, while the
transform itself is here and generic.
One primitive, two jobs, and why the order matters on decrypt
Section titled “One primitive, two jobs, and why the order matters on decrypt”Encryption computes the MIC over the plaintext first, then counter-encrypts
plaintext and MIC together. Decryption must therefore counter-decrypt
first, then recompute the MIC over the recovered plaintext and compare — and
it must not reveal the plaintext if the MIC is wrong, because releasing
unauthenticated plaintext is the classic CCM misuse. [decrypt] returns an
error and zeroes its output on a MIC mismatch.
Parameters are fixed to what CCMP uses and what the RFC 3610 vectors exercise: a 13-byte nonce (so the length field L is 2) and a caller-chosen MIC length M (8 for CCMP).
enum Error { Mic, BadLength,}Errors from [decrypt].
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
Functions
Section titled “Functions”decrypt
Section titled “decrypt”fn decrypt(key: &[u8; 16], nonce: &[u8], aad: &[u8], ciphertext: &[u8], mic: &[u8], out: &mut [u8]) -> Result<(), Error>Decrypt ciphertext and verify mic under key/nonce/aad.
Writes the recovered plaintext into out only if the MIC verifies; on
failure out is zeroed and [Error::Mic] is returned, so unauthenticated
plaintext never reaches the caller.
References: Error
encrypt
Section titled “encrypt”fn encrypt(key: &[u8; 16], nonce: &[u8], aad: &[u8], plaintext: &[u8], mic_len: usize, out: &mut [u8]) -> Result<[u8; 16], Error>Encrypt plaintext under key/nonce with aad authenticated.
Writes the ciphertext (same length as the plaintext) into out, and
returns the mic_len-byte MIC. The 802.11 caller appends the MIC to the
frame; keeping it separate here avoids a second length to get wrong.
References: Error