Skip to content

Commit 069b79e

Browse files
Enhance cryptographic implementations with generic hash and HMAC structures
- Introduced GenericHash and GenericHmac for flexible hash and HMAC handling. - Updated NIST curve key exchange implementations for better structure and clarity. - Added support for additional ECDSA signature algorithms. - Improved RSA verification with new traits and constants for PKCS1 and PSS schemes.
1 parent 72311f3 commit 069b79e

File tree

7 files changed

+619
-332
lines changed

7 files changed

+619
-332
lines changed

src/hash.rs

Lines changed: 77 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,97 @@
11
#[cfg(feature = "alloc")]
22
use alloc::boxed::Box;
3+
use const_default::ConstDefault;
34

5+
use core::marker::PhantomData;
46
use digest::{Digest, OutputSizeUser};
5-
use preinterpret::preinterpret;
67
use rustls::crypto::{self, hash};
78

8-
macro_rules! impl_hash {
9-
($name:ident, $ty:ty, $algo:ty) => {
10-
preinterpret! {
11-
[!set! #hash_name = [!ident! Hash_ $name]]
12-
[!set! #hash_content_name = [!ident! HashContent_ $name]]
9+
/// Trait to provide hash algorithm for different hash types
10+
pub trait HashAlgorithm {
11+
const ALGORITHM: hash::HashAlgorithm;
12+
}
13+
14+
// Generic hash implementation
15+
#[derive(ConstDefault)]
16+
pub struct GenericHash<H> {
17+
_phantom: PhantomData<H>,
18+
}
19+
20+
impl<H> hash::Hash for GenericHash<H>
21+
where
22+
H: Digest + OutputSizeUser + Clone + Send + Sync + 'static + HashAlgorithm,
23+
{
24+
fn start(&self) -> Box<dyn hash::Context> {
25+
Box::new(GenericHashContext(H::new()))
26+
}
27+
28+
fn hash(&self, data: &[u8]) -> hash::Output {
29+
hash::Output::new(&H::digest(data)[..])
30+
}
1331

14-
#[allow(non_camel_case_types)]
15-
pub struct #hash_name;
32+
fn output_len(&self) -> usize {
33+
<H as OutputSizeUser>::output_size()
34+
}
1635

17-
impl hash::Hash for #hash_name {
18-
fn start(&self) -> Box<dyn hash::Context> {
19-
Box::new(#hash_content_name($ty::new()))
20-
}
36+
fn algorithm(&self) -> hash::HashAlgorithm {
37+
H::ALGORITHM
38+
}
39+
}
2140

22-
fn hash(&self, data: &[u8]) -> hash::Output {
23-
hash::Output::new(&$ty::digest(data)[..])
24-
}
41+
// Implement HashAlgorithm trait for each hash type
42+
#[cfg(feature = "hash-sha224")]
43+
impl HashAlgorithm for ::sha2::Sha224 {
44+
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA224;
45+
}
46+
47+
#[cfg(feature = "hash-sha256")]
48+
impl HashAlgorithm for ::sha2::Sha256 {
49+
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA256;
50+
}
2551

26-
fn output_len(&self) -> usize {
27-
<$ty as OutputSizeUser>::output_size()
28-
}
52+
#[cfg(feature = "hash-sha384")]
53+
impl HashAlgorithm for ::sha2::Sha384 {
54+
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA384;
55+
}
2956

30-
fn algorithm(&self) -> hash::HashAlgorithm {
31-
$algo
32-
}
33-
}
57+
#[cfg(feature = "hash-sha512")]
58+
impl HashAlgorithm for ::sha2::Sha512 {
59+
const ALGORITHM: hash::HashAlgorithm = hash::HashAlgorithm::SHA512;
60+
}
3461

35-
#[allow(non_camel_case_types)]
36-
pub struct #hash_content_name($ty);
62+
pub struct GenericHashContext<H>(H);
3763

38-
impl hash::Context for #hash_content_name {
39-
fn fork_finish(&self) -> hash::Output {
40-
hash::Output::new(&self.0.clone().finalize()[..])
41-
}
64+
impl<H> hash::Context for GenericHashContext<H>
65+
where
66+
H: Digest + Clone + Send + Sync + 'static,
67+
{
68+
fn fork_finish(&self) -> hash::Output {
69+
hash::Output::new(&self.0.clone().finalize()[..])
70+
}
4271

43-
fn fork(&self) -> Box<dyn hash::Context> {
44-
Box::new(#hash_content_name(self.0.clone()))
45-
}
72+
fn fork(&self) -> Box<dyn hash::Context> {
73+
Box::new(GenericHashContext(self.0.clone()))
74+
}
4675

47-
fn finish(self: Box<Self>) -> hash::Output {
48-
hash::Output::new(&self.0.finalize()[..])
49-
}
76+
fn finish(self: Box<Self>) -> hash::Output {
77+
hash::Output::new(&self.0.finalize()[..])
78+
}
5079

51-
fn update(&mut self, data: &[u8]) {
52-
self.0.update(data);
53-
}
54-
}
80+
fn update(&mut self, data: &[u8]) {
81+
self.0.update(data);
82+
}
83+
}
5584

56-
pub const $name: &dyn crypto::hash::Hash = &#hash_name;
57-
}
85+
/// Macro to generate hash constants
86+
macro_rules! hash_const {
87+
($name:ident, $hash:ty, $feature:literal) => {
88+
#[cfg(feature = $feature)]
89+
pub const $name: &dyn crypto::hash::Hash = &GenericHash::<$hash>::DEFAULT;
5890
};
5991
}
6092

61-
#[cfg(feature = "hash-sha224")]
62-
impl_hash! {SHA224, ::sha2::Sha224, hash::HashAlgorithm::SHA224}
63-
#[cfg(feature = "hash-sha256")]
64-
impl_hash! {SHA256, ::sha2::Sha256, hash::HashAlgorithm::SHA256}
65-
#[cfg(feature = "hash-sha384")]
66-
impl_hash! {SHA384, ::sha2::Sha384, hash::HashAlgorithm::SHA384}
67-
#[cfg(feature = "hash-sha512")]
68-
impl_hash! {SHA512, ::sha2::Sha512, hash::HashAlgorithm::SHA512}
93+
// Generate hash constants using macro
94+
hash_const!(SHA224, ::sha2::Sha224, "hash-sha224");
95+
hash_const!(SHA256, ::sha2::Sha256, "hash-sha256");
96+
hash_const!(SHA384, ::sha2::Sha384, "hash-sha384");
97+
hash_const!(SHA512, ::sha2::Sha512, "hash-sha512");

src/hmac.rs

Lines changed: 60 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,70 @@
11
#[cfg(feature = "alloc")]
22
use alloc::boxed::Box;
33

4-
use crypto_common::KeyInit;
4+
use core::marker::PhantomData;
55
use crypto_common::OutputSizeUser;
6-
use preinterpret::preinterpret;
7-
use rustls::crypto::hmac::{Hmac, Key, Tag};
8-
9-
macro_rules! impl_hmac {
10-
(
11-
$name: ident,
12-
$ty: ty
13-
) => {
14-
preinterpret! {
15-
[!set! #hmac_type_name = [!ident! Hmac_ $name]]
16-
[!set! #hmac_key_type_name = [!ident! HmacKey_ $name]]
17-
18-
#[allow(non_camel_case_types)]
19-
pub struct #hmac_type_name;
20-
21-
impl Hmac for #hmac_type_name {
22-
fn with_key(&self, key: &[u8]) -> Box<dyn Key> {
23-
Box::new(#hmac_key_type_name(
24-
::hmac::Hmac::<$ty>::new_from_slice(key).expect("Invalid key length for HMAC"),
25-
))
26-
}
27-
28-
fn hash_output_len(&self) -> usize {
29-
$ty::output_size()
30-
}
31-
}
32-
33-
#[allow(non_camel_case_types)]
34-
pub struct #hmac_key_type_name(::hmac::Hmac<$ty>);
35-
36-
impl Key for #hmac_key_type_name {
37-
fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> Tag {
38-
use ::hmac::Mac;
39-
let mut ctx = self.0.clone();
40-
ctx.update(first);
41-
for m in middle {
42-
ctx.update(m);
43-
}
44-
ctx.update(last);
45-
Tag::new(&ctx.finalize().into_bytes()[..])
46-
}
47-
48-
fn tag_len(&self) -> usize {
49-
$ty::output_size()
50-
}
51-
}
52-
pub const $name: &dyn Hmac = &#hmac_type_name;
6+
use hmac::{EagerHash, Hmac};
7+
use rustls::crypto::hmac::{Hmac as RustlsHmac, Key, Tag};
8+
9+
pub trait HmacHash: EagerHash + Send + Sync + 'static {}
10+
11+
impl<T> HmacHash for T where T: EagerHash + Send + Sync + 'static {}
12+
13+
pub struct GenericHmac<H: HmacHash> {
14+
_phantom: PhantomData<H>,
15+
}
16+
17+
impl<H> RustlsHmac for GenericHmac<H>
18+
where
19+
H: HmacHash,
20+
<H as EagerHash>::Core: Send + Sync,
21+
{
22+
fn with_key(&self, key: &[u8]) -> Box<dyn Key> {
23+
Box::new(GenericHmacKey::<H>(
24+
<::hmac::Hmac<H> as hmac::KeyInit>::new_from_slice(key)
25+
.expect("Invalid key length for HMAC"),
26+
))
27+
}
28+
29+
fn hash_output_len(&self) -> usize {
30+
<H as OutputSizeUser>::output_size()
31+
}
32+
}
33+
34+
pub struct GenericHmacKey<H: HmacHash>(Hmac<H>);
35+
36+
impl<H> Key for GenericHmacKey<H>
37+
where
38+
H: HmacHash,
39+
<H as EagerHash>::Core: Send + Sync,
40+
{
41+
fn sign_concat(&self, first: &[u8], middle: &[&[u8]], last: &[u8]) -> Tag {
42+
use ::hmac::Mac;
43+
let mut ctx = self.0.clone();
44+
ctx.update(first);
45+
for m in middle {
46+
ctx.update(m);
5347
}
54-
};
48+
ctx.update(last);
49+
Tag::new(&ctx.finalize().into_bytes()[..])
50+
}
51+
52+
fn tag_len(&self) -> usize {
53+
<H as OutputSizeUser>::output_size()
54+
}
5555
}
5656

5757
#[cfg(feature = "hash-sha256")]
58-
impl_hmac! {SHA256, ::sha2::Sha256}
58+
pub const SHA256: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha256> {
59+
_phantom: PhantomData,
60+
};
61+
5962
#[cfg(feature = "hash-sha384")]
60-
impl_hmac! {SHA384, ::sha2::Sha384}
63+
pub const SHA384: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha384> {
64+
_phantom: PhantomData,
65+
};
66+
6167
#[cfg(feature = "hash-sha512")]
62-
impl_hmac! {SHA512, ::sha2::Sha512}
68+
pub const SHA512: &dyn RustlsHmac = &GenericHmac::<::sha2::Sha512> {
69+
_phantom: PhantomData,
70+
};

src/kx.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
66
#[cfg(feature = "kx-x25519")]
77
&x25519::X25519,
88
#[cfg(feature = "kx-p256")]
9-
&nist::SecP256R1,
9+
&nist::SEC_P256_R1,
1010
#[cfg(feature = "kx-p384")]
11-
&nist::SecP384R1,
11+
&nist::SEC_P384_R1,
1212
#[cfg(feature = "kx-p521")]
13-
&nist::SecP521R1,
13+
&nist::SEC_P521_R1,
1414
];
1515

1616
#[cfg(feature = "kx-nist")]

0 commit comments

Comments
 (0)