Repository navigation
feat(aead): fuse the AES-CCM CBC-MAC and CTR passes with aesni_ccm64 - #147
Merged
Merged
Conversation
CCM ran two passes over the message (CBC-MAC, then CTR) even though
`aesni-x86_64.pl` exports `aesni_ccm64_{encrypt,decrypt}_blocks`, which
interleave the two AES chains over whole blocks.
`Aes` now implements `Ccm` itself — the same split the other modes use, a
concrete impl for AES plus a marker-bounded generic impl — and drives the
assembly routine the way `CRYPTO_ccm128_{encrypt,decrypt}_ccm64` does: the
fused body covers whole blocks and the partial tail, the `ctr64_add`
counter advance and the tag mask stay in Rust. A CPU without AES-NI falls
back to the portable driver, and every other cipher keeps it too.
B0/AAD/length/tag helpers moved to module-level functions so both drivers
share them. A differential test walks a range of message lengths (0, 1, 15,
16, 17, 31, 32, 33, 64, 100) comparing the fused and portable paths; it
caught a first version that skipped the tail when the message was shorter
than one block.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Item 1 of the follow-up list from #144: wire the AES-NI fused bodies for the modes that were still on portable loops.
Done: CCM. CCM ran two passes over the message (CBC-MAC, then CTR) even
though
aesni-x86_64.plexportsaesni_ccm64_{encrypt,decrypt}_blocks, whichinterleave the two AES chains over whole blocks.
Aesnow implementsCcmdirectly — the same split the other modes use(
impl Ctr for aes::Aes/impl Gcm for aes::Aesalongside amarker-bounded generic impl) — and drives the assembly routine the way
CRYPTO_ccm128_{encrypt,decrypt}_ccm64does: the fused body covers wholeblocks, while the partial tail, the
ctr64_addcounter advance and the tagmask stay in Rust.
CcmMarkeris new; every cipher that already implementsBlockCipherMarkerkeeps the portable driver, and so does a CPU withoutAES-NI (
Aes::enc_schedulereports whether the schedule is in the AES-NIformat the body needs).
B0/AAD/length/counter/tag helpers moved to module-level functions so bothdrivers share one copy (
MacBlocksreplaces the byte-at-a-time MAC loop).decrypted plaintext, in one pass, exactly like the C driver.
Not done: OCB3. Its assembly routine takes the OCB state machine with it
(
offset_iin/out, the 64-entryL_itable,checksum,start_block_num),so the mode's seal/open have to be factored first — AAD offset handling, tail
and tag are reusable as-is, but the full-block loop is currently inline in the
generic
Ocb3Impland there is no way to swap it for one concrete cipherwithout that split (the same reason
Ctr/Gcmhave dedicatedAesimpls).The mapping itself is understood: crown's
l[i] = L_i(i in 0..64) matchesthe table the assembly indexes by
ntz(block)andstart_block_numwould be1 for crown's one-shot seal. It is a self-contained next step; I stopped
rather than land it half-verified, since unlike CCM it cannot be validated by
dropping it into the existing implementation.
Verification
evpciph_aes_ccm.txtvectors (the integration test drives AES-CCM,ARIA-CCM, Camellia-CCM, SM4-CCM and SEED-CCM; the non-AES ciphers exercise
the still-generic path).
lengths 0, 1, 15, 16, 17, 31, 32, 33, 64 and 100, plus a round trip. It
caught the first version skipping the tail whenever the message was shorter
than one block.
CARGO_INCREMENTAL=0 cargo test --all(the CI command, asm enabled throughfeature unification): green.
cargo clippy -Dwarningswith and without--features asm, andcargo fmt --all --check.Next
OCB3 as described above, then the two items that need AVX512-IFMA hardware
(
aes-gcm-avx512and thersazx2 driver).