AEAD architecture: FAuthObj + multi-call GCM (from PR #90 concern A) - #102
Conversation
…m#99) Extract Concern A from the ChaCha PR MHumm#90 donor without ChaCha/Poly1305. - Polymorphic FAuthObj replaces dual FGCM/FCCM fields; public IDECAuthenticatedCipher unchanged - Keep EncodeGCM/DecodeGCM/EncodeCCM/DecodeCCM as protected wrappers (no rename break) - GCM multi-call: absorb PR MHumm#99 streaming (GHASH partial + CTR keystream remainder + Done/FFinalized) - Reject PR MHumm#90 fIsLastBlock CTR model (incorrect for unaligned multi-chunk) - Base Done virtual (no-op for CCM one-shot); TDECCipherModes.Done finalizes then verifies ExpectedTag - InitMode always FreeAndNil(FAuthObj) before recreate (leak fix) - Multi-chunk and Done-lifecycle unit tests; corrected large GCM rsp tag See Docs/plans/2026-07-25-aead-architecture.md.
47c7463 to
58b54d1
Compare
Reject DataToAuthenticate after GHASH has absorbed AAD or after Done; cap AuthenticationTagBitLength at 128 bits with a defensive tag copy; keep EncodeCCM/DecodeCCM as independent protected entry points that call FAuthObj directly so EncodeGCM overrides no longer affect CCM.
|
Habe angefangen mir diesen anzuschauen. Muss mal prüfen ob Zugriff auf CalculatedAuthenticationTag vor Aufruf von Done auch eine Exception wirft. Falls nicht würde ich das gerne einbauen, dann werden die Nutzer gleich erzogen ;-) |
|
Nix für diesen PR, aber: soweit meine kurze Recherche nach CCM und "multi-chunk" ergab, sollte auch CCM das können. Das würde bedeuten, dass nur unsere Umsetzung das nicht kann. Falls dem so ist sollte man sich das bei Gelegenheit auch mal anschauen, anderenfalls wäre ich für irgendwelche Metadaten mit denen ein Nutzer rausfinden kann, ob der Algorithmus multi-chunk fähig ist oder nicht. Nur mal so eine Idee... Ich glaube aber immer noch dass wir das mal irgendwann irgendwie auf multi-chunk Fähig umbauen können. |
|
Welche Konsequenz hätte eine Umbenennung von EncodeGCM in DECCipherModes.pas? |
|
TDECCipherModes.InitMode prüft auf Blockgröße 128 bit, das könnte aber evtl. für CCM falsch sein, da lt. etwas das ich gelesen habe (vermutlich Wikipedia Artikel) das so wohl nur im RFC definiert wurde, man müsste mal schauen wo die originale CCM Spezifikaiton ist und ob die das überhaupt so her gibt. Kann ich evtl. später mal tun, nach dem Merge. Jetzt aber erst Mal Pause für mich ;-) |
|
Ich wäre dafür, wenn CCM auch den Done Aufruf bräuchte statt im Encode/Decode das schon zu tun. Damit wäre der Livecycle für alle gleich. |
|
ECAuthenticatedCipherModesBase.pap: GetStandardAuthenticationTagBitLengths: |
|
Hallo Markus, danke fürs Durchschauen und den Merge von #102 — und für die Punkte danach, die sind alle sinnvoll. Kurz dazu:
Wenn du magst, kann ich daraus ein oder zwei kleine Follow-up-Issues/PRs machen (Lifecycle/API vs. CCM multi-chunk/Spec), statt alles in einem Klumpen. Viele Grüße |
|
Gerne in 2 PR. Danke!
Olaf Monien ***@***.***> schrieb am Di., 15. Sept. 2026,
08:25:
… *omonien* left a comment (MHumm/DelphiEncryptionCompendium#102)
<#102 (comment)>
Hallo Markus,
danke fürs Durchschauen und den Merge von #102
<#102> — und für
die Punkte danach, die sind alle sinnvoll.
Kurz dazu:
1. Exception bei CalculatedAuthenticationTag vor Done finde ich gut;
klarer Vertrag, weniger Missbrauch.
2. CCM multi-chunk bzw. zumindest eine erkennbare Capability — gerne
als eigenes Follow-up.
3. Umbenennen/EncodeAuthenticated für die protected Pfade: ja, solange
wir es intern halten und die öffentliche API nicht unnötig brechen.
4. 128-bit in InitMode vs. CCM-Spezifikation: einverstanden, das lohnt
einen gezielten Spec-Check.
5. CCM auch über Done — einheitlicher Lifecycle ist mir lieber als
Sonderwege.
6. Leeres Array + XMLDOC-Hinweis bei
GetStandardAuthenticationTagBitLengths, wenn es keine festen
Tag-Längen gibt: logisch, würde ich so dokumentieren.
Wenn du magst, kann ich daraus ein oder zwei kleine Follow-up-Issues/PRs
machen (Lifecycle/API vs. CCM multi-chunk/Spec), statt alles in einem
Klumpen.
Viele Grüße
Olaf
—
Reply to this email directly, view it on GitHub
<#102?email_source=notifications&email_token=AHCTXHMIRYDWKWW5CWVXN435PDOD7A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNRXGU3TGOJSGM4KM4TFMFZW63VMON2GC5DFL5RWQYLOM5S2KZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5675739238>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AHCTXHPF2VRMPZ4TQ42ZBU35PDOD7AVCNFSNUABEKJSXA33TNF2G64TZHMZTENJVGIZDMNJ3JFZXG5LFHM2DSNZZGQZTMNZSGSQXMAQ>
.
Triage notifications, keep track of coding agent tasks and review pull
requests on the go with GitHub Mobile for iOS
<https://github.com/notifications/mobile/ios/AHCTXHIVHTFBUUPTA6FWQLL5PDOD7A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNRXGU3TGOJSGM4KM4TFMFZW63VMON2GC5DFL5RWQYLOM5S2KZLWMVXHJKTGN5XXIZLSL5UW64Y>
and Android
<https://github.com/notifications/mobile/android/AHCTXHPPF7N3GBLG3GACRH35PDOD7A5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKNRXGU3TGOJSGM4KM4TFMFZW63VMON2GC5DFL5RWQYLOM5S2KZLWMVXHJLTGN5XXIZLSL5QW4ZDSN5UWI>.
Download it today!
You are receiving this because you modified the open/close state.Message
ID: ***@***.***>
|
|
Perfekt, danke — die beiden Follow-ups sind offen:
Viele Grüße |
Follow-up to PR #102 (points 1, 3, 5, 6). Reading CalculatedAuthenticationTag before Done now raises EDECCipherException. Protected EncodeGCM/EncodeCCM are unified as EncodeAuthenticated (Decode counterpart too). CCM materializes the authentication tag in Done so GCM and CCM share one lifecycle. Modes without prescribed tag lengths document returning an empty array. Co-authored-by: Olaf Monien <omonien@users.noreply.github.com>
Follow-up to PR #102 (points 2 and 4). CCM can process several Encode/Decode chunks when the total payload length is known (AuthenticatedPayloadLength or a one-shot Size / EncodeStream DataSize). B_0 still encodes l(m) as required by RFC 3610 / NIST SP 800-38C. InitMode keeps the 128-bit block-size check for both GCM and CCM; comments cite the original CCM spec, RFC 3610, and SP 800-38C/38D. SupportsAuthenticatedMultiChunk reports the capability. Co-authored-by: Olaf Monien <omonien@users.noreply.github.com>
For Markus — AEAD architecture (no ChaCha)
This is package A only: a careful architecture / GCM fix extracted from donor PR #90.
ChaCha / XChaCha / Poly1305 / AES-NI are not in this PR. Those stay separate packages on the fork for later.
Why bother (simple words)
Today, authenticated modes (especially GCM) are a bit of a special case:
This PR does three practical things:
FAuthObjinstead of dualFGCM/FCCMwiring.Encode/Decodecalls; the tag is finalized inDone.Init → (AAD / tag length) → Encode/Decode* → Done → read / check tag.Benefits for existing code (already, without ChaCha)
You get value even if we never merge ChaCha:
Initcase FMode ofduplication for auth properties / DoneFAuthObjimplementation without rewriting GCM againIDECAuthenticatedCiphernames stay; protectedEncodeGCM/DecodeGCMkept as wrappersCall site note: for multi-call GCM, call
Donebefore readingCalculatedAuthenticationResult. Paths that already callDone(most of the suite / normal demo style) keep working. Single-shot “encode then Done then tag” remains the normal pattern.CCM stays one-shot as before (no fake multi-chunk for CCM).
Relation to the donor PR (#90)
PR #90 mixed architecture, GCM rewrite, ChaCha, Poly1305, SIMD, AES-NI, … in one large change.
For this package we:
So: donor as inspiration and reference, not a bulk merge.
What changed (files)
Source/DECAuthenticatedCipherModesBase.pasDoneSource/DECCipherModes.pasFAuthObjwiring, leak-safeInitMode, unified finalize + ExpectedTag checkSource/DECCipherModesGCM.pasFFinalized)Unit Tests/Tests/TestDECCipherModesGCM.pasUnit Tests/Data/gcmEncryptExtIV256_large.rspDocs/plans/2026-07-25-aead-architecture.mdTests (emphasis)
Thorough coverage was a hard requirement for this package — architecture without a green GCM/CCM signal is not mergeable.
Verified locally (Delphi 13, Win32 Console DUnit):
InitRisk
Medium — touches core GCM authentication. Mitigations: multi-chunk NIST-style vectors, Done lifecycle tests, CCM full regression, no public interface rename.
Out of scope (intentionally)
cmPoly1305Suggested review order
Init→ multiEncode/Decode→Done→ tagFFinalizedFAuthObj+ property / Done wiring inDECCipherModes.pasTest plan
Happy to adjust wording or split further if anything feels too large.