Skip to content

Commit 78ea9cb

Browse files
authored
Impl ZeroizeOnDrop for RsaPrivateKey+newtypes (#311)
`RsaPrivateKey` self-zeroizes on drop, so add the `ZeroizeOnDrop` marker trait to `RsaPrivateKey` and all newtypes thereof, i.e. `DecryptingKey` and `SigningKey` for the various padding modes. This also removes the `Zeroize` impl on `RsaPrivateKey`, since it self-zeroizes on `Drop`, and allowing `Zeroize` might accidentally permit use-after-zeroize vulnerabilities.
1 parent b1151df commit 78ea9cb

File tree

5 files changed

+27
-19
lines changed

5 files changed

+27
-19
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ digest = { version = "0.10.5", default-features = false, features = ["alloc", "o
2525
pkcs1 = { version = "0.7.5", default-features = false, features = ["alloc", "pkcs8"] }
2626
pkcs8 = { version = "0.10.2", default-features = false, features = ["alloc"] }
2727
signature = { version = "2", default-features = false , features = ["digest", "rand_core"] }
28-
zeroize = { version = "1", features = ["alloc"] }
28+
zeroize = { version = "1.5", features = ["alloc"] }
2929

3030
# optional dependencies
3131
serde = { version = "1.0.103", optional = true, default-features = false, features = ["derive"] }

src/key.rs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use num_traits::{FromPrimitive, One, ToPrimitive};
1111
use rand_core::CryptoRngCore;
1212
#[cfg(feature = "serde")]
1313
use serde::{Deserialize, Serialize};
14-
use zeroize::Zeroize;
14+
use zeroize::{Zeroize, ZeroizeOnDrop};
1515

1616
use crate::algorithms::generate::generate_multi_prime_key_with_exp;
1717
use crate::dummy_rng::DummyRng;
@@ -61,22 +61,11 @@ impl Hash for RsaPrivateKey {
6161
}
6262
}
6363

64-
impl Zeroize for RsaPrivateKey {
65-
fn zeroize(&mut self) {
66-
self.d.zeroize();
67-
for prime in self.primes.iter_mut() {
68-
prime.zeroize();
69-
}
70-
self.primes.clear();
71-
if self.precomputed.is_some() {
72-
self.precomputed.take().unwrap().zeroize();
73-
}
74-
}
75-
}
76-
7764
impl Drop for RsaPrivateKey {
7865
fn drop(&mut self) {
79-
self.zeroize();
66+
self.d.zeroize();
67+
self.primes.zeroize();
68+
self.precomputed.zeroize();
8069
}
8170
}
8271

@@ -87,6 +76,8 @@ impl Deref for RsaPrivateKey {
8776
}
8877
}
8978

79+
impl ZeroizeOnDrop for RsaPrivateKey {}
80+
9081
#[derive(Debug, Clone)]
9182
pub(crate) struct PrecomputedValues {
9283
/// D mod (P-1)

src/oaep.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
//! # Usage
44
//!
55
//! See [code example in the toplevel rustdoc](../index.html#oaep-encryption).
6+
67
use alloc::boxed::Box;
78
use alloc::string::{String, ToString};
89
use alloc::vec::Vec;
910
use core::fmt;
1011
use core::marker::PhantomData;
11-
use rand_core::CryptoRngCore;
1212

1313
use digest::{Digest, DynDigest, FixedOutputReset};
1414
use num_bigint::BigUint;
15-
use zeroize::Zeroizing;
15+
use rand_core::CryptoRngCore;
16+
use zeroize::{ZeroizeOnDrop, Zeroizing};
1617

1718
use crate::algorithms::oaep::*;
1819
use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
@@ -411,6 +412,13 @@ where
411412
}
412413
}
413414

415+
impl<D, MGD> ZeroizeOnDrop for DecryptingKey<D, MGD>
416+
where
417+
D: Digest,
418+
MGD: Digest + FixedOutputReset,
419+
{
420+
}
421+
414422
#[cfg(test)]
415423
mod tests {
416424
use crate::key::{RsaPrivateKey, RsaPublicKey};

src/pkcs1v15.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use signature::{
2424
DigestSigner, DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner,
2525
SignatureEncoding, Signer, Verifier,
2626
};
27-
use zeroize::Zeroizing;
27+
use zeroize::{ZeroizeOnDrop, Zeroizing};
2828

2929
use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
3030
use crate::algorithms::pkcs1v15::*;
@@ -418,6 +418,8 @@ where
418418
}
419419
}
420420

421+
impl<D> ZeroizeOnDrop for SigningKey<D> where D: Digest {}
422+
421423
impl<D> Signer<Signature> for SigningKey<D>
422424
where
423425
D: Digest,
@@ -731,6 +733,8 @@ impl EncryptingKeypair for DecryptingKey {
731733
}
732734
}
733735

736+
impl ZeroizeOnDrop for DecryptingKey {}
737+
734738
mod oid {
735739
use const_oid::ObjectIdentifier;
736740

src/pss.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use signature::{
3030
hazmat::{PrehashVerifier, RandomizedPrehashSigner},
3131
DigestVerifier, Keypair, RandomizedDigestSigner, RandomizedSigner, SignatureEncoding, Verifier,
3232
};
33+
use zeroize::ZeroizeOnDrop;
3334

3435
use crate::algorithms::pad::{uint_to_be_pad, uint_to_zeroizing_be_pad};
3536
use crate::algorithms::pss::*;
@@ -483,6 +484,8 @@ where
483484
}
484485
}
485486

487+
impl<D> ZeroizeOnDrop for SigningKey<D> where D: Digest {}
488+
486489
/// Signing key for producing "blinded" RSASSA-PSS signatures as described in
487490
/// [draft-irtf-cfrg-rsa-blind-signatures](https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/).
488491
#[derive(Debug, Clone)]
@@ -656,6 +659,8 @@ where
656659
}
657660
}
658661

662+
impl<D> ZeroizeOnDrop for BlindedSigningKey<D> where D: Digest {}
663+
659664
/// Verifying key for checking the validity of RSASSA-PSS signatures as
660665
/// described in [RFC8017 § 8.1].
661666
///

0 commit comments

Comments
 (0)