summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-02-15 10:02:57 +0100
committerJustus Winter <justus@sequoia-pgp.org>2022-02-15 10:02:57 +0100
commitf7e3e6fbb693add25401b792c495f4a35adacd55 (patch)
tree8bbce5149ebddc17af637899c9d90643c96d2c84
parentcf2a472a34588c453f10efa0263ec51e0c860988 (diff)
openpgp: Use unique keys for memory encryption.
- Previously, we used the same session key for every encrypted memory region, relying on the nonces being derived from a random initialization vector. - However, in cf2a472a34588c453f10efa0263ec51e0c860988 we changed the nonce to be a simple counter. This leads reuse of (key, nonce) pairs. - Instead of relying on the nonces having some entropy, a more robust way to deal with this is to have distinct keys. To that end, add a random salt to each memory region that we hash before hashing the prekey.
-rw-r--r--openpgp/src/crypto/mem.rs11
1 files changed, 8 insertions, 3 deletions
diff --git a/openpgp/src/crypto/mem.rs b/openpgp/src/crypto/mem.rs
index d09eb3a8..30a0ab66 100644
--- a/openpgp/src/crypto/mem.rs
+++ b/openpgp/src/crypto/mem.rs
@@ -213,6 +213,7 @@ impl fmt::Debug for Protected {
#[derive(Clone, Debug)]
pub struct Encrypted {
ciphertext: Protected,
+ salt: [u8; 32],
}
assert_send_and_sync!(Encrypted);
@@ -272,9 +273,10 @@ mod has_access_to_prekey {
impl Encrypted {
/// Computes the sealing key used to encrypt the memory.
- fn sealing_key() -> SessionKey {
+ fn sealing_key(salt: &[u8; 32]) -> SessionKey {
let mut ctx = HASH_ALGO.context()
.expect("Mandatory algorithm unsupported");
+ ctx.update(salt);
PREKEY.iter().for_each(|page| ctx.update(page));
let mut sk: SessionKey = vec![0; 256/8].into();
let _ = ctx.digest(&mut sk);
@@ -283,6 +285,8 @@ mod has_access_to_prekey {
/// Encrypts the given chunk of memory.
pub fn new(p: Protected) -> Self {
+ let mut salt = [0; 32];
+ crate::crypto::random(&mut salt);
let mut ciphertext = Vec::new();
{
let mut encryptor =
@@ -290,7 +294,7 @@ mod has_access_to_prekey {
AEAD_ALGO,
4096,
CounterSchedule::default(),
- Self::sealing_key(),
+ Self::sealing_key(&salt),
&mut ciphertext)
.expect("Mandatory algorithm unsupported");
encryptor.write_all(&p).unwrap();
@@ -299,6 +303,7 @@ mod has_access_to_prekey {
Encrypted {
ciphertext: ciphertext.into(),
+ salt,
}
}
@@ -317,7 +322,7 @@ mod has_access_to_prekey {
AEAD_ALGO,
4096,
CounterSchedule::default(),
- Self::sealing_key(),
+ Self::sealing_key(&self.salt),
Box::new(ciphertext))
.expect("Mandatory algorithm unsupported");
io::copy(&mut decryptor, &mut plaintext)