Performed the rest of the upgrade
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crypto::generic_array::typenum::Unsigned;
|
||||
use log::*;
|
||||
use nymsphinx::anonymous_replies::{
|
||||
encryption_key::EncryptionKeyDigest, encryption_key::Unsigned, SurbEncryptionKey,
|
||||
SurbEncryptionKeySize,
|
||||
encryption_key::EncryptionKeyDigest, SurbEncryptionKey, SurbEncryptionKeySize,
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
@@ -43,7 +43,7 @@ impl ReplyKeyStorage {
|
||||
// if this fails it means we have some database corruption and we
|
||||
// absolutely can't continue
|
||||
|
||||
if key_bytes_ref.len() != SurbEncryptionKeySize::to_usize() {
|
||||
if key_bytes_ref.len() != SurbEncryptionKeySize::USIZE {
|
||||
error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
||||
panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
|
||||
}
|
||||
|
||||
@@ -1,27 +1,28 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use hkdf::{hmac::digest::Digest, Hkdf};
|
||||
|
||||
pub use hkdf::HmacImpl;
|
||||
|
||||
// pub struct Hkdf<H: OutputSizeUser, I: HmacImpl<H> = Hmac<H>> {
|
||||
use hkdf::{
|
||||
hmac::{
|
||||
digest::{crypto_common::BlockSizeUser, Digest},
|
||||
SimpleHmac,
|
||||
},
|
||||
Hkdf,
|
||||
};
|
||||
|
||||
/// Perform HKDF `extract` then `expand` as a single step.
|
||||
pub fn extract_then_expand<D, I>(
|
||||
pub fn extract_then_expand<D>(
|
||||
salt: Option<&[u8]>,
|
||||
ikm: &[u8],
|
||||
info: Option<&[u8]>,
|
||||
okm_length: usize,
|
||||
) -> Result<Vec<u8>, hkdf::InvalidLength>
|
||||
where
|
||||
D: Digest,
|
||||
I: HmacImpl<D>,
|
||||
D: Digest + BlockSizeUser + Clone,
|
||||
{
|
||||
// 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, I>::new(salt, ikm);
|
||||
let hkdf = Hkdf::<D, SimpleHmac<D>>::new(salt, ikm);
|
||||
let mut okm = vec![0u8; okm_length];
|
||||
hkdf.expand(info.unwrap_or(&[]), &mut okm)?;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ pub mod hmac;
|
||||
pub mod shared_key;
|
||||
pub mod symmetric;
|
||||
|
||||
pub use digest::Digest;
|
||||
pub use digest::{Digest, OutputSizeUser};
|
||||
pub use generic_array;
|
||||
|
||||
// with the below my idea was to try to introduce having a single place of importing all hashing, encryption,
|
||||
|
||||
@@ -2,21 +2,21 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::asymmetric::encryption;
|
||||
use crate::hkdf::{self, HmacImpl};
|
||||
use crate::hkdf;
|
||||
use cipher::{Key, KeyIvInit, StreamCipher};
|
||||
use digest::crypto_common::BlockSizeUser;
|
||||
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, I, R>(
|
||||
pub fn new_ephemeral_shared_key<C, D, R>(
|
||||
rng: &mut R,
|
||||
remote_key: &encryption::PublicKey,
|
||||
) -> (encryption::KeyPair, Key<C>)
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
D: Digest,
|
||||
I: HmacImpl<D>,
|
||||
D: Digest + BlockSizeUser + Clone,
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||
@@ -25,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, I>(None, &dh_result, None, C::key_size())
|
||||
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::key_size())
|
||||
.expect("somehow too long okm was provided");
|
||||
|
||||
let derived_shared_key =
|
||||
@@ -35,19 +35,18 @@ where
|
||||
}
|
||||
|
||||
/// Recompute shared key using remote public key and local private key.
|
||||
pub fn recompute_shared_key<C, D, I>(
|
||||
pub fn recompute_shared_key<C, D>(
|
||||
remote_key: &encryption::PublicKey,
|
||||
local_key: &encryption::PrivateKey,
|
||||
) -> Key<C>
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
D: Digest,
|
||||
I: HmacImpl<D>,
|
||||
D: Digest + BlockSizeUser + Clone,
|
||||
{
|
||||
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, I>(None, &dh_result, None, C::key_size())
|
||||
let okm = hkdf::extract_then_expand::<D>(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,11 +1,12 @@
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use cipher::{generic_array::GenericArray, Iv, KeyIvInit, StreamCipher};
|
||||
use cipher::{generic_array::GenericArray, Iv, StreamCipher};
|
||||
pub use cipher::{IvSizeUser, KeyIvInit, KeySizeUser};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
// re-export this for ease of use
|
||||
pub use cipher::Key;
|
||||
pub use cipher::Key as CipherKey;
|
||||
|
||||
// SECURITY:
|
||||
// TODO: note that this is not the most secure approach here
|
||||
@@ -20,12 +21,12 @@ pub use cipher::Key;
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub type IV<C> = Iv<C>;
|
||||
|
||||
pub fn generate_key<C, R>(rng: &mut R) -> Key<C>
|
||||
pub fn generate_key<C, R>(rng: &mut R) -> CipherKey<C>
|
||||
where
|
||||
C: KeyIvInit,
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
let mut key = GenericArray::default();
|
||||
let mut key = CipherKey::<C>::default();
|
||||
rng.fill_bytes(&mut key);
|
||||
key
|
||||
}
|
||||
@@ -35,7 +36,7 @@ where
|
||||
C: KeyIvInit,
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
let mut iv = GenericArray::default();
|
||||
let mut iv = IV::<C>::default();
|
||||
rng.fill_bytes(&mut iv);
|
||||
iv
|
||||
}
|
||||
@@ -44,7 +45,7 @@ pub fn zero_iv<C>() -> IV<C>
|
||||
where
|
||||
C: KeyIvInit,
|
||||
{
|
||||
GenericArray::default()
|
||||
Iv::<C>::default()
|
||||
}
|
||||
|
||||
pub fn iv_from_slice<C>(b: &[u8]) -> &IV<C>
|
||||
@@ -67,7 +68,7 @@ where
|
||||
// However, do we really expect to ever need it?
|
||||
|
||||
#[inline]
|
||||
pub fn encrypt<C>(key: &Key<C>, iv: &IV<C>, data: &[u8]) -> Vec<u8>
|
||||
pub fn encrypt<C>(key: &CipherKey<C>, iv: &IV<C>, data: &[u8]) -> Vec<u8>
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
@@ -77,7 +78,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn encrypt_in_place<C>(key: &Key<C>, iv: &IV<C>, data: &mut [u8])
|
||||
pub fn encrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
@@ -86,7 +87,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decrypt<C>(key: &Key<C>, iv: &IV<C>, ciphertext: &[u8]) -> Vec<u8>
|
||||
pub fn decrypt<C>(key: &CipherKey<C>, iv: &IV<C>, ciphertext: &[u8]) -> Vec<u8>
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
@@ -96,7 +97,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn decrypt_in_place<C>(key: &Key<C>, iv: &IV<C>, data: &mut [u8])
|
||||
pub fn decrypt_in_place<C>(key: &CipherKey<C>, iv: &IV<C>, data: &mut [u8])
|
||||
where
|
||||
C: StreamCipher + KeyIvInit,
|
||||
{
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::AckKey;
|
||||
use crypto::generic_array::typenum::Unsigned;
|
||||
use crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, NewCipher};
|
||||
use crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
|
||||
use nymsphinx_params::{
|
||||
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
|
||||
};
|
||||
@@ -33,7 +32,7 @@ pub fn recover_identifier(
|
||||
return None;
|
||||
}
|
||||
|
||||
let iv_size = <AckEncryptionAlgorithm as NewCipher>::NonceSize::to_usize();
|
||||
let iv_size = AckEncryptionAlgorithm::iv_size();
|
||||
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
|
||||
|
||||
let id = stream_cipher::decrypt::<AckEncryptionAlgorithm>(
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crypto::generic_array::{typenum::Unsigned, GenericArray};
|
||||
use crypto::symmetric::stream_cipher::{generate_key, CipherKey, NewCipher};
|
||||
use crypto::symmetric::stream_cipher::{generate_key, CipherKey, KeySizeUser};
|
||||
use nymsphinx_params::AckEncryptionAlgorithm;
|
||||
use pemstore::traits::PemStorableKey;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
@@ -33,11 +32,14 @@ impl AckKey {
|
||||
}
|
||||
|
||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, AckKeyConversionError> {
|
||||
if bytes.len() != <AckEncryptionAlgorithm as NewCipher>::KeySize::to_usize() {
|
||||
if bytes.len() != AckEncryptionAlgorithm::key_size() {
|
||||
return Err(AckKeyConversionError::BytesOfInvalidLengthError);
|
||||
}
|
||||
|
||||
Ok(AckKey(GenericArray::clone_from_slice(bytes)))
|
||||
// Ok(AckKey(GenericArray::clone_from_slice(bytes)))
|
||||
Ok(AckKey(
|
||||
CipherKey::<AckEncryptionAlgorithm>::clone_from_slice(bytes),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8> {
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use crypto::generic_array::typenum::Unsigned;
|
||||
use crypto::{
|
||||
crypto_hash,
|
||||
generic_array::GenericArray,
|
||||
symmetric::stream_cipher::{generate_key, CipherKey, NewCipher},
|
||||
Digest,
|
||||
generic_array::{typenum::Unsigned, GenericArray},
|
||||
symmetric::stream_cipher::{generate_key, CipherKey, KeySizeUser},
|
||||
OutputSizeUser,
|
||||
};
|
||||
use nymsphinx_params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
pub type EncryptionKeyDigest =
|
||||
GenericArray<u8, <ReplySurbKeyDigestAlgorithm as Digest>::OutputSize>;
|
||||
GenericArray<u8, <ReplySurbKeyDigestAlgorithm as OutputSizeUser>::OutputSize>;
|
||||
|
||||
pub type SurbEncryptionKeySize = <ReplySurbEncryptionAlgorithm as NewCipher>::KeySize;
|
||||
pub type SurbEncryptionKeySize = <ReplySurbEncryptionAlgorithm as KeySizeUser>::KeySize;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SurbEncryptionKey(CipherKey<ReplySurbEncryptionAlgorithm>);
|
||||
@@ -45,7 +44,7 @@ impl SurbEncryptionKey {
|
||||
}
|
||||
|
||||
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, SurbEncryptionKeyError> {
|
||||
if bytes.len() != SurbEncryptionKeySize::to_usize() {
|
||||
if bytes.len() != SurbEncryptionKeySize::USIZE {
|
||||
return Err(SurbEncryptionKeyError::BytesOfInvalidLengthError);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod encryption_key;
|
||||
pub mod reply_surb;
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::encryption_key::{
|
||||
SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize, Unsigned,
|
||||
};
|
||||
use crypto::Digest;
|
||||
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
|
||||
use crypto::{generic_array::typenum::Unsigned, Digest};
|
||||
use nymsphinx_addressing::clients::Recipient;
|
||||
use nymsphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||
use nymsphinx_params::packet_sizes::PacketSize;
|
||||
@@ -65,7 +63,7 @@ pub struct ReplySurb {
|
||||
// Serialize + Deserialize is not really used anymore (it was for a CBOR experiment)
|
||||
// however, if we decided we needed it again, it's already here
|
||||
impl Serialize for ReplySurb {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
@@ -139,7 +137,7 @@ impl ReplySurb {
|
||||
|
||||
// the SURB itself consists of SURB_header, first hop address and set of payload keys
|
||||
// (note extra 1 for the gateway)
|
||||
SurbEncryptionKeySize::to_usize()
|
||||
SurbEncryptionKeySize::USIZE
|
||||
+ HEADER_SIZE
|
||||
+ NODE_ADDRESS_LENGTH
|
||||
+ (1 + mix_hops as usize) * PAYLOAD_KEY_SIZE
|
||||
@@ -160,9 +158,9 @@ impl ReplySurb {
|
||||
|
||||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, ReplySurbError> {
|
||||
let encryption_key =
|
||||
SurbEncryptionKey::try_from_bytes(&bytes[..SurbEncryptionKeySize::to_usize()])?;
|
||||
SurbEncryptionKey::try_from_bytes(&bytes[..SurbEncryptionKeySize::USIZE])?;
|
||||
|
||||
let surb = match SURB::from_bytes(&bytes[SurbEncryptionKeySize::to_usize()..]) {
|
||||
let surb = match SURB::from_bytes(&bytes[SurbEncryptionKeySize::USIZE..]) {
|
||||
Err(err) => return Err(ReplySurbError::RecoveryError(err)),
|
||||
Ok(surb) => surb,
|
||||
};
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crypto::generic_array::{typenum::Unsigned, GenericArray};
|
||||
use crypto::symmetric::stream_cipher::{random_iv, NewCipher, IV as CryptoIV};
|
||||
use crypto::symmetric::stream_cipher::{random_iv, IvSizeUser, IV as CryptoIV};
|
||||
use nymsphinx::params::GatewayEncryptionAlgorithm;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use thiserror::Error;
|
||||
|
||||
type NonceSize = <GatewayEncryptionAlgorithm as NewCipher>::NonceSize;
|
||||
type NonceSize = <GatewayEncryptionAlgorithm as IvSizeUser>::IvSize;
|
||||
|
||||
// I think 'IV' looks better than 'Iv', feel free to change that.
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use crypto::generic_array;
|
||||
use crypto::hmac::{hmac::Mac, HmacOutput};
|
||||
use crypto::hmac::HmacOutput;
|
||||
use crypto::OutputSizeUser;
|
||||
use nymsphinx::params::GatewayIntegrityHmacAlgorithm;
|
||||
pub use types::*;
|
||||
|
||||
@@ -15,4 +16,4 @@ pub type GatewayMac = HmacOutput<GatewayIntegrityHmacAlgorithm>;
|
||||
|
||||
// TODO: could using `Mac` trait here for OutputSize backfire?
|
||||
// Should hmac itself be exposed, imported and used instead?
|
||||
pub type GatewayMacSize = <GatewayIntegrityHmacAlgorithm as Mac>::OutputSize;
|
||||
pub type GatewayMacSize = <GatewayIntegrityHmacAlgorithm as OutputSizeUser>::OutputSize;
|
||||
|
||||
@@ -7,7 +7,7 @@ use crypto::generic_array::{
|
||||
GenericArray,
|
||||
};
|
||||
use crypto::hmac::{compute_keyed_hmac, recompute_keyed_hmac_and_verify_tag};
|
||||
use crypto::symmetric::stream_cipher::{self, CipherKey, NewCipher, IV};
|
||||
use crypto::symmetric::stream_cipher::{self, CipherKey, KeySizeUser, IV};
|
||||
use nymsphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorithm};
|
||||
use pemstore::traits::PemStorableKey;
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
@@ -17,7 +17,7 @@ pub type SharedKeySize = Sum<EncryptionKeySize, MacKeySize>;
|
||||
|
||||
// we're using 16 byte long key in sphinx, so let's use the same one here
|
||||
type MacKeySize = U16;
|
||||
type EncryptionKeySize = <GatewayEncryptionAlgorithm as NewCipher>::KeySize;
|
||||
type EncryptionKeySize = <GatewayEncryptionAlgorithm as KeySizeUser>::KeySize;
|
||||
|
||||
/// Shared key used when computing MAC for messages exchanged between client and its gateway.
|
||||
pub type MacKey = GenericArray<u8, MacKeySize>;
|
||||
|
||||
Reference in New Issue
Block a user