diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-03-07 11:22:44 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-03-07 11:52:53 +0100 |
commit | 7917e31af5f89e3ea7474f3bdd386607c5fccb16 (patch) | |
tree | 081f70567d69fa3eca05ecc838af3a4335c013a8 /openpgp/src/crypto | |
parent | 85af379944d11681895867324f51d9b4ac1e0258 (diff) |
openpgp: Fix secret leaking into the heap moving it into Protected.
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r-- | openpgp/src/crypto/mem.rs | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/openpgp/src/crypto/mem.rs b/openpgp/src/crypto/mem.rs index fc5de59b..8a517ac0 100644 --- a/openpgp/src/crypto/mem.rs +++ b/openpgp/src/crypto/mem.rs @@ -133,10 +133,10 @@ impl DerefMut for Protected { impl From<Vec<u8>> for Protected { fn from(mut v: Vec<u8>) -> Self { - // Make a vector with the correct size to avoid potential - // reallocations when turning it into a `Protected`. - let mut p = Vec::with_capacity(v.len()); - p.extend_from_slice(&v); + // Make a careful copy of the data. We do this instead of + // reusing v's allocation so that our allocation has the exact + // size. + let p = Protected::from(&v[..]); // Now clear the previous allocation. Just to be safe, we // clear the whole allocation. @@ -148,7 +148,7 @@ impl From<Vec<u8>> for Protected { memsec::memzero(v.as_mut_ptr(), capacity); } - p.into_boxed_slice().into() + p } } @@ -160,7 +160,13 @@ impl From<Box<[u8]>> for Protected { impl From<&[u8]> for Protected { fn from(v: &[u8]) -> Self { - Vec::from(v).into() + let mut p = Protected::new(v.len()); + + // Very carefully copy the slice. The obvious + // `p.copy_from_slice(v);` indeed leaks secrets. + v.iter().zip(p.iter_mut()).for_each(|(f, t)| *t = *f); + + p } } |