Skip to content

Commit 365820c

Browse files
author
Steve Fan
committed
Refactor TLS cipher suite definitions and verification algorithms
- Simplified the definition of TLS 1.2 cipher suites by introducing the `feature_slice!` macro for conditional compilation based on features. - Replaced repetitive cipher suite definitions in `ecdsa.rs` and `rsa.rs` with a new macro `tls12_ecdhe_cipher_suite!` to streamline the code. - Enhanced the `ALL` and `MAPPING` constants in `verify.rs` to utilize the `feature_slice!` macro for better readability and maintainability. - Added support for EdDSA signature schemes in the verification algorithms. - Refactored RSA hash implementations and verifier constants using a new macro `rsa_hash_and_consts!` to reduce code duplication. - Updated TLS 1.3 cipher suite definitions in `aes.rs`, `chacha20.rs`, and `suites.rs` to use the `tls13_cipher_suite!` macro for consistency. - Improved the organization and clarity of the codebase by consolidating feature checks and reducing boilerplate code.
1 parent cd3752c commit 365820c

File tree

20 files changed

+683
-804
lines changed

20 files changed

+683
-804
lines changed

src/hash.rs

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ use alloc::boxed::Box;
33

44
use core::marker::PhantomData;
55
use digest::{Digest, OutputSizeUser};
6-
use rustls::crypto::{self, hash};
76

87
/// Trait to provide hash algorithm for different hash types
98
pub trait HashAlgorithm {
10-
const ALGORITHM: hash::HashAlgorithm;
9+
const ALGORITHM: rustls::crypto::hash::HashAlgorithm;
1110
}
1211

1312
// Generic hash implementation
@@ -22,64 +21,43 @@ impl<H> GenericHash<H> {
2221
};
2322
}
2423

