summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2021-09-28 11:03:27 +0200
committerJustus Winter <justus@sequoia-pgp.org>2021-09-28 14:11:08 +0200
commita759d80f4f9ad4b3c6121665458ab6847cb0bd39 (patch)
tree9ec93ec502171497d55c93623054b9e10ace6ba9 /openpgp
parenta9c7911284f51780ffcf34b0398d2fb03829fd72 (diff)
openpgp: Add methods for padding and truncating MPI values.
- Cryptographic values are often expected to have a certain size. Handling this is repetitive and error prone. - This is especially problematic because MPI-encoding strips leading zero bytes. Introduce two methods for that purpose. - Fixes #759.
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/NEWS2
-rw-r--r--openpgp/src/crypto/mod.rs1
-rw-r--r--openpgp/src/crypto/mpi.rs24
3 files changed, 26 insertions, 1 deletions
diff --git a/openpgp/NEWS b/openpgp/NEWS
index 2bec0b11..d17c9c08 100644
--- a/openpgp/NEWS
+++ b/openpgp/NEWS
@@ -5,7 +5,9 @@
* Changes in 1.4.0
** New functionality
- CipherSuite::is_supported
+ - MPI::value_padded
- Preferences::policy_uri
+ - ProtectedMPI::value_padded
- TSK::eq
- ValidAmalgamation::revocation_keys
- ValidCert::policy_uri
diff --git a/openpgp/src/crypto/mod.rs b/openpgp/src/crypto/mod.rs
index 8dfe77b7..817908a0 100644
--- a/openpgp/src/crypto/mod.rs
+++ b/openpgp/src/crypto/mod.rs
@@ -247,7 +247,6 @@ impl Password {
/// Some encodings strip leading zero-bytes. This function adds them
/// back, if necessary. If the size exceeds `to`, an error is
/// returned.
-#[allow(dead_code)]
pub(crate) fn pad(value: &[u8], to: usize) -> Result<Cow<[u8]>>
{
if value.len() == to {
diff --git a/openpgp/src/crypto/mpi.rs b/openpgp/src/crypto/mpi.rs
index 0bda2b52..ecff49ac 100644
--- a/openpgp/src/crypto/mpi.rs
+++ b/openpgp/src/crypto/mpi.rs
@@ -18,6 +18,7 @@
use std::fmt;
use std::cmp::Ordering;
use std::io::Write;
+use std::borrow::Cow;
#[cfg(test)]
use quickcheck::{Arbitrary, Gen};
@@ -135,6 +136,15 @@ impl MPI {
&self.value
}
+ /// Returns the value of this MPI zero-padded to the given length.
+ ///
+ /// MPI-encoding strips leading zero-bytes. This function adds
+ /// them back, if necessary. If the size exceeds `to`, an error
+ /// is returned.
+ pub fn value_padded(&self, to: usize) -> Result<Cow<[u8]>> {
+ crate::crypto::pad(self.value(), to)
+ }
+
/// Decodes an EC point encoded as MPI.
///
/// Decodes the MPI into a point on an elliptic curve (see
@@ -387,6 +397,20 @@ impl ProtectedMPI {
&self.value
}
+ /// Returns the value of this MPI zero-padded to the given length.
+ ///
+ /// MPI-encoding strips leading zero-bytes. This function adds
+ /// them back. This operation is done unconditionally to avoid
+ /// timing differences. If the size exceeds `to`, the result is
+ /// silently truncated to avoid timing differences.
+ pub fn value_padded(&self, to: usize) -> Protected {
+ let missing = to.saturating_sub(self.value.len());
+ let limit = self.value.len().min(to);
+ let mut v: Protected = vec![0; to].into();
+ v[missing..].copy_from_slice(&self.value()[..limit]);
+ v
+ }
+
/// Decodes an EC point encoded as MPI.
///
/// Decodes the MPI into a point on an elliptic curve (see