diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2020-02-12 12:02:16 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2020-02-12 15:12:21 +0100 |
commit | e5d72b7c92d5af171855c8267c57f5e33ff6cc2e (patch) | |
tree | 07c780f8eb954cd98926d52a08914f60522b1c49 | |
parent | 567d70df3b889bf862a18be7b17473efddf993c8 (diff) |
openpgp: Add optional plaintext length to Decryptor::decrypt.
- If we know the length of the plaintext, we can reduce the
side-channel leakage of the RSA decryption operation.
-rw-r--r-- | ipc/src/gnupg.rs | 3 | ||||
-rw-r--r-- | openpgp/src/crypto/asymmetric.rs | 17 | ||||
-rw-r--r-- | openpgp/src/packet/pkesk.rs | 2 |
3 files changed, 16 insertions, 6 deletions
diff --git a/ipc/src/gnupg.rs b/ipc/src/gnupg.rs index 561c749b..dd74ef77 100644 --- a/ipc/src/gnupg.rs +++ b/ipc/src/gnupg.rs @@ -743,7 +743,8 @@ impl<'a> crypto::Decryptor for KeyPair<'a> { self.public } - fn decrypt(&mut self, ciphertext: &crypto::mpis::Ciphertext) + fn decrypt(&mut self, ciphertext: &crypto::mpis::Ciphertext, + _plaintext_len: Option<usize>) -> Result<crypto::SessionKey> { use crate::openpgp::crypto::mpis::{PublicKey, Ciphertext}; diff --git a/openpgp/src/crypto/asymmetric.rs b/openpgp/src/crypto/asymmetric.rs index f73c83ec..555132d6 100644 --- a/openpgp/src/crypto/asymmetric.rs +++ b/openpgp/src/crypto/asymmetric.rs @@ -47,7 +47,8 @@ pub trait Decryptor { fn public(&self) -> &Key<key::PublicParts, key::UnspecifiedRole>; /// Decrypts `ciphertext`, returning the plain session key. - fn decrypt(&mut self, ciphertext: &mpis::Ciphertext) + fn decrypt(&mut self, ciphertext: &mpis::Ciphertext, + plaintext_len: Option<usize>) -> Result<SessionKey>; } @@ -222,7 +223,8 @@ impl Decryptor for KeyPair { } /// Creates a signature over the `digest` produced by `hash_algo`. - fn decrypt(&mut self, ciphertext: &mpis::Ciphertext) + fn decrypt(&mut self, ciphertext: &mpis::Ciphertext, + plaintext_len: Option<usize>) -> Result<SessionKey> { use crate::PublicKeyAlgorithm::*; @@ -238,9 +240,16 @@ impl Decryptor for KeyPair { let secret = rsa::PrivateKey::new(d.value(), p.value(), q.value(), Option::None)?; let mut rand = Yarrow::default(); - rsa::decrypt_pkcs1_insecure(&public, &secret, &mut rand, - c.value())? + if let Some(l) = plaintext_len { + let mut plaintext: SessionKey = vec![0; l].into(); + rsa::decrypt_pkcs1(&public, &secret, &mut rand, + c.value(), plaintext.as_mut())?; + plaintext + } else { + rsa::decrypt_pkcs1_insecure(&public, &secret, + &mut rand, c.value())? .into() + } } (PublicKey::Elgamal{ .. }, diff --git a/openpgp/src/packet/pkesk.rs b/openpgp/src/packet/pkesk.rs index 3554f991..7e85c61b 100644 --- a/openpgp/src/packet/pkesk.rs +++ b/openpgp/src/packet/pkesk.rs @@ -135,7 +135,7 @@ impl PKESK3 { pub fn decrypt(&self, decryptor: &mut dyn Decryptor) -> Result<(SymmetricAlgorithm, SessionKey)> { - let plain = decryptor.decrypt(&self.esk)?; + let plain = decryptor.decrypt(&self.esk, None)?; let key_rgn = 1..(plain.len() - 2); let sym_algo: SymmetricAlgorithm = plain[0].into(); let mut key: SessionKey = vec![0u8; sym_algo.key_size()?].into(); |