summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2020-02-12 12:02:16 +0100
committerJustus Winter <justus@sequoia-pgp.org>2020-02-12 15:12:21 +0100
commite5d72b7c92d5af171855c8267c57f5e33ff6cc2e (patch)
tree07c780f8eb954cd98926d52a08914f60522b1c49
parent567d70df3b889bf862a18be7b17473efddf993c8 (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.rs3
-rw-r--r--openpgp/src/crypto/asymmetric.rs17
-rw-r--r--openpgp/src/packet/pkesk.rs2
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();