Repository navigation
feat(pairwise): let the reversible deriver's keys stay in an HSM or KMS - #653
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
NewReversibleWith builds the reversible deriver on a ReversibleOps: the two keyed operations the construction needs (HMAC-SHA-256, and AES-256-CTR with a caller-supplied IV as a full 128-bit counter), implemented by the embedder against an HSM or KMS that never releases the keys. For the same keys it derives exactly the subs NewReversible does, so a deployment can move between them without changing any user's sub. NewReversible is now NewReversibleWith over in-memory operations, one code path for both. Every result is checked (a 32-byte MAC, a ciphertext as long as its input), and a failed or wrong-sized operation means the derivation or lookup couldn't be answered, never ErrSubjectNotFound. Tests cover the published vectors through ops, a 32-bit-counter implementation failing the carry vector, operation failures, the caller's context, custody and the deriver contract. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A compatibility table in GETTING_STARTED's pairwise section: for PKCS#11 HSMs, AWS CloudHSM, Google Cloud KMS, AWS KMS, Azure Key Vault Managed HSM, Azure Cloud HSM and HashiCorp Vault Transit, whether both keys can stay inside, the exact mechanisms or APIs for each operation, and caveats (the 128-bit counter, roles, unverified support), with sources. Plus how to choose between envelope-wrapped keys and HSM- or KMS-resident ones. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
osanderson
force-pushed
the
feat/pairwise-reversible-ops
branch
from
October 13, 2026 02:42
7d88dec to
3a2f59d
Compare
|
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.



pairwise.NewReversibleWith(ops ReversibleOps, opts...)builds the reversible pairwise deriver on two embedder-implemented keyed operations, so the MAC and encryption keys can stay inside an HSM or KMS that never releases them:MAC(ctx, data): HMAC-SHA-256 under the MAC key, full 32-byte output (PKCS#11CKM_SHA256_HMAC).EncryptCTR(ctx, iv, data): AES-256-CTR under the encryption key, with the 16-byte IV as the whole initial counter block incremented as one 128-bit big-endian integer (PKCS#11CKM_AES_CTRwithulCounterBits128). Decryption is the same operation.For the same keys it derives exactly the subs
NewReversibledoes, so a deployment can move between envelope-wrapped keys and HSM/KMS-resident ones without changing any user's sub.NewReversibleis nowNewReversibleWithover in-memory operations, so both share one code path (the existing weak-key checks stay inNewReversible).Fail closed: every operation result is checked (a 32-byte MAC, a ciphertext as long as its input). An error or wrong-sized result fails the derivation or lookup and is never
ErrSubjectNotFound, so it surfaces asserver_error, not an unknown subject. The caller's context reaches each operation. Custody is declared throughopts, as forNewReversible.Docs: GETTING_STARTED's pairwise section gets a compatibility table (PKCS#11 HSMs, AWS CloudHSM, Google Cloud KMS, AWS KMS, Azure Key Vault Managed HSM, Azure Cloud HSM, HashiCorp Vault Transit) with the exact mechanisms or APIs for each operation, caveats and sources, plus guidance on choosing between envelope-wrapped and resident keys (two key-service calls per derivation and per resource-server lookup with JWT access tokens).
Tests:
NewReversibleWithover a standard-library stand-in for an HSM reproduces all 11 published vectors in both directions.0xfffffffd).ErrSubjectNotFound.FuzzReversibleWithRoundTripchecks byte-identical bodies againstNewReversibleand round-trips (registered in the scheduled fuzz workflow).Non-breaking.
🤖 Generated with Claude Code