From eb3ed98f94b023cc3074a1827d0befb1b0afef7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 1 Mar 2022 14:38:22 +0000 Subject: [PATCH] Performed the rest of the upgrade --- .../src/client/reply_key_storage.rs | 6 +++--- common/crypto/src/hkdf.rs | 19 +++++++++-------- common/crypto/src/lib.rs | 2 +- common/crypto/src/shared_key.rs | 17 +++++++-------- common/crypto/src/symmetric/stream_cipher.rs | 21 ++++++++++--------- .../acknowledgements/src/identifier.rs | 5 ++--- common/nymsphinx/acknowledgements/src/key.rs | 10 +++++---- .../anonymous-replies/src/encryption_key.rs | 13 ++++++------ common/nymsphinx/anonymous-replies/src/lib.rs | 1 + .../anonymous-replies/src/reply_surb.rs | 14 ++++++------- gateway/gateway-requests/src/iv.rs | 4 ++-- gateway/gateway-requests/src/lib.rs | 5 +++-- .../src/registration/handshake/shared_key.rs | 4 ++-- 13 files changed, 61 insertions(+), 60 deletions(-) diff --git a/clients/client-core/src/client/reply_key_storage.rs b/clients/client-core/src/client/reply_key_storage.rs index e9ed2be1c8..a717f44ea2 100644 --- a/clients/client-core/src/client/reply_key_storage.rs +++ b/clients/client-core/src/client/reply_key_storage.rs @@ -1,10 +1,10 @@ // Copyright 2021 - Nym Technologies SA // 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"); } diff --git a/common/crypto/src/hkdf.rs b/common/crypto/src/hkdf.rs index bc65831d5d..57c1187b07 100644 --- a/common/crypto/src/hkdf.rs +++ b/common/crypto/src/hkdf.rs @@ -1,27 +1,28 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use hkdf::{hmac::digest::Digest, Hkdf}; - -pub use hkdf::HmacImpl; - -// pub struct Hkdf = Hmac> { +use hkdf::{ + hmac::{ + digest::{crypto_common::BlockSizeUser, Digest}, + SimpleHmac, + }, + Hkdf, +}; /// Perform HKDF `extract` then `expand` as a single step. -pub fn extract_then_expand( +pub fn extract_then_expand( salt: Option<&[u8]>, ikm: &[u8], info: Option<&[u8]>, okm_length: usize, ) -> Result, hkdf::InvalidLength> where - D: Digest, - I: HmacImpl, + 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::::new(salt, ikm); + let hkdf = Hkdf::>::new(salt, ikm); let mut okm = vec![0u8; okm_length]; hkdf.expand(info.unwrap_or(&[]), &mut okm)?; diff --git a/common/crypto/src/lib.rs b/common/crypto/src/lib.rs index 60c63bb31f..4c869b39fb 100644 --- a/common/crypto/src/lib.rs +++ b/common/crypto/src/lib.rs @@ -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, diff --git a/common/crypto/src/shared_key.rs b/common/crypto/src/shared_key.rs index 5ef65b95af..80cb4b6c6d 100644 --- a/common/crypto/src/shared_key.rs +++ b/common/crypto/src/shared_key.rs @@ -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( +pub fn new_ephemeral_shared_key( rng: &mut R, remote_key: &encryption::PublicKey, ) -> (encryption::KeyPair, Key) where C: StreamCipher + KeyIvInit, - D: Digest, - I: HmacImpl, + 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::(None, &dh_result, None, C::key_size()) + let okm = hkdf::extract_then_expand::(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( +pub fn recompute_shared_key( remote_key: &encryption::PublicKey, local_key: &encryption::PrivateKey, ) -> Key where C: StreamCipher + KeyIvInit, - D: Digest, - I: HmacImpl, + 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::(None, &dh_result, None, C::key_size()) + let okm = hkdf::extract_then_expand::(None, &dh_result, None, C::key_size()) .expect("somehow too long okm was provided"); Key::::from_exact_iter(okm).expect("okm was expanded to incorrect length!") diff --git a/common/crypto/src/symmetric/stream_cipher.rs b/common/crypto/src/symmetric/stream_cipher.rs index 308a610891..c1c595c8ea 100644 --- a/common/crypto/src/symmetric/stream_cipher.rs +++ b/common/crypto/src/symmetric/stream_cipher.rs @@ -1,11 +1,12 @@ // Copyright 2020 - Nym Technologies SA // 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 = Iv; -pub fn generate_key(rng: &mut R) -> Key +pub fn generate_key(rng: &mut R) -> CipherKey where C: KeyIvInit, R: RngCore + CryptoRng, { - let mut key = GenericArray::default(); + let mut key = CipherKey::::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::::default(); rng.fill_bytes(&mut iv); iv } @@ -44,7 +45,7 @@ pub fn zero_iv() -> IV where C: KeyIvInit, { - GenericArray::default() + Iv::::default() } pub fn iv_from_slice(b: &[u8]) -> &IV @@ -67,7 +68,7 @@ where // However, do we really expect to ever need it? #[inline] -pub fn encrypt(key: &Key, iv: &IV, data: &[u8]) -> Vec +pub fn encrypt(key: &CipherKey, iv: &IV, data: &[u8]) -> Vec where C: StreamCipher + KeyIvInit, { @@ -77,7 +78,7 @@ where } #[inline] -pub fn encrypt_in_place(key: &Key, iv: &IV, data: &mut [u8]) +pub fn encrypt_in_place(key: &CipherKey, iv: &IV, data: &mut [u8]) where C: StreamCipher + KeyIvInit, { @@ -86,7 +87,7 @@ where } #[inline] -pub fn decrypt(key: &Key, iv: &IV, ciphertext: &[u8]) -> Vec +pub fn decrypt(key: &CipherKey, iv: &IV, ciphertext: &[u8]) -> Vec where C: StreamCipher + KeyIvInit, { @@ -96,7 +97,7 @@ where } #[inline] -pub fn decrypt_in_place(key: &Key, iv: &IV, data: &mut [u8]) +pub fn decrypt_in_place(key: &CipherKey, iv: &IV, data: &mut [u8]) where C: StreamCipher + KeyIvInit, { diff --git a/common/nymsphinx/acknowledgements/src/identifier.rs b/common/nymsphinx/acknowledgements/src/identifier.rs index 988bdad156..7b7a2ae844 100644 --- a/common/nymsphinx/acknowledgements/src/identifier.rs +++ b/common/nymsphinx/acknowledgements/src/identifier.rs @@ -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 = ::NonceSize::to_usize(); + let iv_size = AckEncryptionAlgorithm::iv_size(); let iv = iv_from_slice::(&iv_id_ciphertext[..iv_size]); let id = stream_cipher::decrypt::( diff --git a/common/nymsphinx/acknowledgements/src/key.rs b/common/nymsphinx/acknowledgements/src/key.rs index a7ff5f9271..ec65537c87 100644 --- a/common/nymsphinx/acknowledgements/src/key.rs +++ b/common/nymsphinx/acknowledgements/src/key.rs @@ -1,8 +1,7 @@ // Copyright 2021 - Nym Technologies SA // 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 { - if bytes.len() != ::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::::clone_from_slice(bytes), + )) } pub fn to_bytes(&self) -> Vec { diff --git a/common/nymsphinx/anonymous-replies/src/encryption_key.rs b/common/nymsphinx/anonymous-replies/src/encryption_key.rs index c8ce8b851d..b52b8cea60 100644 --- a/common/nymsphinx/anonymous-replies/src/encryption_key.rs +++ b/common/nymsphinx/anonymous-replies/src/encryption_key.rs @@ -1,21 +1,20 @@ // Copyright 2021 - Nym Technologies SA // 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::OutputSize>; + GenericArray::OutputSize>; -pub type SurbEncryptionKeySize = ::KeySize; +pub type SurbEncryptionKeySize = ::KeySize; #[derive(Clone, Debug)] pub struct SurbEncryptionKey(CipherKey); @@ -45,7 +44,7 @@ impl SurbEncryptionKey { } pub fn try_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() != SurbEncryptionKeySize::to_usize() { + if bytes.len() != SurbEncryptionKeySize::USIZE { return Err(SurbEncryptionKeyError::BytesOfInvalidLengthError); } diff --git a/common/nymsphinx/anonymous-replies/src/lib.rs b/common/nymsphinx/anonymous-replies/src/lib.rs index f405c8043f..ce93c4099b 100644 --- a/common/nymsphinx/anonymous-replies/src/lib.rs +++ b/common/nymsphinx/anonymous-replies/src/lib.rs @@ -1,5 +1,6 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 + pub mod encryption_key; pub mod reply_surb; diff --git a/common/nymsphinx/anonymous-replies/src/reply_surb.rs b/common/nymsphinx/anonymous-replies/src/reply_surb.rs index 6e146d721a..b8b8ec04cf 100644 --- a/common/nymsphinx/anonymous-replies/src/reply_surb.rs +++ b/common/nymsphinx/anonymous-replies/src/reply_surb.rs @@ -1,10 +1,8 @@ // Copyright 2021 - Nym Technologies SA // 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(&self, serializer: S) -> Result<::Ok, ::Error> + fn serialize(&self, serializer: S) -> Result 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 { 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, }; diff --git a/gateway/gateway-requests/src/iv.rs b/gateway/gateway-requests/src/iv.rs index 88c4d800f5..0a7d428f1c 100644 --- a/gateway/gateway-requests/src/iv.rs +++ b/gateway/gateway-requests/src/iv.rs @@ -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 = ::NonceSize; +type NonceSize = ::IvSize; // I think 'IV' looks better than 'Iv', feel free to change that. #[allow(clippy::upper_case_acronyms)] diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index 1c41b3da64..98de45c377 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -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; // TODO: could using `Mac` trait here for OutputSize backfire? // Should hmac itself be exposed, imported and used instead? -pub type GatewayMacSize = ::OutputSize; +pub type GatewayMacSize = ::OutputSize; diff --git a/gateway/gateway-requests/src/registration/handshake/shared_key.rs b/gateway/gateway-requests/src/registration/handshake/shared_key.rs index 23c69409cc..3fc014db51 100644 --- a/gateway/gateway-requests/src/registration/handshake/shared_key.rs +++ b/gateway/gateway-requests/src/registration/handshake/shared_key.rs @@ -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; // we're using 16 byte long key in sphinx, so let's use the same one here type MacKeySize = U16; -type EncryptionKeySize = ::KeySize; +type EncryptionKeySize = ::KeySize; /// Shared key used when computing MAC for messages exchanged between client and its gateway. pub type MacKey = GenericArray;