Skip to main content

ferritls_rustls/
kx.rs

1//! 密钥交换组:`SupportedKxGroup` / `ActiveKeyExchange` 适配。
2//!
3//! X25519 = 非批准;secp256r1/secp384r1 = 批准(但认证前 `fips()` 恒
4//! `false`,见 lib.rs“fips() 语义”)。
5//!
6//! 私钥由 ferritls-core 的 OS 熵直读生成(批准模式的 DRBG 路径由
7//! `CryptoProvider::secure_random` 与密钥生成入口的自检守卫覆盖;
8//! ECDH 私钥生成熵需求为曲线阶长,风险敞口极小)。
9
10use rustls::crypto::{ActiveKeyExchange, SharedSecret, SupportedKxGroup};
11use rustls::{Error as RustlsError, NamedGroup, PeerMisbehaved};
12
13use ferritls_core::ecdh::{p256, p384, x25519};
14
15/// 把 core 的共享秘密错误映射为 rustls 的 InvalidKeyShare。
16fn map_dh_err(_: ferritls_core::Error) -> RustlsError {
17    RustlsError::PeerMisbehaved(PeerMisbehaved::InvalidKeyShare)
18}
19
20/// X25519(RFC 7748)密钥交换组。
21#[derive(Debug)]
22pub struct X25519;
23
24/// secp256r1(NIST P-256)密钥交换组。
25#[derive(Debug)]
26pub struct SecP256R1;
27
28/// secp384r1(NIST P-384)密钥交换组。
29#[derive(Debug)]
30pub struct SecP384R1;
31
32impl SupportedKxGroup for X25519 {
33    fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, RustlsError> {
34        let sk = x25519::SecretKey::generate().map_err(map_dh_err)?;
35        let pk = sk.public_key();
36        Ok(Box::new(ActiveX25519 { sk, pk }))
37    }
38
39    fn name(&self) -> NamedGroup {
40        NamedGroup::X25519
41    }
42
43    fn fips(&self) -> bool {
44        // X25519 独立使用为非批准算法;即便认证后也不会在批准模式提供。
45        false
46    }
47}
48
49impl SupportedKxGroup for SecP256R1 {
50    fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, RustlsError> {
51        let sk = p256::SecretKey::generate().map_err(map_dh_err)?;
52        let pk = sk.public_key();
53        Ok(Box::new(ActiveSecP256R1 { sk, pk }))
54    }
55
56    fn name(&self) -> NamedGroup {
57        NamedGroup::secp256r1
58    }
59
60    fn fips(&self) -> bool {
61        // 认证(阶段 C)落地前恒 false。
62        false
63    }
64}
65
66impl SupportedKxGroup for SecP384R1 {
67    fn start(&self) -> Result<Box<dyn ActiveKeyExchange>, RustlsError> {
68        let sk = p384::SecretKey::generate().map_err(map_dh_err)?;
69        let pk = sk.public_key();
70        Ok(Box::new(ActiveSecP384R1 { sk, pk }))
71    }
72
73    fn name(&self) -> NamedGroup {
74        NamedGroup::secp384r1
75    }
76
77    fn fips(&self) -> bool {
78        false
79    }
80}
81
82/// 进行中的 X25519 密钥交换。
83pub(crate) struct ActiveX25519 {
84    sk: x25519::SecretKey,
85    pk: [u8; 32],
86}
87
88/// 进行中的 P-256 密钥交换。
89pub(crate) struct ActiveSecP256R1 {
90    sk: p256::SecretKey,
91    pk: [u8; p256::PUBLIC_KEY_LEN],
92}
93
94/// 进行中的 P-384 密钥交换。
95pub(crate) struct ActiveSecP384R1 {
96    sk: p384::SecretKey,
97    pk: [u8; p384::PUBLIC_KEY_LEN],
98}
99
100impl std::fmt::Debug for ActiveX25519 {
101    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102        f.write_str("ActiveX25519")
103    }
104}
105
106impl std::fmt::Debug for ActiveSecP256R1 {
107    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108        f.write_str("ActiveSecP256R1")
109    }
110}
111
112impl std::fmt::Debug for ActiveSecP384R1 {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        f.write_str("ActiveSecP384R1")
115    }
116}
117
118impl ActiveKeyExchange for ActiveX25519 {
119    fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, RustlsError> {
120        let ss = self.sk.diffie_hellman(peer_pub_key).map_err(map_dh_err)?;
121        Ok(SharedSecret::from(ss.as_bytes().to_vec()))
122    }
123
124    fn pub_key(&self) -> &[u8] {
125        &self.pk
126    }
127
128    fn group(&self) -> NamedGroup {
129        NamedGroup::X25519
130    }
131}
132
133impl ActiveKeyExchange for ActiveSecP256R1 {
134    fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, RustlsError> {
135        let ss = self.sk.diffie_hellman(peer_pub_key).map_err(map_dh_err)?;
136        Ok(SharedSecret::from(ss.as_bytes().to_vec()))
137    }
138
139    fn pub_key(&self) -> &[u8] {
140        &self.pk
141    }
142
143    fn group(&self) -> NamedGroup {
144        NamedGroup::secp256r1
145    }
146}
147
148impl ActiveKeyExchange for ActiveSecP384R1 {
149    fn complete(self: Box<Self>, peer_pub_key: &[u8]) -> Result<SharedSecret, RustlsError> {
150        let ss = self.sk.diffie_hellman(peer_pub_key).map_err(map_dh_err)?;
151        Ok(SharedSecret::from(ss.as_bytes().to_vec()))
152    }
153
154    fn pub_key(&self) -> &[u8] {
155        &self.pk
156    }
157
158    fn group(&self) -> NamedGroup {
159        NamedGroup::secp384r1
160    }
161}
162
163/// X25519 组单例。
164pub static X25519_GROUP: &dyn SupportedKxGroup = &X25519;
165/// P-256 组单例。
166pub static SECP256R1_GROUP: &dyn SupportedKxGroup = &SecP256R1;
167/// P-384 组单例。
168pub static SECP384R1_GROUP: &dyn SupportedKxGroup = &SecP384R1;
169
170/// 默认(非批准模式)密钥交换组清单;顺序即偏好,首项为 TLS 1.3
171/// 默认 key share(X25519:非 FIPS 模式下的主流互操作选择)。
172pub static ALL_KX_GROUPS: &[&'static dyn SupportedKxGroup] = &[&X25519, &SecP256R1, &SecP384R1];
173
174/// 批准模式密钥交换组清单(无 X25519)。
175pub static FIPS_KX_GROUPS: &[&'static dyn SupportedKxGroup] = &[&SecP256R1, &SecP384R1];