diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2021-09-28 11:03:27 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2021-09-28 14:11:08 +0200 |
commit | a759d80f4f9ad4b3c6121665458ab6847cb0bd39 (patch) | |
tree | 9ec93ec502171497d55c93623054b9e10ace6ba9 /openpgp/src/crypto/mpi.rs | |
parent | a9c7911284f51780ffcf34b0398d2fb03829fd72 (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/src/crypto/mpi.rs')
-rw-r--r-- | openpgp/src/crypto/mpi.rs | 24 |
1 files changed, 24 insertions, 0 deletions
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 |