aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-05-03 00:21:07 -0400
committerJesse Luehrs <doy@tozt.net>2020-05-03 00:56:21 -0400
commit047550f2368d134c9d5dca60aeb0b56fe151a323 (patch)
tree2ad014146d2214db42f550646379bb2dbd571ff1 /src
parentea6398d5951ef6a5811cf605bfa223b5b1ce08c4 (diff)
downloadrbw-047550f2368d134c9d5dca60aeb0b56fe151a323.tar.gz
rbw-047550f2368d134c9d5dca60aeb0b56fe151a323.zip
move to ring for things that it supports
it doesn't support AES_256_CBC_HMAC_SHA256, so we can't move that over yet (see https://github.com/briansmith/ring/issues/588)
Diffstat (limited to 'src')
-rw-r--r--src/cipherstring.rs52
-rw-r--r--src/error.rs18
-rw-r--r--src/identity.rs29
3 files changed, 45 insertions, 54 deletions
diff --git a/src/cipherstring.rs b/src/cipherstring.rs
index 2398b07..09d5c88 100644
--- a/src/cipherstring.rs
+++ b/src/cipherstring.rs
@@ -1,7 +1,6 @@
use crate::prelude::*;
use block_modes::BlockMode as _;
-use hmac::Mac as _;
use rand::RngCore as _;
pub struct CipherString {
@@ -58,6 +57,8 @@ impl CipherString {
) -> Result<Self> {
let iv = random_iv();
+ // ring doesn't currently support CBC ciphers, so we have to do it
+ // manually. see https://github.com/briansmith/ring/issues/588
let cipher = block_modes::Cbc::<
aes::Aes256,
block_modes::block_padding::Pkcs7,
@@ -65,12 +66,12 @@ impl CipherString {
.context(crate::error::CreateBlockMode)?;
let ciphertext = cipher.encrypt_vec(plaintext);
- let mut digest =
- hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key())
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(&iv);
- digest.input(&ciphertext);
- let mac = digest.result().code().to_vec();
+ let mut digest = ring::hmac::Context::with_key(
+ &ring::hmac::Key::new(ring::hmac::HMAC_SHA256, keys.mac_key()),
+ );
+ digest.update(&iv);
+ digest.update(&ciphertext);
+ let mac = digest.sign().as_ref().to_vec();
Ok(Self {
ty: 2,
@@ -111,18 +112,25 @@ impl CipherString {
}
if let Some(mac) = &self.mac {
- let mut digest =
- hmac::Hmac::<sha2::Sha256>::new_varkey(keys.mac_key())
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(&self.iv);
- digest.input(&self.ciphertext);
- let calculated_mac = digest.result().code();
-
- if !macs_equal(mac, &calculated_mac, keys.mac_key())? {
+ let key =
+ ring::hmac::Key::new(ring::hmac::HMAC_SHA256, keys.mac_key());
+ // it'd be nice to not have to pull this into a vec, but ring
+ // doesn't currently support non-contiguous verification. see
+ // https://github.com/briansmith/ring/issues/615
+ let data: Vec<_> = self
+ .iv
+ .iter()
+ .chain(self.ciphertext.iter())
+ .copied()
+ .collect();
+
+ if ring::hmac::verify(&key, &data, mac).is_err() {
return Err(Error::InvalidMac);
}
}
+ // ring doesn't currently support CBC ciphers, so we have to do it
+ // manually. see https://github.com/briansmith/ring/issues/588
Ok(block_modes::Cbc::<
aes::Aes256,
block_modes::block_padding::Pkcs7,
@@ -144,20 +152,6 @@ impl std::fmt::Display for CipherString {
}
}
-fn macs_equal(mac1: &[u8], mac2: &[u8], mac_key: &[u8]) -> Result<bool> {
- let mut digest = hmac::Hmac::<sha2::Sha256>::new_varkey(mac_key)
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(mac1);
- let hmac1 = digest.result().code();
-
- let mut digest = hmac::Hmac::<sha2::Sha256>::new_varkey(mac_key)
- .map_err(|_| Error::InvalidMacKey)?;
- digest.input(mac2);
- let hmac2 = digest.result().code();
-
- Ok(hmac1 == hmac2)
-}
-
fn random_iv() -> Vec<u8> {
let mut iv = vec![0_u8; 16];
let mut rng = rand::thread_rng();
diff --git a/src/error.rs b/src/error.rs
index b1ce2b6..2222f66 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -22,18 +22,9 @@ pub enum Error {
res: std::process::ExitStatus,
},
- // no Error impl
- // #[snafu(display("failed to expand with hkdf: {}", source))]
- // HkdfExpand { source: hkdf::InvalidLength },
#[snafu(display("failed to expand with hkdf"))]
HkdfExpand,
- // no Error impl
- // #[snafu(display("failed to create hkdf: {}", source))]
- // HkdfFromPrk { source: hkdf::InvalidPrkLength },
- #[snafu(display("failed to create hkdf"))]
- HkdfFromPrk,
-
#[snafu(display("username or password incorrect"))]
IncorrectPassword,
@@ -49,12 +40,6 @@ pub enum Error {
#[snafu(display("invalid mac"))]
InvalidMac,
- // no Error impl
- // #[snafu(display("invalid mac key: {}", source))]
- // InvalidMacKey { source: hmac::crypto_mac::InvalidKeyLength },
- #[snafu(display("invalid mac key"))]
- InvalidMacKey,
-
#[snafu(display("failed to load config: {}", source))]
LoadConfig { source: std::io::Error },
@@ -73,6 +58,9 @@ pub enum Error {
#[snafu(display("failed to load db: {}", source))]
LoadDbJson { source: serde_json::Error },
+ #[snafu(display("pbkdf2 requires at least 1 iteration (got 0)"))]
+ Pbkdf2ZeroIterations,
+
#[snafu(display("pinentry cancelled"))]
PinentryCancelled,
diff --git a/src/identity.rs b/src/identity.rs
index 1baac0f..8415765 100644
--- a/src/identity.rs
+++ b/src/identity.rs
@@ -12,33 +12,42 @@ impl Identity {
password: &crate::locked::Password,
iterations: u32,
) -> Result<Self> {
+ let iterations = std::num::NonZeroU32::new(iterations)
+ .context(crate::error::Pbkdf2ZeroIterations)?;
+
let mut keys = crate::locked::Vec::new();
keys.extend(std::iter::repeat(0).take(64));
let enc_key = &mut keys.data_mut()[0..32];
- pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>(
- password.password(),
+ ring::pbkdf2::derive(
+ ring::pbkdf2::PBKDF2_HMAC_SHA256,
+ iterations,
email.as_bytes(),
- iterations as usize,
+ password.password(),
enc_key,
);
let mut hash = crate::locked::Vec::new();
hash.extend(std::iter::repeat(0).take(32));
- pbkdf2::pbkdf2::<hmac::Hmac<sha2::Sha256>>(
- enc_key,
+ ring::pbkdf2::derive(
+ ring::pbkdf2::PBKDF2_HMAC_SHA256,
+ std::num::NonZeroU32::new(1).unwrap(),
password.password(),
- 1,
+ enc_key,
hash.data_mut(),
);
- let hkdf = hkdf::Hkdf::<sha2::Sha256>::from_prk(enc_key)
- .map_err(|_| Error::HkdfFromPrk)?;
- hkdf.expand(b"enc", enc_key)
+ let hkdf =
+ ring::hkdf::Prk::new_less_safe(ring::hkdf::HKDF_SHA256, enc_key);
+ hkdf.expand(&[b"enc"], ring::hkdf::HKDF_SHA256)
+ .map_err(|_| Error::HkdfExpand)?
+ .fill(enc_key)
.map_err(|_| Error::HkdfExpand)?;
let mac_key = &mut keys.data_mut()[32..64];
- hkdf.expand(b"mac", mac_key)
+ hkdf.expand(&[b"mac"], ring::hkdf::HKDF_SHA256)
+ .map_err(|_| Error::HkdfExpand)?
+ .fill(mac_key)
.map_err(|_| Error::HkdfExpand)?;
let keys = crate::locked::Keys::new(keys);