summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-09-26 13:00:06 +0200
committerJustus Winter <justus@sequoia-pgp.org>2023-09-26 13:39:58 +0200
commit55b16c4904b9875a68193ca2a15f4a61ad05d9ac (patch)
tree9e5ee29d848713d0414683ee172d07fc1a80bb66
parentc62fb995baee091ef6009a06068b88421d43a994 (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.rs18
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs18
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])