Skip to content

Commit 80eca79

Browse files
committed
pss, oaep: remove DynDigest
I'm not sure I see why usage of `DynDigest` was originally introduced. The need to make the Digest also Send is hard to use in downstream crates. I don't believe this was necessary, this removes its use and makes the consumer specify the Digest types.
1 parent 7ae85c1 commit 80eca79

File tree

6 files changed

+210
-144
lines changed

6 files changed

+210
-144
lines changed

src/algorithms/mgf.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
//! Mask generation function common to both PSS and OAEP padding
22
3-
use digest::{Digest, DynDigest, FixedOutputReset};
3+
use digest::{Digest, FixedOutputReset};
44

55
/// Mask generation function.
66
///
77
/// Panics if out is larger than 2**32. This is in accordance with RFC 8017 - PKCS #1 B.2.1
8-
pub(crate) fn mgf1_xor(out: &mut [u8], digest: &mut dyn DynDigest, seed: &[u8]) {
8+
pub(crate) fn mgf1_xor<D>(out: &mut [u8], digest: &mut D, seed: &[u8])
9+
where
10+
D: Digest + FixedOutputReset,
11+
{
912
let mut counter = [0u8; 4];
1013
let mut i = 0;
1114

@@ -17,7 +20,7 @@ pub(crate) fn mgf1_xor(out: &mut [u8], digest: &mut dyn DynDigest, seed: &[u8])
1720
digest_input[0..seed.len()].copy_from_slice(seed);
1821
digest_input[seed.len()..].copy_from_slice(&counter);
1922

20-
digest.update(digest_input.as_slice());
23+
Digest::update(digest, digest_input.as_slice());
2124
let digest_output = &*digest.finalize_reset();
2225
let mut j = 0;
2326
loop {

src/algorithms/oaep.rs

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use alloc::boxed::Box;
44
use alloc::vec::Vec;
55

6-
use digest::{Digest, DynDigest, FixedOutputReset};
6+
use digest::{Digest, FixedOutputReset};
77
use rand_core::TryCryptoRng;
88
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
99
use zeroize::Zeroizing;
@@ -57,22 +57,27 @@ fn encrypt_internal<R: TryCryptoRng + ?Sized, MGF: FnMut(&mut [u8], &mut [u8])>(
5757
///
5858
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
5959
#[inline]
60-
pub(crate) fn oaep_encrypt<R: TryCryptoRng + ?Sized>(
60+
pub(crate) fn oaep_encrypt<R, D, MGD>(
6161
rng: &mut R,
6262
msg: &[u8],
63-
digest: &mut dyn DynDigest,
64-
mgf_digest: &mut dyn DynDigest,
63+
digest: &mut D,
64+
mgf_digest: &mut MGD,
6565
label: Option<Box<[u8]>>,
6666
k: usize,
67-
) -> Result<Zeroizing<Vec<u8>>> {
68-
let h_size = digest.output_size();
67+
) -> Result<Zeroizing<Vec<u8>>>
68+
where
69+
R: TryCryptoRng + ?Sized,
70+
D: Digest + FixedOutputReset,
71+
MGD: Digest + FixedOutputReset,
72+
{
73+
let h_size = <D as Digest>::output_size();
6974

7075
let label = label.unwrap_or_default();
7176
if label.len() as u64 >= MAX_LABEL_LEN {
7277
return Err(Error::LabelTooLong);
7378
}
7479

75-
digest.update(&label);
80+
Digest::update(digest, &label);
7681
let p_hash = digest.finalize_reset();
7782

7883
encrypt_internal(rng, msg, &p_hash, h_size, k, |seed, db| {
@@ -89,16 +94,17 @@ pub(crate) fn oaep_encrypt<R: TryCryptoRng + ?Sized>(
8994
///
9095
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
9196
#[inline]
92-
pub(crate) fn oaep_encrypt_digest<
93-
R: TryCryptoRng + ?Sized,
94-
D: Digest,
95-
MGD: Digest + FixedOutputReset,
96-
>(
97+
pub(crate) fn oaep_encrypt_digest<R, D, MGD>(
9798
rng: &mut R,
9899
msg: &[u8],
99100
label: Option<Box<[u8]>>,
100101
k: usize,
101-
) -> Result<Zeroizing<Vec<u8>>> {
102+
) -> Result<Zeroizing<Vec<u8>>>
103+
where
104+
R: TryCryptoRng + ?Sized,
105+
D: Digest,
106+
MGD: Digest + FixedOutputReset,
107+
{
102108
let h_size = <D as Digest>::output_size();
103109

104110
let label = label.unwrap_or_default();
@@ -126,21 +132,25 @@ pub(crate) fn oaep_encrypt_digest<
126132
///
127133
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
128134
#[inline]
129-
pub(crate) fn oaep_decrypt(
135+
pub(crate) fn oaep_decrypt<D, MGD>(
130136
em: &mut [u8],
131-
digest: &mut dyn DynDigest,
132-
mgf_digest: &mut dyn DynDigest,
137+
digest: &mut D,
138+
mgf_digest: &mut MGD,
133139
label: Option<Box<[u8]>>,
134140
k: usize,
135-
) -> Result<Vec<u8>> {
136-
let h_size = digest.output_size();
141+
) -> Result<Vec<u8>>
142+
where
143+
D: Digest + FixedOutputReset,
144+
MGD: Digest + FixedOutputReset,
145+
{
146+
let h_size = <D as Digest>::output_size();
137147

138148
let label = label.unwrap_or_default();
139149
if label.len() as u64 >= MAX_LABEL_LEN {
140150
return Err(Error::Decryption);
141151
}
142152

143-
digest.update(&label);
153+
Digest::update(digest, &label);
144154

145155
let expected_p_hash = digest.finalize_reset();
146156

@@ -168,11 +178,15 @@ pub(crate) fn oaep_decrypt(
168178
///
169179
/// [PKCS#1 OAEP]: https://datatracker.ietf.org/doc/html/rfc8017#section-7.1
170180
#[inline]
171-
pub(crate) fn oaep_decrypt_digest<D: Digest, MGD: Digest + FixedOutputReset>(
181+
pub(crate) fn oaep_decrypt_digest<D, MGD>(
172182
em: &mut [u8],
173183
label: Option<Box<[u8]>>,
174184
k: usize,
175-
) -> Result<Vec<u8>> {
185+
) -> Result<Vec<u8>>
186+
where
187+
D: Digest,
188+
MGD: Digest + FixedOutputReset,
189+
{
176190
let h_size = <D as Digest>::output_size();
177191

178192
let label = label.unwrap_or_default();

src/algorithms/pss.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,23 @@
1010
//! [RFC8017 § 8.1]: https://datatracker.ietf.org/doc/html/rfc8017#section-8.1
1111
1212
use alloc::vec::Vec;
13-
use digest::{Digest, DynDigest, FixedOutputReset};
13+
use digest::{Digest, FixedOutputReset};
1414
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
1515

1616
use super::mgf::{mgf1_xor, mgf1_xor_digest};
1717
use crate::errors::{Error, Result};
1818

19-
pub(crate) fn emsa_pss_encode(
19+
pub(crate) fn emsa_pss_encode<D>(
2020
m_hash: &[u8],
2121
em_bits: usize,
2222
salt: &[u8],
23-
hash: &mut dyn DynDigest,
24-
) -> Result<Vec<u8>> {
23+
hash: &mut D,
24+
) -> Result<Vec<u8>>
25+
where
26+
D: Digest + FixedOutputReset,
27+
{
2528
// See [1], section 9.1.1
26-
let h_len = hash.output_size();
29+
let h_len = <D as Digest>::output_size();
2730
let s_len = salt.len();
2831
let em_len = em_bits.div_ceil(8);
2932

@@ -59,9 +62,9 @@ pub(crate) fn emsa_pss_encode(
5962
// 6. Let H = Hash(M'), an octet string of length h_len.
6063
let prefix = [0u8; 8];
6164

62-
hash.update(&prefix);
63-
hash.update(m_hash);
64-
hash.update(salt);
65+
Digest::update(hash, &prefix);
66+
Digest::update(hash, m_hash);
67+
Digest::update(hash, salt);
6568

6669
let hashed = hash.finalize_reset();
6770
h.copy_from_slice(&hashed);
@@ -267,17 +270,20 @@ fn emsa_pss_get_salt_len(db: &[u8], em_len: usize, h_len: usize) -> (usize, Choi
267270
(result_len as usize, final_valid)
268271
}
269272

270-
pub(crate) fn emsa_pss_verify(
273+
pub(crate) fn emsa_pss_verify<D>(
271274
m_hash: &[u8],
272275
em: &mut [u8],
273276
s_len: Option<usize>,
274-
hash: &mut dyn DynDigest,
277+
hash: &mut D,
275278
key_bits: usize,
276-
) -> Result<()> {
279+
) -> Result<()>
280+
where
281+
D: Digest + FixedOutputReset,
282+
{
277283
let em_bits = key_bits - 1;
278284
let em_len = em_bits.div_ceil(8);
279285
let key_len = key_bits.div_ceil(8);
280-
let h_len = hash.output_size();
286+
let h_len = <D as Digest>::output_size();
281287

282288
let em = &mut em[key_len - em_len..];
283289

@@ -308,9 +314,9 @@ pub(crate) fn emsa_pss_verify(
308314
// 13. Let H' = Hash(M'), an octet string of length hLen.
309315
let prefix = [0u8; 8];
310316

311-
hash.update(&prefix[..]);
312-
hash.update(m_hash);
313-
hash.update(salt);
317+
Digest::update(hash, &prefix[..]);
318+
Digest::update(hash, m_hash);
319+
Digest::update(hash, salt);
314320
let h0 = hash.finalize_reset();
315321

316322
// 14. If H = H', output "consistent." Otherwise, output "inconsistent."

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@
3434
//!
3535
//! // Encrypt
3636
//! let data = b"hello world";
37-
//! let padding = Oaep::new::<Sha256>();
37+
//! let padding = Oaep::<Sha256>::new();
3838
//! let enc_data = public_key.encrypt(&mut rng, padding, &data[..]).expect("failed to encrypt");
3939
//! assert_ne!(&data[..], &enc_data[..]);
4040
//!
4141
//! // Decrypt
42-
//! let padding = Oaep::new::<Sha256>();
42+
//! let padding = Oaep::<Sha256>::new();
4343
//! let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt");
4444
//! assert_eq!(&data[..], &dec_data[..]);
4545
//! ```

0 commit comments

Comments
 (0)