Coverage Report

Created: 2025-10-31 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.27/src/crypto/hpke.rs
Line
Count
Source
1
use alloc::boxed::Box;
2
use alloc::vec::Vec;
3
use core::fmt::Debug;
4
5
use zeroize::Zeroize;
6
7
use crate::Error;
8
use crate::msgs::enums::HpkeKem;
9
use crate::msgs::handshake::HpkeSymmetricCipherSuite;
10
11
/// An HPKE suite, specifying a key encapsulation mechanism and a symmetric cipher suite.
12
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13
pub 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.
25
pub 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
0
    fn fips(&self) -> bool {
83
0
        false
84
0
    }
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.
94
pub 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.
104
pub 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)]
111
pub struct HpkePublicKey(pub Vec<u8>);
112
113
/// An HPKE private key.
114
pub struct HpkePrivateKey(Vec<u8>);
115
116
impl HpkePrivateKey {
117
    /// Return the private key bytes.
118
0
    pub fn secret_bytes(&self) -> &[u8] {
119
0
        self.0.as_slice()
120
0
    }
121
}
122
123
impl From<Vec<u8>> for HpkePrivateKey {
124
0
    fn from(bytes: Vec<u8>) -> Self {
125
0
        Self(bytes)
126
0
    }
127
}
128
129
impl Drop for HpkePrivateKey {
130
0
    fn drop(&mut self) {
131
0
        self.0.zeroize();
132
0
    }
133
}
134
135
/// An HPKE key pair, made of a matching public and private key.
136
pub 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)]
145
pub struct EncapsulatedSecret(pub Vec<u8>);