diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-02-15 10:02:57 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-02-15 10:02:57 +0100 |
commit | f7e3e6fbb693add25401b792c495f4a35adacd55 (patch) | |
tree | 8bbce5149ebddc17af637899c9d90643c96d2c84 | |
parent | cf2a472a34588c453f10efa0263ec51e0c860988 (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.rs | 11 |
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) |