Traits should be fixed now

This commit is contained in:
Jędrzej Stuczyński
2022-03-01 12:20:39 +00:00
parent 5701ea5c02
commit 9d6a4ea99d
4 changed files with 39 additions and 33 deletions
+7 -2
View File
@@ -3,8 +3,12 @@
use hkdf::{hmac::digest::Digest, Hkdf};
pub use hkdf::HmacImpl;
// pub struct Hkdf<H: OutputSizeUser, I: HmacImpl<H> = Hmac<H>> {
/// Perform HKDF `extract` then `expand` as a single step.
pub fn extract_then_expand<D>(
pub fn extract_then_expand<D, I>(
salt: Option<&[u8]>,
ikm: &[u8],
info: Option<&[u8]>,
@@ -12,11 +16,12 @@ pub fn extract_then_expand<D>(
) -> Result<Vec<u8>, hkdf::InvalidLength>
where
D: Digest,
I: HmacImpl<D>,
{
// TODO: this would need to change if we ever needed the generated pseudorandom key, but
// realistically I don't see any reasons why we might need it
let hkdf = Hkdf::<D>::new(salt, ikm);
let hkdf = Hkdf::<D, I>::new(salt, ikm);
let mut okm = vec![0u8; okm_length];
hkdf.expand(info.unwrap_or(&[]), &mut okm)?;
+22 -22
View File
@@ -2,14 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
use hmac::{
digest::{crypto_common::BlockSizeUser, Digest, Output},
digest::{crypto_common::BlockSizeUser, CtOutput, Digest, Output},
Mac, SimpleHmac,
};
pub use hmac;
// TODO: We should probably change it to use some sealed trait to allow for both `Hmac` and `SimpleHmac`
pub type HmacOutput<D> = Output<SimpleHmac<D>>;
pub type HmacOutput<D> = CtOutput<SimpleHmac<D>>;
/// Compute keyed hmac
pub fn compute_keyed_hmac<D>(key: &[u8], data: &[u8]) -> HmacOutput<D>
@@ -25,29 +25,29 @@ where
/// Compute keyed hmac and performs constant time equality check with the provided tag value.
pub fn recompute_keyed_hmac_and_verify_tag<D>(key: &[u8], data: &[u8], tag: &[u8]) -> bool
where
D: Digest,
D: Digest + BlockSizeUser,
{
let mut hmac = SimpleHmac::<D>::new_from_slice(key)
.expect("HMAC was instantiated with a key of an invalid size!");
hmac.update(data);
let tag_arr = Output::<D>::from_slice(tag);
// note, under the hood ct_eq is called
hmac.verify(tag).is_ok()
hmac.verify(tag_arr).is_ok()
}
// /// Verifies tag of an hmac output.
// pub fn verify_tag<D>(tag: &[u8], out: HmacOutput<D>) -> bool
// where
// D: Digest,
// {
// if tag.len() != D::output_size() {
// return false;
// }
//
// let tag_bytes = GenericArray::clone_from_slice(tag);
//
// // note, under the hood ct_eq is called
// out == tag_out
// }
/// Verifies tag of an hmac output.
pub fn verify_tag<D>(tag: &[u8], out: HmacOutput<D>) -> bool
where
D: Digest + BlockSizeUser,
{
if tag.len() != <D as Digest>::output_size() {
return false;
}
let tag_arr = Output::<D>::from_slice(tag);
out == tag_arr.into()
}
#[cfg(test)]
mod tests {
@@ -71,9 +71,9 @@ mod tests {
&output_tag
));
// assert!(verify_tag::<blake3::Hasher>(
// &output_tag,
// compute_keyed_hmac::<blake3::Hasher>(&key, msg)
// ));
assert!(verify_tag::<blake3::Hasher>(
&output_tag,
compute_keyed_hmac::<blake3::Hasher>(&key, msg)
));
}
}
+7 -5
View File
@@ -2,20 +2,21 @@
// SPDX-License-Identifier: Apache-2.0
use crate::asymmetric::encryption;
use crate::hkdf;
use crate::hkdf::{self, HmacImpl};
use cipher::{Key, KeyIvInit, StreamCipher};
use digest::Digest;
use rand::{CryptoRng, RngCore};
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
/// shared key with the remote.
pub fn new_ephemeral_shared_key<C, D, R>(
pub fn new_ephemeral_shared_key<C, D, I, R>(
rng: &mut R,
remote_key: &encryption::PublicKey,
) -> (encryption::KeyPair, Key<C>)
where
C: StreamCipher + KeyIvInit,
D: Digest,
I: HmacImpl<D>,
R: RngCore + CryptoRng,
{
let ephemeral_keypair = encryption::KeyPair::new(rng);
@@ -24,7 +25,7 @@ where
let dh_result = ephemeral_keypair.private_key().diffie_hellman(remote_key);
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::KeySize::to_usize())
let okm = hkdf::extract_then_expand::<D, I>(None, &dh_result, None, C::key_size())
.expect("somehow too long okm was provided");
let derived_shared_key =
@@ -34,18 +35,19 @@ where
}
/// Recompute shared key using remote public key and local private key.
pub fn recompute_shared_key<C, D>(
pub fn recompute_shared_key<C, D, I>(
remote_key: &encryption::PublicKey,
local_key: &encryption::PrivateKey,
) -> Key<C>
where
C: StreamCipher + KeyIvInit,
D: Digest,
I: HmacImpl<D>,
{
let dh_result = local_key.diffie_hellman(remote_key);
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::KeySize::to_usize())
let okm = hkdf::extract_then_expand::<D, I>(None, &dh_result, None, C::key_size())
.expect("somehow too long okm was provided");
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
+3 -4
View File
@@ -1,8 +1,7 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use cipher::{Iv, KeyIvInit, StreamCipher};
use generic_array::{typenum::Unsigned, GenericArray};
use cipher::{generic_array::GenericArray, Iv, KeyIvInit, StreamCipher};
use rand::{CryptoRng, RngCore};
// re-export this for ease of use
@@ -52,13 +51,13 @@ pub fn iv_from_slice<C>(b: &[u8]) -> &IV<C>
where
C: KeyIvInit,
{
if b.len() != C::NonceSize::to_usize() {
if b.len() != C::iv_size() {
// `from_slice` would have caused a panic about this issue anyway.
// Now we at least have slightly more information
panic!(
"Tried to convert {} bytes to IV. Expected {}",
b.len(),
C::NonceSize::to_usize()
C::iv_size()
)
}
GenericArray::from_slice(b)