summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2019-06-28 15:04:29 +0200
committerJustus Winter <justus@sequoia-pgp.org>2019-06-28 15:57:32 +0200
commit20cae96915c9acd5e36c426e8ca3f0fc70b80693 (patch)
tree646911d33cced955db3c0c78d393b4553b6fdb29 /openpgp/src/crypto
parent023fc4e95f4d727690c9f1a6f616d6b9e6191d46 (diff)
openpgp: Do not store the length of MPIs.
- The length in bits can be computed in constant time. Storing it is unnecessary, introduces redundancy, and creates the potential for inconsistencies.
Diffstat (limited to 'openpgp/src/crypto')
-rw-r--r--openpgp/src/crypto/mpis.rs23
1 files changed, 11 insertions, 12 deletions
diff --git a/openpgp/src/crypto/mpis.rs b/openpgp/src/crypto/mpis.rs
index c88bb8f0..418a58dd 100644
--- a/openpgp/src/crypto/mpis.rs
+++ b/openpgp/src/crypto/mpis.rs
@@ -25,8 +25,6 @@ use nettle;
/// Holds a single MPI.
#[derive(Clone, Hash)]
pub struct MPI {
- /// Length of the integer in bits.
- bits: usize,
/// Integer value as big-endian.
value: Box<[u8]>,
}
@@ -54,7 +52,6 @@ impl MPI {
let value = Vec::from(&value[offset..]).into_boxed_slice();
MPI {
- bits: value.len() * 8 - leading_zeros % 8,
value: value,
}
}
@@ -72,13 +69,14 @@ impl MPI {
MPI{
value: val.into_boxed_slice(),
- bits: 3 + 16 * field_sz,
}
}
/// Returns the length of the MPI in bits.
pub fn bits(&self) -> usize {
- self.bits
+ self.value.len() * 8
+ - self.value.get(0).map(|&b| b.leading_zeros() as usize)
+ .unwrap_or(0)
}
/// Returns the value of this MPI.
@@ -149,7 +147,7 @@ impl MPI {
/// Update the Hash with a hash of the MPIs.
pub fn hash<H: nettle::Hash>(&self, hash: &mut H) {
- let len = &[(self.bits >> 8) as u8 & 0xFF, self.bits as u8];
+ let len = &[(self.bits() >> 8) as u8 & 0xFF, self.bits() as u8];
hash.update(len);
hash.update(&self.value);
@@ -182,14 +180,15 @@ impl MPI {
impl fmt::Debug for MPI {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!(
- "{} bits: {}", self.bits, ::conversions::to_hex(&*self.value, true)))
+ "{} bits: {}", self.bits(),
+ ::conversions::to_hex(&*self.value, true)))
}
}
impl Hash for MPI {
/// Update the Hash with a hash of the MPIs.
fn hash<H: nettle::Hash + Write>(&self, hash: &mut H) {
- let len = &[(self.bits >> 8) as u8 & 0xFF, self.bits as u8];
+ let len = &[(self.bits() >> 8) as u8 & 0xFF, self.bits() as u8];
hash.update(len);
hash.update(&self.value);
@@ -357,9 +356,9 @@ impl PublicKey {
pub fn bits(&self) -> Option<usize> {
use self::PublicKey::*;
match self {
- &RSA { ref n,.. } => Some(n.bits),
- &DSA { ref p,.. } => Some(p.bits),
- &Elgamal { ref p,.. } => Some(p.bits),
+ &RSA { ref n,.. } => Some(n.bits()),
+ &DSA { ref p,.. } => Some(p.bits()),
+ &Elgamal { ref p,.. } => Some(p.bits()),
&EdDSA { ref curve,.. } => curve.bits(),
&ECDSA { ref curve,.. } => curve.bits(),
&ECDH { ref curve,.. } => curve.bits(),
@@ -517,7 +516,7 @@ impl fmt::Debug for SecretKey {
}
fn secure_mpi_cmp(a: &MPI, b: &MPI) -> Ordering {
- let ord1 = a.bits.cmp(&b.bits);
+ let ord1 = a.bits().cmp(&b.bits());
let ord2 = secure_cmp(&a.value, &b.value);
if ord1 == Ordering::Equal { ord2 } else { ord1 }