Traits should be fixed now
This commit is contained in:
@@ -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
@@ -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)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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!")
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user