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 MlKem768;
13
14impl SupportedKxGroup for MlKem768 {
15 fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, Error> {
16 let decaps_key = kem::DecapsulationKey::generate(&kem::ML_KEM_768)
17 .map_err(|_| Error::General("key generation failed".into()))?;
18
19 let pub_key_bytes = decaps_key
20 .encapsulation_key()
21 .and_then(|encaps_key| encaps_key.key_bytes())
22 .map_err(|_| Error::General("encaps failed".into()))?;
23
24 Ok(Box::new(Active {
25 decaps_key: Box::new(decaps_key),
26 encaps_key_bytes: Vec::from(pub_key_bytes.as_ref()),
27 }))
28 }
29
30 fn start_and_complete(&self, client_share: &[u8]) -> Result<CompletedKeyExchange, Error> {
31 let encaps_key = kem::EncapsulationKey::new(&kem::ML_KEM_768, client_share)
32 .map_err(|_| INVALID_KEY_SHARE)?;
33
34 let (ciphertext, shared_secret) = encaps_key
35 .encapsulate()
36 .map_err(|_| INVALID_KEY_SHARE)?;
37
38 Ok(CompletedKeyExchange {
39 group: self.name(),
40 pub_key: Vec::from(ciphertext.as_ref()),
41 secret: SharedSecret::from(shared_secret.as_ref()),
42 })
43 }
44
45 fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
46 None
47 }
48
49 fn name(&self) -> NamedGroup {
50 NamedGroup::MLKEM768
51 }
52
53 fn fips(&self) -> bool {
54 super::super::fips()
67 }
68
69 fn usable_for_version(&self, version: ProtocolVersion) -> bool {
70 version == ProtocolVersion::TLSv1_3
71 }
72}
73
74struct Active {
75 decaps_key: Box<kem::DecapsulationKey<kem::AlgorithmId>>,
76 encaps_key_bytes: Vec<u8>,
77}
78
79impl ActiveKeyExchange for Active {
80 fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, Error> {
84 let shared_secret = self
85 .decaps_key
86 .decapsulate(peer_pub_key.into())
87 .map_err(|_| INVALID_KEY_SHARE)?;
88
89 Ok(SharedSecret::from(shared_secret.as_ref()))
90 }
91
92 fn pub_key(&self) -> &[u8] {
93 &self.encaps_key_bytes
94 }
95
96 fn ffdhe_group(&self) -> Option<FfdheGroup<'static>> {
97 None
98 }
99
100 fn group(&self) -> NamedGroup {
101 NamedGroup::MLKEM768
102 }
103}