[KeyManager] Add HPKE and DHKEM crypto primitives#643
[KeyManager] Add HPKE and DHKEM crypto primitives#643NilanjanDaw merged 16 commits intogoogle:mainfrom
Conversation
b1f0ee6 to
b27759c
Compare
5c118fe to
6c40a58
Compare
6c40a58 to
7cdba30
Compare
7cdba30 to
9812c48
Compare
keymanager/km_common/src/crypto.rs
Outdated
|
|
||
| // Extract eae_prk | ||
| // labeled_ikm = "HPKE-v1" || suite_id || "eae_prk" || shared_key | ||
| let labeled_ikm = [b"HPKE-v1".as_slice(), &suite_id, b"eae_prk", &shared_key].concat(); |
There was a problem hiding this comment.
.concat creates a heap. and clear_stack_on_return won't clear that heap i think.
can you wrap this in Zeroizing::new(?
There was a problem hiding this comment.
It may be a good idea to wrap all the private types with structures that ZeroizeOnDrop.
- It simplifies error handling (Early returns without zeroizing sensitive data).
- As the code shifts around, critical data will still be zeroized.
There was a problem hiding this comment.
Thanks for pointing this out. I have added a ZeroizeOnDrop to the PrivateKey wrapper. Additionally wrapped the labeled_ikm and labeled_info with Zeroizing::new()
There was a problem hiding this comment.
Ah I'm sorry, I didn't realize that when I suggested moving to .concat(), that would lead to additional heap issues.
I see you have an implementation of labeled_extract() in #649 that's earmarked for tests, but makes it clear when a Vec is being created. Could consider adopting that pattern here.
There was a problem hiding this comment.
Moved the labeled_extract and labeled_expand to separate functions with SecretBox based storage. This should make it easier to handle the secret material clean-up.
|
/gcbrun |
Vault for secure key storage Implements a secure Vault struct in keymanager/common that stores sensitive key material in a memory-backed file created via memfd_create. Key Changes: - Sealed Storage: Uses memfd_create with `MFD_CLOEXEC` and `MFD_NOEXEC_SEAL` to create an anonymous file in RAM. - Immutability: Applies `F_SEAL_GROW`, `F_SEAL_SHRINK`, and `F_SEAL_SEAL` using fcntl to prevent modification of the file's content or size after initialization. - Secure Cleanup: Implements ZeroizeOnDrop (via the zeroize crate) to ensure the memory map is cleared when the Vault is dropped. - Restricted Access: The underlying file descriptor is dropped immediately after mapping (except in test builds), ensuring no direct file access remains.
`km_common`
Introduces a `crypto` module in `km_common` to handle cryptographic
operations backed by BoringSSL (`bssl-crypto`).
Key Contributions:
1. HPKE Decryption (`decrypt`):
- Implements `decrypt` using `bssl_crypto::hpke` for "single-shot"
Hybrid Public Key Encryption (HPKE) opening.
- Supports the standard HPKE suite: DHKEM(X25519, HKDF-SHA256),
HKDF-SHA256, and AES-256-GCM.
- Maps internal `HpkeAlgorithm` types to BoringSSL parameters.
2. DHKEM Decapsulation (`decaps`):
- Implements a standalone `decaps` function for DHKEM(X25519, HKDF-SHA256).
- Manually constructs the KEM context (suite ID, labeled IKM/Info)
compliant with RFC 9180 to derive the shared secret directly from
an encapsulated key and private key.
- Validates implementation against test vectors accounting for
BoringSSL's internal private key clamping.
3. Dependencies & Error Handling:
- Adds `bssl-crypto` for underlying crypto operations.
- Uses `thiserror` for structured error definitions (`KeyLenMismatch`,
`DecapsError`, `HpkeDecryptionError`).
… key generation function.
- Refactor PublicKey and PrivateKey to use an enum-wrapped trait pattern - Use fixed-size [u8; 32] arrays for X25519 keys to improve memory hygiene - Implement Zeroize and ZeroizeOnDrop for X25519PrivateKey - Enhance decaps_internal with Zeroizing wrappers for sensitive intermediates - Add RFC 9180 Section 4.1 documentation for DHKEM decapsulation - Improve test coverage for X25519 clamped vector compatibility
- Added `test_labeled_extract_and_expand` in `x25519.rs` to verify the functionality of the new helper functions. - Ensures correct output length and that different inputs produce different outputs.
3af7e9d to
3b30e79
Compare
| const CLEAR_STACK_PAGES: usize = 2; | ||
|
|
||
| /// A trait for public keys with algorithm-specific implementations. | ||
| pub(crate) trait PublicKeyOps: Send + Sync { |
There was a problem hiding this comment.
These traits assume that every public key can do HPKE sealing and every private key can do both KEM decaps and HPKE open. If there were a future use-case for an ECDSA or ML-DSA key, it would be hard to represent those in this type system.
Would it make sense to have individual traits for each of these capabilities? Leaves room in the future for Sign and Verify traits.
There was a problem hiding this comment.
That makes sense. Let me do this in a follow up PR. Filed Issue #660 to track the change.
|
/gcbrun |
|
/gcbrun |
Introduces a
cryptomodule inkm_commonto handle cryptographic operations backed by BoringSSL (bssl-crypto).Key Contributions:
HPKE Decryption (
decrypt):decryptusingbssl_crypto::hpkefor "single-shot" Hybrid Public Key Encryption (HPKE) opening.DHKEM(X25519, HKDF-SHA256),HKDF-SHA256, andAES-256-GCM.HpkeAlgorithmtypes to BoringSSL parameters.DHKEM Decapsulation (
decaps):decapsfunction forDHKEM(X25519, HKDF-SHA256).Dependencies & Error Handling:
bssl-cryptofor underlying crypto operations.thiserrorfor structured error definitions (KeyLenMismatch,DecapsError,HpkeDecryptionError).