25-
impl<H> hash::Hash for GenericHash<H>
24+
impl<H> rustls::crypto::hash::Hash for GenericHash<H>
2625
where
2726
H: Digest + OutputSizeUser + Clone + Send + Sync + 'static + HashAlgorithm,
2827
{
29-
fn start(&self) -> Box<dyn hash::Context> {
28+
fn start(&self) -> Box<dyn rustls::crypto::hash::Context> {
3029
Box::new(GenericHashContext(H::new()))
3130
}
3231

33-
fn hash(&self, data: &[u8]) -> hash::Output {
34-
hash::Output::new(&H::digest(data)[..])
32+
fn hash(&self, data: &[u8]) -> rustls::crypto::hash::Output {
33+
rustls::crypto::hash::Output::new(&H::digest(data)[..])
3534
}
3635

3736
fn output_len(&self) -> usize {
3837
<H as OutputSizeUser>::output_size()
3938
}
4039

41-
fn algorithm(&self) -> hash::HashAlgorithm {
40+
fn algorithm(&self) -> rustls::crypto::hash::HashAlgorithm {
4241
H::ALGORITHM
4342
}
4443
}
4544

46-
// Implement HashAlgorithm trait for each hash type
47-
#[cfg(feature = "hash-sha224")]
48-
impl HashAlgorithm for ::sha2::Sha224 {
49-
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA224;
50-
}
51-
52-
#[cfg(feature = "hash-sha256")]
53-
impl HashAlgorithm for ::sha2::Sha256 {
54-
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA256;
55-
}
56-
57-
#[cfg(feature = "hash-sha384")]
58-
impl HashAlgorithm for ::sha2::Sha384 {
59-
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA384;
60-
}
61-
62-
#[cfg(feature = "hash-sha512")]
63-
impl HashAlgorithm for ::sha2::Sha512 {
64-
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA512;
65-
}
66-
6745
pub struct GenericHashContext<H>(H);
6846

69-
impl<H> hash::Context for GenericHashContext<H>
47+
impl<H> rustls::crypto::hash::Context for GenericHashContext<H>
7048
where
7149
H: Digest + Clone + Send + Sync + 'static,
7250
{
73-
fn fork_finish(&self) -> hash::Output {
74-
hash::Output::new(&self.0.clone().finalize()[..])
51+
fn fork_finish(&self) -> rustls::crypto::hash::Output {
52+
rustls::crypto::hash::Output::new(&self.0.clone().finalize()[..])
7553
}
7654

77-
fn fork(&self) -> Box<dyn hash::Context> {
55+
fn fork(&self) -> Box<dyn rustls::crypto::hash::Context> {
7856
Box::new(GenericHashContext(self.0.clone()))
7957
}
8058

81-
fn finish(self: Box<Self>) -> hash::Output {
82-
hash::Output::new(&self.0.finalize()[..])
59+
fn finish(self: Box<Self>) -> rustls::crypto::hash::Output {
60+
rustls::crypto::hash::Output::new(&self.0.finalize()[..])
8361
}
8462

8563
fn update(&mut self, data: &[u8]) {
@@ -88,15 +66,23 @@ where
8866
}
8967

9068
/// Macro to generate hash constants
91-
macro_rules! hash_const {
92-
($name:ident, $hash:ty, $feature:literal) => {
93-
#[cfg(feature = $feature)]
94-
pub const $name: &dyn crypto::hash::Hash = &GenericHash::<$hash>::DEFAULT;
69+
macro_rules! impl_hash {
70+
($name:ident, $hash:ty) => {
71+
impl HashAlgorithm for $hash {
72+
const ALGORITHM: rustls::crypto::hash::HashAlgorithm =
73+
rustls::crypto::hash::HashAlgorithm::$name;
74+
}
75+
76+
pub const $name: &dyn rustls::crypto::hash::Hash = &GenericHash::<$hash>::DEFAULT;
9577
};
9678
}
9779

9880
// Generate hash constants using macro
99-
hash_const!(SHA224, ::sha2::Sha224, "hash-sha224");
100-
hash_const!(SHA256, ::sha2::Sha256, "hash-sha256");
101-
hash_const!(SHA384, ::sha2::Sha384, "hash-sha384");
102-
hash_const!(SHA512, ::sha2::Sha512, "hash-sha512");
81+
#[cfg(feature = "hash-sha224")]
82+
impl_hash!(SHA224, ::sha2::Sha224);
83+
#[cfg(feature = "hash-sha256")]
84+
impl_hash!(SHA256, ::sha2::Sha256);
85+
#[cfg(feature = "hash-sha384")]
86+
impl_hash!(SHA384, ::sha2::Sha384);
87+
#[cfg(feature = "hash-sha512")]
88+
impl_hash!(SHA512, ::sha2::Sha512);

src/hmac.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ pub struct GenericHmac<H: HmacHash> {
1414
_phantom: PhantomData<H>,
1515
}
1616

17+
impl<H: HmacHash> GenericHmac<H> {
18+
pub const DEFAULT: Self = Self {
19+
_phantom: PhantomData,
20+
};
21+
}
22+
1723
impl<H> RustlsHmac for GenericHmac<H>
1824
where
1925
H: HmacHash,
@@ -54,17 +60,14 @@ where
5460
}
5561
}
5662

57-
#[cfg(feature = "hash-sha256")]
58-
pub const SHA256: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha256> {
59-
_phantom: PhantomData,
60-
};
61-
62-
#[cfg(feature = "hash-sha384")]
63-
pub const SHA384: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha384> {
64-
_phantom: PhantomData,
65-
};
63+
/// Macro to generate HMAC constants
64+
macro_rules! hmac_const {
65+
($name:ident, $hash:ty) => {
66+
pub const $name: &GenericHmac<$hash> = &GenericHmac::DEFAULT;
67+
};
68+
}
6669

67-
#[cfg(feature = "hash-sha512")]
68-
pub const SHA512: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha512> {
69-
_phantom: PhantomData,
70-
};
70+
// Generate HMAC constants using macro
71+
hmac_const!(SHA256, ::sha2::Sha256);
72+
hmac_const!(SHA384, ::sha2::Sha384);
73+
hmac_const!(SHA512, ::sha2::Sha512);

src/kx/nist.rs

Lines changed: 26 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,35 @@
1-
#[cfg(all(feature = "alloc", feature = "kx-nist"))]
1+
#[cfg(feature = "alloc")]
22
use alloc::boxed::Box;
3-
4-
#[cfg(feature = "kx-nist")]
3+
use core::fmt::Debug;
54
use core::marker::PhantomData;
65

7-
#[cfg(feature = "kx-nist")]
8-
use rustls::{Error, NamedGroup, PeerMisbehaved, crypto};
9-
10-
#[cfg(feature = "kx-nist")]
116
use crypto::{ActiveKeyExchange, SharedSecret, SupportedKxGroup};
12-
13-
#[cfg(feature = "kx-nist")]
147
use elliptic_curve::{
158
Curve, CurveArithmetic, PublicKey,
169
ecdh::EphemeralSecret,
1710
point::PointCompression,
1811
sec1::{FromEncodedPoint, ToEncodedPoint},
1912
};
20-
21-
#[cfg(feature = "kx-nist")]
2213
use rand_core::OsRng;
23-
24-
#[cfg(feature = "kx-nist")]
14+
use rustls::{Error, NamedGroup, PeerMisbehaved, crypto};
2515
use sec1::point::ModulusSize;
2616

27-
#[cfg(feature = "kx-nist")]
28-
use core::fmt::Debug;
29-
30-
#[cfg(feature = "kx-nist")]
3117
pub trait NistCurve: Curve + CurveArithmetic + PointCompression {
3218
const NAMED_GROUP: NamedGroup;
3319
}
3420

35-
#[cfg(all(feature = "kx-nist", feature = "kx-p256"))]
36-
impl NistCurve for ::p256::NistP256 {
37-
const NAMED_GROUP: NamedGroup = NamedGroup::secp256r1;
38-
}
39-
40-
#[cfg(all(feature = "kx-nist", feature = "kx-p384"))]
41-
impl NistCurve for ::p384::NistP384 {
42-
const NAMED_GROUP: NamedGroup = NamedGroup::secp384r1;
43-
}
44-
45-
#[cfg(all(feature = "kx-nist", feature = "kx-p521"))]
46-
impl NistCurve for ::p521::NistP521 {
47-
const NAMED_GROUP: NamedGroup = NamedGroup::secp521r1;
48-
}
49-
50-
#[cfg(feature = "kx-nist")]
5121
#[derive(Debug)]
5222
pub struct NistKxGroup<C>(PhantomData<C>)
5323
where
5424
C: NistCurve;
5525

56-
#[cfg(feature = "kx-nist")]
26+
impl<C> NistKxGroup<C>
27+
where
28+
C: NistCurve,
29+
{
30+
const DEFAULT: Self = Self(PhantomData);
31+
}
32+
5733
impl<C> SupportedKxGroup for NistKxGroup<C>
5834
where
5935
<C as CurveArithmetic>::AffinePoint: FromEncodedPoint<C> + ToEncodedPoint<C>,
@@ -75,7 +51,6 @@ where
7551
}
7652
}
7753

78-
#[cfg(feature = "kx-nist")]
7954
#[allow(non_camel_case_types)]
8055
pub struct NistKeyExchange<C>
8156
where
@@ -85,12 +60,11 @@ where
8560
pub_key: Box<[u8]>,
8661
}
8762

88-
#[cfg(feature = "kx-nist")]
89-
impl<C: NistCurve> ActiveKeyExchange for NistKeyExchange<C>
63+
impl<C> ActiveKeyExchange for NistKeyExchange<C>
9064
where
91-
<C as CurveArithmetic>::AffinePoint: FromEncodedPoint<C>,
65+
<C as CurveArithmetic>::AffinePoint: FromEncodedPoint<C> + ToEncodedPoint<C>,
9266
<C as elliptic_curve::Curve>::FieldBytesSize: ModulusSize,
93-
<C as CurveArithmetic>::AffinePoint: ToEncodedPoint<C>,
67+
C: NistCurve,
9468
{
9569
fn complete(self: Box<Self>, peer: &[u8]) -> Result<SharedSecret, Error> {
9670
let their_pub = PublicKey::<C>::from_sec1_bytes(peer)
@@ -112,11 +86,21 @@ where
11286
}
11387
}
11488

89+
macro_rules! impl_nist_curve {
90+
($ty:ty, $named_group:expr, $const_name:ident) => {
91+
impl NistCurve for $ty {
92+
const NAMED_GROUP: NamedGroup = $named_group;
93+
}
94+
95+
pub const $const_name: NistKxGroup<$ty> = NistKxGroup::DEFAULT;
96+
};
97+
}
98+
11599
#[cfg(feature = "kx-p256")]
116-
pub const SEC_P256_R1: NistKxGroup<::p256::NistP256> = NistKxGroup(PhantomData);
100+
impl_nist_curve!(::p256::NistP256, NamedGroup::secp256r1, SEC_P256_R1);
117101

118102
#[cfg(feature = "kx-p384")]
119-
pub const SEC_P384_R1: NistKxGroup<::p384::NistP384> = NistKxGroup(PhantomData);
103+
impl_nist_curve!(::p384::NistP384, NamedGroup::secp384r1, SEC_P384_R1);
120104

121105
#[cfg(feature = "kx-p521")]
122-
pub const SEC_P521_R1: NistKxGroup<::p521::NistP521> = NistKxGroup(PhantomData);
106+
impl_nist_curve!(::p521::NistP521, NamedGroup::secp521r1, SEC_P521_R1);

src/lib.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,16 @@ pub fn provider() -> CryptoProvider {
5656

5757
impl SecureRandom for Provider {
5858
fn fill(&self, #[allow(unused_variables)] bytes: &mut [u8]) -> Result<(), GetRandomFailed> {
59-
#[cfg(feature = "rand")]
60-
{
61-
use rand_core::TryRngCore;
62-
rand_core::OsRng
63-
.try_fill_bytes(bytes)
64-
.map_err(|_| GetRandomFailed)
65-
}
66-
67-
#[cfg(not(feature = "rand"))]
68-
{
69-
Err(GetRandomFailed)
70-
}
59+
feature_eval_expr!(
60+
[feature = "rand"],
61+
{
62+
use rand_core::TryRngCore;
63+
rand_core::OsRng
64+
.try_fill_bytes(bytes)
65+
.map_err(|_| GetRandomFailed)
66+
},
67+
else Err(GetRandomFailed)
68+
)
7169
}
7270
}
7371

@@ -76,30 +74,17 @@ impl KeyProvider for Provider {
7674
&self,
7775
#[allow(unused_variables)] key_der: PrivateKeyDer<'static>,
7876
) -> Result<Arc<dyn SigningKey>, rustls::Error> {
79-
#[cfg(feature = "sign")]
80-
{
81-
sign::any_supported_type(&key_der)
82-
}
83-
#[cfg(not(feature = "sign"))]
84-
{
85-
Err(rustls::Error::General("not key providers supported".into()))
86-
}
77+
feature_eval_expr!(
78+
[feature = "sign"],
79+
sign::any_supported_type(&key_der),
80+
else Err(rustls::Error::General("not key providers supported".into()))
81+
)
8782
}
8883
}
8984

9085
pub const ALL_CIPHER_SUITES: &[SupportedCipherSuite] = misc::const_concat_slices!(
9186
SupportedCipherSuite,
92-
{
93-
#[cfg(feature = "tls12")]
94-
{
95-
tls12::suites::TLS12_SUITES
96-
}
97-
98-
#[cfg(not(feature = "tls12"))]
99-
{
100-
&[]
101-
}
102-
},
87+
feature_slice!([feature = "tls12"], tls12::suites::TLS12_SUITES),
10388
tls13::suites::TLS13_SUITES
10489
);
10590

0 commit comments

Comments
 (0)