diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-09-26 13:00:06 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-09-26 13:39:58 +0200 |
commit | 55b16c4904b9875a68193ca2a15f4a61ad05d9ac (patch) | |
tree | 9e5ee29d848713d0414683ee172d07fc1a80bb66 | |
parent | c62fb995baee091ef6009a06068b88421d43a994 (diff) |
openpgp: Heap-allocate the ed25519_dalek::SigningKey.
- Stack allocated values may be moved freely by the Rust compiler
leaving traces of the secret laying around the stack. Zeroize
doesn't help with that. Heap allocate the secret instead, which
prevents the moves.
-rw-r--r-- | openpgp/src/crypto/backend/cng/asymmetric.rs | 18 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/asymmetric.rs | 18 |
2 files changed, 20 insertions, 16 deletions
diff --git a/openpgp/src/crypto/backend/cng/asymmetric.rs b/openpgp/src/crypto/backend/cng/asymmetric.rs index a681b2a5..027725bc 100644 --- a/openpgp/src/crypto/backend/cng/asymmetric.rs +++ b/openpgp/src/crypto/backend/cng/asymmetric.rs @@ -8,7 +8,7 @@ use crate::{Error, Result}; use crate::crypto::asymmetric::KeyPair; use crate::crypto::backend::interface::Asymmetric; -use crate::crypto::mem::{Protected, zero_stack}; +use crate::crypto::mem::Protected; use crate::crypto::mpi::{self, MPI, ProtectedMPI}; use crate::crypto::SessionKey; use crate::crypto::{pad, pad_at_least, pad_truncating}; @@ -22,7 +22,7 @@ use win_crypto_ng as cng; const CURVE25519_SIZE: usize = 32; -impl TryFrom<&Protected> for ed25519_dalek::SigningKey { +impl TryFrom<&Protected> for Box<ed25519_dalek::SigningKey> { type Error = anyhow::Error; fn try_from(value: &Protected) -> Result<Self> { @@ -30,9 +30,11 @@ impl TryFrom<&Protected> for ed25519_dalek::SigningKey { return Err(crate::Error::InvalidArgument( "Bad Ed25519 secret length".into()).into()); } - Ok(Self::from_bytes(value.as_ref().try_into().map_err(|e: std::array::TryFromSliceError| { - Error::InvalidKey(e.to_string()) - })?)) + Ok(Box::new(ed25519_dalek::SigningKey::from_bytes( + value.as_ref().try_into().map_err( + |e: std::array::TryFromSliceError| { + Error::InvalidKey(e.to_string()) + })?))) } } @@ -122,7 +124,7 @@ impl Asymmetric for super::Backend { fn ed25519_derive_public(secret: &Protected) -> Result<[u8; 32]> { use ed25519_dalek::SigningKey; - let secret: SigningKey = secret.try_into()?; + let secret: Box<SigningKey> = secret.try_into()?; let public = secret.verifying_key(); Ok(public.to_bytes()) } @@ -130,8 +132,8 @@ impl Asymmetric for super::Backend { fn ed25519_sign(secret: &Protected, _public: &[u8; 32], digest: &[u8]) -> Result<[u8; 64]> { use ed25519_dalek::{SigningKey, Signer}; - let pair: SigningKey = secret.try_into()?; - Ok(zero_stack::<256, _>(pair.sign(digest)).to_bytes().try_into()?) + let secret: Box<SigningKey> = secret.try_into()?; + Ok(secret.sign(digest).to_bytes().try_into()?) } fn ed25519_verify(public: &[u8; 32], digest: &[u8], signature: &[u8; 64]) diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index d0d199f5..5bee9ecd 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -14,7 +14,7 @@ use rsa::{Pkcs1v15Encrypt, RsaPublicKey, RsaPrivateKey, Pkcs1v15Sign}; use crate::{Error, Result}; use crate::crypto::asymmetric::KeyPair; use crate::crypto::backend::interface::Asymmetric; -use crate::crypto::mem::{Protected, zero_stack}; +use crate::crypto::mem::Protected; use crate::crypto::mpi::{self, MPI, ProtectedMPI}; use crate::crypto::SessionKey; use crate::crypto::pad_truncating; @@ -26,7 +26,7 @@ use super::GenericArrayExt; const CURVE25519_SIZE: usize = 32; -impl TryFrom<&Protected> for ed25519_dalek::SigningKey { +impl TryFrom<&Protected> for Box<ed25519_dalek::SigningKey> { type Error = anyhow::Error; fn try_from(value: &Protected) -> Result<Self> { @@ -34,9 +34,11 @@ impl TryFrom<&Protected> for ed25519_dalek::SigningKey { return Err(crate::Error::InvalidArgument( "Bad Ed25519 secret length".into()).into()); } - Ok(Self::from_bytes(value.as_ref().try_into().map_err(|e: std::array::TryFromSliceError| { - Error::InvalidKey(e.to_string()) - })?)) + Ok(Box::new(ed25519_dalek::SigningKey::from_bytes( + value.as_ref().try_into().map_err( + |e: std::array::TryFromSliceError| { + Error::InvalidKey(e.to_string()) + })?))) } } @@ -110,7 +112,7 @@ impl Asymmetric for super::Backend { fn ed25519_derive_public(secret: &Protected) -> Result<[u8; 32]> { use ed25519_dalek::SigningKey; - let secret: SigningKey = secret.try_into()?; + let secret: Box<SigningKey> = secret.try_into()?; let public = secret.verifying_key(); Ok(public.to_bytes()) } @@ -118,8 +120,8 @@ impl Asymmetric for super::Backend { fn ed25519_sign(secret: &Protected, _public: &[u8; 32], digest: &[u8]) -> Result<[u8; 64]> { use ed25519_dalek::{SigningKey, Signer}; - let pair: SigningKey = secret.try_into()?; - Ok(zero_stack::<256, _>(pair.sign(digest)).to_bytes().try_into()?) + let pair: Box<SigningKey> = secret.try_into()?; + Ok(pair.sign(digest).to_bytes().try_into()?) } fn ed25519_verify(public: &[u8; 32], digest: &[u8], signature: &[u8; 64]) |