Make encrypt_unit report a refused slice, and expand its key once

Two defects in the encrypt_unit promoted to public API last round, both found by
round 2 auditing that new code.

It returned silently without encrypting when the slice was shorter than
ALIGNED_UNIT_LEN. Its own contract requires the caller to set the container's
encrypted flag BEFORE calling — the header is the key seed — so a silent no-op
leaves a unit advertised as encrypted while still carrying plaintext, with
nothing for an authoring caller to check. It now returns bool and is
#[must_use], so ignoring the refusal is a compile-time warning; every call site
was updated to assert on it.

bool rather than Result deliberately: a wrong buffer length is a programming
error at a library boundary, not a disc condition, and a new Error variant would
mean a new numeric code plus its rendering in another repo.

It also drove CBC from the single-block aes_ecb_encrypt, rebuilding the AES key
schedule for each of the 383 blocks in a unit — an order of magnitude slower
than its inverse, which expands the key once via aes_cbc_decrypt. The missing
counterpart aes_cbc_encrypt now exists alongside it, and encrypt_unit calls it,
so the two directions are symmetric in structure as well as in result. For an
authoring caller encrypting a 90 GB image that removes ~5.6 billion redundant
key expansions.

New test pins the boundary: ALIGNED_UNIT_LEN - 1 returns false and leaves the
buffer byte-identical, ALIGNED_UNIT_LEN succeeds. The existing round-trip and
padding-asymmetry tests still pass, so the CBC rewrite is provably the same
transform.
This commit is contained in:
Matthew Jackson
2026-07-29 18:54:19 -07:00
parent 94a876664b
commit a9dc3d7244
7 changed files with 106 additions and 24 deletions
+4 -1
View File
@@ -2642,7 +2642,10 @@ mod tests {
}
// Flag encrypted BEFORE encrypting: bytes 0..16 are the key seed.
u[0] |= 0xC0;
crate::aacs::content::encrypt_unit(&mut u, key);
assert!(
crate::aacs::content::encrypt_unit(&mut u, key),
"a full-length unit must encrypt"
);
u
}