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