rustls/crypto/aws_lc_rs/pq/
mlkem.rs1use alloc::boxed::Box;
2use alloc::vec::Vec;
3
4use aws_lc_rs::kem;
5
6use super::INVALID_KEY_SHARE;
7use crate::crypto::{ActiveKeyExchange, CompletedKeyExchange, SharedSecret, SupportedKxGroup};
8use crate::ffdhe_groups::FfdheGroup;
9use crate::{Error, NamedGroup, ProtocolVersion};
10
11#[derive(Debug)]
12pub(crate) struct MlKem {
13 pub(crate) alg: &'static kem::Algorithm<kem::AlgorithmId>,
14 pub(crate) group: NamedGroup,
15}
16
17impl SupportedKxGroup for MlKem {
18 fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error> {
19 let decaps_key = kem::DecapsulationKey::generate(self.alg)
20 .map_err(|_| Error::General("key generation failed".into()))?;
21
22 let pub_key_bytes = decaps_key
23 .encapsulation_key()
24 .and_then(|encaps_key| encaps_key.key_bytes())
25 .map_err(|_| Error::General("encaps failed".into()))?;
26
27 Ok(Box::new(Active {
28 decaps_key: Box::new(decaps_key),
29 encaps_key_bytes: Vec::from(pub_key_bytes.as_ref()),
30 group: self.group,
31 }))
32 }
33
34 fn start_and_complete(&self, client_share: &[u8]) -> Result<CompletedKeyExchange, Error> {
35 let encaps_key =
36 kem::EncapsulationKey::new(self.alg, client_share).map_err(|_| INVALID_KEY_SHARE)?;
37
38 let (ciphertext, shared_secret) = encaps_key
39 .encapsulate()
40 .map_err(|_| INVALID_KEY_SHARE)?;
41
42 Ok(CompletedKeyExchange {
43 group: self.name(),
44 pub_key: Vec::from(ciphertext.as_ref()),
45 secret: SharedSecret::from(shared_secret.as_ref()),
46 })
47 }
48
49 fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
50 None
51 }
52
53 fn name(&self) -> NamedGroup {
54 self.group
55 }
56
57 fn fips(&self) -> bool {
58 super::super::fips()
71 }
72
73 fn usable_for_version(&self, version: ProtocolVersion) -> bool {
74 version == ProtocolVersion::TLSv1_3
75 }
76}
77
78struct Active {
79 decaps_key: Box<kem::DecapsulationKey<kem::AlgorithmId>>,
80 encaps_key_bytes: Vec<u8>,
81 group: NamedGroup,
82}
83
84impl ActiveKeyExchange for Active {
85 fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
89 let shared_secret = self
90 .decaps_key
91 .decapsulate(peer_pub_key.into())
92 .map_err(|_| INVALID_KEY_SHARE)?;
93
94 Ok(SharedSecret::from(shared_secret.as_ref()))
95 }
96
97 fn pub_key(&self) -> &[u8] {
98 &self.encaps_key_bytes
99 }
100
101 fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
102 None
103 }
104
105 fn group(&self) -> NamedGroup {
106 self.group
107 }
108}