rustls/crypto/hpke.rs
1use alloc::boxed::Box;
2use alloc::vec::Vec;
3use core::fmt::Debug;
4
5use zeroize::Zeroize;
6
7use crate::Error;
8pub use crate::msgs::enums::{HpkeAead, HpkeKdf, HpkeKem};
9pub use crate::msgs::handshake::HpkeSymmetricCipherSuite;
10
11/// An HPKE suite, specifying a key encapsulation mechanism and a symmetric cipher suite.
12#[allow(clippy::exhaustive_structs)]
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub struct HpkeSuite {
15 /// The choice of HPKE key encapsulation mechanism.
16 pub kem: HpkeKem,
17
18 /// The choice of HPKE symmetric cipher suite.
19 ///
20 /// This combines a choice of authenticated encryption with additional data (AEAD) algorithm
21 /// and a key derivation function (KDF).
22 pub sym: HpkeSymmetricCipherSuite,
23}
24
25/// An HPKE instance that can be used for base-mode single-shot encryption and decryption.
26pub trait Hpke: Debug + Send + Sync {
27 /// Seal the provided `plaintext` to the recipient public key `pub_key` with application supplied
28 /// `info`, and additional data `aad`.
29 ///
30 /// Returns ciphertext that can be used with [Self::open] by the recipient to recover plaintext
31 /// using the same `info` and `aad` and the private key corresponding to `pub_key`. RFC 9180
32 /// refers to `pub_key` as `pkR`.
33 fn seal(
34 &self,
35 info: &[u8],
36 aad: &[u8],
37 plaintext: &[u8],
38 pub_key: &HpkePublicKey,
39 ) -> Result<(EncapsulatedSecret, Vec<u8>), Error>;
40
41 /// Set up a sealer context for the receiver public key `pub_key` with application supplied `info`.
42 ///
43 /// Returns both an encapsulated ciphertext and a sealer context that can be used to seal
44 /// messages to the recipient. RFC 9180 refers to `pub_key` as `pkR`.
45 fn setup_sealer(
46 &self,
47 info: &[u8],
48 pub_key: &HpkePublicKey,
49 ) -> Result<(EncapsulatedSecret, Box<dyn HpkeSealer + 'static>), Error>;
50
51 /// Open the provided `ciphertext` using the encapsulated secret `enc`, with application
52 /// supplied `info`, and additional data `aad`.
53 ///
54 /// Returns plaintext if the `info` and `aad` match those used with [Self::seal], and
55 /// decryption with `secret_key` succeeds. RFC 9180 refers to `secret_key` as `skR`.
56 fn open(
57 &self,
58 enc: &EncapsulatedSecret,
59 info: &[u8],
60 aad: &[u8],
61 ciphertext: &[u8],
62 secret_key: &HpkePrivateKey,
63 ) -> Result<Vec<u8>, Error>;
64
65 /// Set up an opener context for the secret key `secret_key` with application supplied `info`.
66 ///
67 /// Returns an opener context that can be used to open sealed messages encrypted to the
68 /// public key corresponding to `secret_key`. RFC 9180 refers to `secret_key` as `skR`.
69 fn setup_opener(
70 &self,
71 enc: &EncapsulatedSecret,
72 info: &[u8],
73 secret_key: &HpkePrivateKey,
74 ) -> Result<Box<dyn HpkeOpener + 'static>, Error>;
75
76 /// Generate a new public key and private key pair compatible with this HPKE instance.
77 ///
78 /// Key pairs should be encoded as raw big endian fixed length integers sized based
79 /// on the suite's DH KEM algorithm.
80 fn generate_key_pair(&self) -> Result<(HpkePublicKey, HpkePrivateKey), Error>;
81
82 /// Return whether the HPKE instance is FIPS compatible.
83 fn fips(&self) -> bool {
84 false
85 }
86
87 /// Return the [HpkeSuite] that this HPKE instance supports.
88 fn suite(&self) -> HpkeSuite;
89}
90
91/// An HPKE sealer context.
92///
93/// This is a stateful object that can be used to seal messages for receipt by
94/// a receiver.
95pub trait HpkeSealer: Debug + Send + Sync + 'static {
96 /// Seal the provided `plaintext` with additional data `aad`, returning
97 /// ciphertext.
98 fn seal(&mut self, aad: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, Error>;
99}
100
101/// An HPKE opener context.
102///
103/// This is a stateful object that can be used to open sealed messages sealed
104/// by a sender.
105pub trait HpkeOpener: Debug + Send + Sync + 'static {
106 /// Open the provided `ciphertext` with additional data `aad`, returning plaintext.
107 fn open(&mut self, aad: &[u8], ciphertext: &[u8]) -> Result<Vec<u8>, Error>;
108}
109
110/// An HPKE public key.
111#[allow(clippy::exhaustive_structs)]
112#[derive(Clone, Debug)]
113pub struct HpkePublicKey(pub Vec<u8>);
114
115/// An HPKE private key.
116pub struct HpkePrivateKey(Vec<u8>);
117
118impl HpkePrivateKey {
119 /// Return the private key bytes.
120 pub fn secret_bytes(&self) -> &[u8] {
121 self.0.as_slice()
122 }
123}
124
125impl From<Vec<u8>> for HpkePrivateKey {
126 fn from(bytes: Vec<u8>) -> Self {
127 Self(bytes)
128 }
129}
130
131impl Drop for HpkePrivateKey {
132 fn drop(&mut self) {
133 self.0.zeroize();
134 }
135}
136
137/// An HPKE key pair, made of a matching public and private key.
138#[allow(clippy::exhaustive_structs)]
139pub struct HpkeKeyPair {
140 /// A HPKE public key.
141 pub public_key: HpkePublicKey,
142 /// A HPKE private key.
143 pub private_key: HpkePrivateKey,
144}
145
146/// An encapsulated secret returned from setting up a sender or receiver context.
147#[allow(clippy::exhaustive_structs)]
148#[derive(Debug)]
149pub struct EncapsulatedSecret(pub Vec<u8>);