diff --git a/Cargo.toml b/Cargo.toml index ae3b9655..06691488 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["askar-bbs", "askar-crypto"] [package] name = "aries-askar" -version = "0.2.2" +version = "0.2.3" authors = ["Hyperledger Aries Contributors "] edition = "2018" description = "Hyperledger Aries Askar secure storage" @@ -30,8 +30,8 @@ any = [] ffi = ["any", "ffi-support", "logger", "option-lock"] jemalloc = ["jemallocator"] logger = ["env_logger", "log"] -postgres = ["sqlx", "sqlx/postgres", "sqlx/tls"] -sqlite = ["num_cpus", "sqlx", "sqlx/sqlite"] +postgres = ["sqlx", "sqlx-core", "sqlx/postgres", "sqlx/tls"] +sqlite = ["num_cpus", "sqlx", "sqlx-core", "sqlx/sqlite"] pg_test = ["postgres"] [dev-dependencies] @@ -42,12 +42,12 @@ async-lock = "2.4" async-stream = "0.3" bs58 = "0.4" chrono = "0.4" -digest = "0.9" +digest = "0.10" env_logger = { version = "0.7", optional = true } ffi-support = { version = "0.4", optional = true } futures-lite = "1.11" hex = "0.4" -hmac = "0.11" +hmac = "0.12" indy-wql = "0.4" itertools = "0.10" jemallocator = { version = "0.3", optional = true } @@ -60,7 +60,7 @@ serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11" serde_cbor = "0.11" serde_json = "1.0" -sha2 = "0.9" +sha2 = "0.10" tokio = { version = "1.5", features = ["time"] } url = { version = "2.1", default-features = false } uuid = { version = "0.8", features = ["v4"] } @@ -72,11 +72,16 @@ path = "./askar-crypto" features = ["all_keys", "any_key", "argon2", "crypto_box", "std"] [dependencies.sqlx] -version = "0.5.9" +version = "=0.5.9" default-features = false features = ["chrono", "runtime-tokio-rustls"] optional = true +[dependencies.sqlx-core] +version = "=0.5.9" +default-features = false +optional = true + [profile.release] lto = true codegen-units = 1 diff --git a/askar-crypto/Cargo.toml b/askar-crypto/Cargo.toml index 2ffe1dab..ad1032a9 100644 --- a/askar-crypto/Cargo.toml +++ b/askar-crypto/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "askar-crypto" -version = "0.2.2" +version = "0.2.3" authors = ["Hyperledger Aries Contributors "] edition = "2018" description = "Hyperledger Aries Askar cryptography" @@ -24,7 +24,7 @@ aes = ["aes-core", "aes-gcm", "block-modes", "hmac"] bls = ["bls12_381", "hkdf"] chacha = ["chacha20poly1305"] crypto_box = ["alloc", "crypto_box_rs", "ed25519", "getrandom"] -ec_curves = ["k256", "p256"] +ec_curves = ["elliptic-curve", "k256", "p256"] ed25519 = ["curve25519-dalek", "ed25519-dalek", "x25519-dalek"] getrandom = ["rand/getrandom"] std_rng = ["getrandom", "rand/std", "rand/std_rng"] @@ -45,30 +45,31 @@ name = "kdf" harness = false [dependencies] -aead = "0.3" -aes-core = { package = "aes", version = "0.6", default-features = false, optional = true } -aes-gcm = { version = "0.8", default-features = false, features = ["aes"], optional = true } +aead = "0.4" +aes-core = { package = "aes", version = "0.7", default-features = false, optional = true } +aes-gcm = { version = "0.9", default-features = false, features = ["aes"], optional = true } arbitrary = { version = "1.0", optional = true, features = ["derive"] } -argon2 = { version = "0.1", default-features = false, features = ["password-hash"], optional = true } +argon2 = { version = "0.3", default-features = false, features = ["alloc", "password-hash"], optional = true } base64 = { version = "0.13", default-features = false } -blake2 = { version = "0.9", default-features = false } -block-modes = { version = "0.7", default-features = false, optional = true } +blake2 = { version = "0.10", default-features = false } +block-modes = { version = "0.8", default-features = false, optional = true } bls12_381 = { version = "0.6", default-features = false, features = ["groups", "zeroize"], optional = true } -chacha20 = { version = "0.6" } # should match chacha20poly1305 -chacha20poly1305 = { version = "0.7", default-features = false, features = ["chacha20", "xchacha20poly1305"], optional = true } -crypto_box_rs = { package = "crypto_box", version = "0.5", default-features = false, features = ["u64_backend"], optional = true } +chacha20 = { version = "0.7" } # should match chacha20poly1305 +chacha20poly1305 = { version = "0.8", default-features = false, optional = true } +crypto_box_rs = { package = "crypto_box", version = "0.6", default-features = false, features = ["u64_backend"], optional = true } curve25519-dalek = { version = "3.1", default-features = false, features = ["u64_backend"], optional = true } ed25519-dalek = { version = "1.0", default-features = false, features = ["u64_backend"], optional = true } -digest = "0.9" +elliptic-curve = { version = "0.11", optional = true } +digest = "0.10" group = "0.11" -hkdf = { version = "0.11", optional = true } -hmac = { version = "0.11", optional = true } -k256 = { version = "0.9", default-features = false, features = ["arithmetic", "ecdsa", "ecdh", "sha256", "zeroize"], optional = true } -p256 = { version = "0.9", default-features = false, features = ["arithmetic", "ecdsa", "ecdh", "zeroize"], optional = true } +hkdf = { version = "0.12", optional = true } +hmac = { version = "0.12", optional = true } +k256 = { version = "0.10", default-features = false, features = ["arithmetic", "ecdsa", "ecdh", "sha256"], optional = true } +p256 = { version = "0.10", default-features = false, features = ["arithmetic", "ecdsa", "ecdh"], optional = true } rand = { version = "0.8", default-features = false } serde = { version = "1.0", default-features = false, features = ["derive"] } serde-json-core = { version = "0.4", default-features = false } subtle = "2.4" -sha2 = { version = "0.9", default-features = false } -x25519-dalek = { version = "1.1", default-features = false, features = ["u64_backend"], optional = true } +sha2 = { version = "0.10", default-features = false } +x25519-dalek = { version = "=1.1", default-features = false, features = ["u64_backend"], optional = true } zeroize = { version = "1.4", features = ["zeroize_derive"] } diff --git a/askar-crypto/src/alg/aes/cbc_hmac.rs b/askar-crypto/src/alg/aes/cbc_hmac.rs index 1994c577..81348e2f 100644 --- a/askar-crypto/src/alg/aes/cbc_hmac.rs +++ b/askar-crypto/src/alg/aes/cbc_hmac.rs @@ -6,11 +6,11 @@ use aead::generic_array::ArrayLength; use aes_core::{Aes128, Aes256}; use block_modes::{ block_padding::Pkcs7, - cipher::{BlockCipher, NewBlockCipher}, + cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}, BlockMode, Cbc, }; -use digest::{BlockInput, FixedOutput, Reset, Update}; -use hmac::{Hmac, Mac, NewMac}; +use digest::{crypto_common::BlockSizeUser, Digest}; +use hmac::{Mac, SimpleHmac}; use subtle::ConstantTimeEq; use super::{AesKey, AesType, NonceSize, TagSize}; @@ -69,8 +69,8 @@ where impl KeyAeadInPlace for AesKey> where AesCbcHmac: AesType, - C: BlockCipher + NewBlockCipher, - D: Update + BlockInput + FixedOutput + Reset + Default + Clone, + C: BlockCipher + NewBlockCipher + BlockEncrypt + BlockDecrypt, + D: Digest + BlockSizeUser, C::KeySize: core::ops::Shl, >::Output: ArrayLength, { @@ -106,7 +106,7 @@ where .map_err(|_| err_msg!(Encryption, "AES-CBC encryption error"))?; let ctext_end = msg_len + pad_len; - let mut hmac = Hmac::::new_from_slice(&self.0[..C::KeySize::USIZE]) + let mut hmac = SimpleHmac::::new_from_slice(&self.0[..C::KeySize::USIZE]) .expect("Incompatible HMAC key length"); hmac.update(aad); hmac.update(nonce.as_ref()); @@ -141,7 +141,7 @@ where let ctext_end = buf_len - TagSize::::USIZE; let tag = GenericArray::>::from_slice(&buffer.as_ref()[ctext_end..]); - let mut hmac = Hmac::::new_from_slice(&self.0[..C::KeySize::USIZE]) + let mut hmac = SimpleHmac::::new_from_slice(&self.0[..C::KeySize::USIZE]) .expect("Incompatible HMAC key length"); hmac.update(aad); hmac.update(nonce.as_ref()); diff --git a/askar-crypto/src/alg/aes/key_wrap.rs b/askar-crypto/src/alg/aes/key_wrap.rs index e363e494..ee7d4e16 100644 --- a/askar-crypto/src/alg/aes/key_wrap.rs +++ b/askar-crypto/src/alg/aes/key_wrap.rs @@ -3,7 +3,7 @@ use core::{convert::TryInto, marker::PhantomData}; use aes_core::{Aes128, Aes256}; -use block_modes::cipher::{BlockCipher, NewBlockCipher}; +use block_modes::cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher}; use subtle::ConstantTimeEq; use super::{AesKey, AesType, NonceSize, TagSize}; @@ -54,7 +54,9 @@ impl KeyAeadInPlace for AesKey> where AesKeyWrap: AesType, C: NewBlockCipher as AesType>::KeySize> - + BlockCipher, + + BlockCipher + + BlockDecrypt + + BlockEncrypt, { fn encrypt_in_place( &self, diff --git a/askar-crypto/src/alg/aes/mod.rs b/askar-crypto/src/alg/aes/mod.rs index ce57989c..0d757de6 100644 --- a/askar-crypto/src/alg/aes/mod.rs +++ b/askar-crypto/src/alg/aes/mod.rs @@ -2,7 +2,7 @@ use core::fmt::{self, Debug, Formatter}; -use aead::{generic_array::ArrayLength, AeadInPlace, NewAead}; +use aead::{generic_array::ArrayLength, AeadCore, AeadInPlace, NewAead}; use aes_gcm::{Aes128Gcm, Aes256Gcm}; use serde::{Deserialize, Serialize}; use zeroize::Zeroize; @@ -174,9 +174,9 @@ impl AesType for A256Gcm { } // generic implementation applying to AesGcm -impl KeyAeadMeta for AesKey { - type NonceSize = ::NonceSize; - type TagSize = ::TagSize; +impl KeyAeadMeta for AesKey { + type NonceSize = ::NonceSize; + type TagSize = ::TagSize; } // generic implementation applying to AesGcm diff --git a/askar-crypto/src/alg/bls.rs b/askar-crypto/src/alg/bls.rs index a8165722..8f5ea39d 100644 --- a/askar-crypto/src/alg/bls.rs +++ b/askar-crypto/src/alg/bls.rs @@ -261,7 +261,7 @@ impl KeyMaterial for BlsKeyGen<'_> { self.salt.replace(match self.salt { None => Sha256::digest(SALT), - Some(salt) => Sha256::digest(salt.as_ref()), + Some(salt) => Sha256::digest(salt), }); let mut extract = hkdf::HkdfExtract::::new(Some(self.salt.as_ref().unwrap())); extract.input_ikm(self.ikm); diff --git a/askar-crypto/src/alg/chacha20.rs b/askar-crypto/src/alg/chacha20.rs index 134594c9..621cd612 100644 --- a/askar-crypto/src/alg/chacha20.rs +++ b/askar-crypto/src/alg/chacha20.rs @@ -2,7 +2,7 @@ use core::fmt::{self, Debug, Formatter}; -use aead::{Aead, AeadInPlace, NewAead}; +use aead::{AeadCore, AeadInPlace, NewAead}; use chacha20poly1305::{ChaCha20Poly1305, XChaCha20Poly1305}; use serde::{Deserialize, Serialize}; use zeroize::Zeroize; @@ -25,7 +25,7 @@ pub static JWK_KEY_TYPE: &'static str = "oct"; /// Trait implemented by supported ChaCha20 algorithms pub trait Chacha20Type: 'static { /// The AEAD implementation - type Aead: NewAead + Aead + AeadInPlace; + type Aead: NewAead + AeadCore + AeadInPlace; /// The associated algorithm type const ALG_TYPE: Chacha20Types; @@ -57,9 +57,9 @@ impl Chacha20Type for XC20P { type KeyType = ArrayKey<<::Aead as NewAead>::KeySize>; -type NonceSize = <::Aead as Aead>::NonceSize; +type NonceSize = <::Aead as AeadCore>::NonceSize; -type TagSize = <::Aead as Aead>::TagSize; +type TagSize = <::Aead as AeadCore>::TagSize; /// A ChaCha20 symmetric encryption key #[derive(Serialize, Deserialize, Zeroize)] diff --git a/askar-crypto/src/alg/ec_common.rs b/askar-crypto/src/alg/ec_common.rs new file mode 100644 index 00000000..d35eea2b --- /dev/null +++ b/askar-crypto/src/alg/ec_common.rs @@ -0,0 +1,18 @@ +use elliptic_curve::{ + bigint::{Encoding, Limb}, + Curve, SecretKey, +}; + +pub fn write_sk(sk: &SecretKey, out: &mut [u8]) { + let limbs = sk.as_scalar_core().as_limbs(); + debug_assert_eq!(out.len(), Limb::BYTE_SIZE * limbs.len()); + + for (src, dst) in limbs + .iter() + .rev() + .cloned() + .zip(out.chunks_exact_mut(Limb::BYTE_SIZE)) + { + dst.copy_from_slice(&src.to_be_bytes()); + } +} diff --git a/askar-crypto/src/alg/k256.rs b/askar-crypto/src/alg/k256.rs index 1e1ad649..ce0e6ab3 100644 --- a/askar-crypto/src/alg/k256.rs +++ b/askar-crypto/src/alg/k256.rs @@ -7,12 +7,16 @@ use k256::{ signature::{Signer, Verifier}, Signature, SigningKey, VerifyingKey, }, - elliptic_curve::{self, ecdh::diffie_hellman, sec1::Coordinates}, + elliptic_curve::{ + self, + ecdh::diffie_hellman, + sec1::{Coordinates, FromEncodedPoint, ToEncodedPoint}, + }, EncodedPoint, PublicKey, SecretKey, }; use subtle::ConstantTimeEq; -use super::{EcCurves, HasKeyAlg, KeyAlg}; +use super::{ec_common, EcCurves, HasKeyAlg, KeyAlg}; use crate::{ buffer::{ArrayKey, WriteBuffer}, error::Error, @@ -115,7 +119,7 @@ impl KeyGen for K256KeyPair { fn generate(mut rng: impl KeyMaterial) -> Result { ArrayKey::::temp(|buf| loop { rng.read_okm(buf); - if let Ok(key) = SecretKey::from_bytes(&buf) { + if let Ok(key) = SecretKey::from_be_bytes(&buf) { return Ok(Self::from_secret_key(key)); } }) @@ -125,13 +129,16 @@ impl KeyGen for K256KeyPair { impl KeySecretBytes for K256KeyPair { fn from_secret_bytes(key: &[u8]) -> Result { Ok(Self::from_secret_key( - SecretKey::from_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?, + SecretKey::from_be_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?, )) } fn with_secret_bytes(&self, f: impl FnOnce(Option<&[u8]>) -> O) -> O { if let Some(sk) = self.secret.as_ref() { - f(Some(sk.as_scalar_bytes().as_ref())) + ArrayKey::::temp(|arr| { + ec_common::write_sk(sk, &mut arr[..]); + f(Some(&arr)) + }) } else { f(None) } @@ -155,12 +162,11 @@ impl KeypairBytes for K256KeyPair { } fn with_keypair_bytes(&self, f: impl FnOnce(Option<&[u8]>) -> O) -> O { - if let Some(secret) = self.secret.as_ref() { + if let Some(sk) = self.secret.as_ref() { ArrayKey::<::KeypairSize>::temp(|arr| { - let sk_b = secret.as_scalar_bytes(); - let pk_enc = EncodedPoint::encode(self.public, true); - arr[..SECRET_KEY_LENGTH].copy_from_slice(sk_b.as_ref()); - arr[SECRET_KEY_LENGTH..].copy_from_slice(pk_enc.as_ref()); + ec_common::write_sk(sk, &mut arr[..SECRET_KEY_LENGTH]); + let pk_enc = self.public.to_encoded_point(true); + arr[SECRET_KEY_LENGTH..].copy_from_slice(pk_enc.as_bytes()); f(Some(&*arr)) }) } else { @@ -171,9 +177,7 @@ impl KeypairBytes for K256KeyPair { impl KeyPublicBytes for K256KeyPair { fn from_public_bytes(key: &[u8]) -> Result { - let pk = EncodedPoint::from_bytes(key) - .and_then(|pt| pt.decode()) - .map_err(|_| err_msg!(InvalidKeyData))?; + let pk = PublicKey::from_sec1_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?; Ok(Self { secret: None, public: pk, @@ -181,8 +185,7 @@ impl KeyPublicBytes for K256KeyPair { } fn with_public_bytes(&self, f: impl FnOnce(&[u8]) -> O) -> O { - let pt = EncodedPoint::encode(self.public, true); - f(pt.as_ref()) + f(self.public.to_encoded_point(true).as_bytes()) } } @@ -225,7 +228,7 @@ impl KeySigVerify for K256KeyPair { impl ToJwk for K256KeyPair { fn encode_jwk(&self, enc: &mut dyn JwkEncoder) -> Result<(), Error> { - let pk_enc = EncodedPoint::encode(self.public, false); + let pk_enc = self.public.to_encoded_point(false); let (x, y) = match pk_enc.coordinates() { Coordinates::Identity => { return Err(err_msg!( @@ -276,9 +279,10 @@ impl FromJwk for K256KeyPair { Ok(()) } })?; - let pk = EncodedPoint::from_affine_coordinates(pk_x.as_ref(), pk_y.as_ref(), false) - .decode() - .map_err(|_| err_msg!(InvalidKeyData))?; + let pk = Option::from(PublicKey::from_encoded_point( + &EncodedPoint::from_affine_coordinates(pk_x.as_ref(), pk_y.as_ref(), false), + )) + .ok_or_else(|| err_msg!(InvalidKeyData))?; if jwk.d.is_some() { ArrayKey::::temp(|arr| { if jwk.d.decode_base64(arr)? != arr.len() { @@ -305,7 +309,7 @@ impl KeyExchange for K256KeyPair { fn write_key_exchange(&self, other: &Self, out: &mut dyn WriteBuffer) -> Result<(), Error> { match self.secret.as_ref() { Some(sk) => { - let xk = diffie_hellman(sk.to_secret_scalar(), other.public.as_affine()); + let xk = diffie_hellman(sk.to_nonzero_scalar(), other.public.as_affine()); out.buffer_write(xk.as_bytes())?; Ok(()) } diff --git a/askar-crypto/src/alg/mod.rs b/askar-crypto/src/alg/mod.rs index 050b4d12..5bc921b2 100644 --- a/askar-crypto/src/alg/mod.rs +++ b/askar-crypto/src/alg/mod.rs @@ -39,6 +39,9 @@ pub mod ed25519; #[cfg_attr(docsrs, doc(cfg(feature = "ed25519")))] pub mod x25519; +#[cfg(feature = "ec_curves")] +mod ec_common; + #[cfg(feature = "k256")] #[cfg_attr(docsrs, doc(cfg(feature = "k256")))] pub mod k256; diff --git a/askar-crypto/src/alg/p256.rs b/askar-crypto/src/alg/p256.rs index 8fd06144..daa6b743 100644 --- a/askar-crypto/src/alg/p256.rs +++ b/askar-crypto/src/alg/p256.rs @@ -7,12 +7,16 @@ use p256::{ signature::{Signer, Verifier}, Signature, SigningKey, VerifyingKey, }, - elliptic_curve::{self, ecdh::diffie_hellman, sec1::Coordinates}, + elliptic_curve::{ + self, + ecdh::diffie_hellman, + sec1::{Coordinates, FromEncodedPoint, ToEncodedPoint}, + }, EncodedPoint, PublicKey, SecretKey, }; use subtle::ConstantTimeEq; -use super::{EcCurves, HasKeyAlg, KeyAlg}; +use super::{ec_common, EcCurves, HasKeyAlg, KeyAlg}; use crate::{ buffer::{ArrayKey, WriteBuffer}, error::Error, @@ -115,7 +119,7 @@ impl KeyGen for P256KeyPair { fn generate(mut rng: impl KeyMaterial) -> Result { ArrayKey::::temp(|buf| loop { rng.read_okm(buf); - if let Ok(key) = SecretKey::from_bytes(&buf) { + if let Ok(key) = SecretKey::from_be_bytes(&buf) { return Ok(Self::from_secret_key(key)); } }) @@ -125,13 +129,16 @@ impl KeyGen for P256KeyPair { impl KeySecretBytes for P256KeyPair { fn from_secret_bytes(key: &[u8]) -> Result { Ok(Self::from_secret_key( - SecretKey::from_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?, + SecretKey::from_be_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?, )) } fn with_secret_bytes(&self, f: impl FnOnce(Option<&[u8]>) -> O) -> O { if let Some(sk) = self.secret.as_ref() { - f(Some(sk.as_scalar_bytes().as_ref())) + ArrayKey::::temp(|arr| { + ec_common::write_sk(sk, &mut arr[..]); + f(Some(&arr)) + }) } else { f(None) } @@ -155,12 +162,11 @@ impl KeypairBytes for P256KeyPair { } fn with_keypair_bytes(&self, f: impl FnOnce(Option<&[u8]>) -> O) -> O { - if let Some(secret) = self.secret.as_ref() { + if let Some(sk) = self.secret.as_ref() { ArrayKey::<::KeypairSize>::temp(|arr| { - let sk_b = secret.as_scalar_bytes(); - let pk_enc = EncodedPoint::encode(self.public, true); - arr[..SECRET_KEY_LENGTH].copy_from_slice(sk_b.as_ref()); - arr[SECRET_KEY_LENGTH..].copy_from_slice(pk_enc.as_ref()); + ec_common::write_sk(sk, &mut arr[..SECRET_KEY_LENGTH]); + let pk_enc = self.public.to_encoded_point(true); + arr[SECRET_KEY_LENGTH..].copy_from_slice(pk_enc.as_bytes()); f(Some(&*arr)) }) } else { @@ -171,9 +177,7 @@ impl KeypairBytes for P256KeyPair { impl KeyPublicBytes for P256KeyPair { fn from_public_bytes(key: &[u8]) -> Result { - let pk = EncodedPoint::from_bytes(key) - .and_then(|pt| pt.decode()) - .map_err(|_| err_msg!(InvalidKeyData))?; + let pk = PublicKey::from_sec1_bytes(key).map_err(|_| err_msg!(InvalidKeyData))?; Ok(Self { secret: None, public: pk, @@ -181,8 +185,7 @@ impl KeyPublicBytes for P256KeyPair { } fn with_public_bytes(&self, f: impl FnOnce(&[u8]) -> O) -> O { - let pt = EncodedPoint::encode(self.public, true); - f(pt.as_ref()) + f(self.public.to_encoded_point(true).as_bytes()) } } @@ -225,7 +228,7 @@ impl KeySigVerify for P256KeyPair { impl ToJwk for P256KeyPair { fn encode_jwk(&self, enc: &mut dyn JwkEncoder) -> Result<(), Error> { - let pk_enc = EncodedPoint::encode(self.public, false); + let pk_enc = self.public.to_encoded_point(false); let (x, y) = match pk_enc.coordinates() { Coordinates::Identity => { return Err(err_msg!( @@ -276,9 +279,10 @@ impl FromJwk for P256KeyPair { Ok(()) } })?; - let pk = EncodedPoint::from_affine_coordinates(pk_x.as_ref(), pk_y.as_ref(), false) - .decode() - .map_err(|_| err_msg!(InvalidKeyData))?; + let pk = Option::from(PublicKey::from_encoded_point( + &EncodedPoint::from_affine_coordinates(pk_x.as_ref(), pk_y.as_ref(), false), + )) + .ok_or_else(|| err_msg!(InvalidKeyData))?; if jwk.d.is_some() { ArrayKey::::temp(|arr| { if jwk.d.decode_base64(arr)? != arr.len() { @@ -305,7 +309,7 @@ impl KeyExchange for P256KeyPair { fn write_key_exchange(&self, other: &Self, out: &mut dyn WriteBuffer) -> Result<(), Error> { match self.secret.as_ref() { Some(sk) => { - let xk = diffie_hellman(sk.to_secret_scalar(), other.public.as_affine()); + let xk = diffie_hellman(sk.to_nonzero_scalar(), other.public.as_affine()); out.buffer_write(xk.as_bytes())?; Ok(()) } diff --git a/askar-crypto/src/encrypt/crypto_box.rs b/askar-crypto/src/encrypt/crypto_box.rs index d62fa280..eb459a2f 100644 --- a/askar-crypto/src/encrypt/crypto_box.rs +++ b/askar-crypto/src/encrypt/crypto_box.rs @@ -4,8 +4,8 @@ use crate::{ buffer::Writer, generic_array::{typenum::Unsigned, GenericArray}, }; -use aead::AeadInPlace; -use blake2::{digest::Update, digest::VariableOutput, VarBlake2b}; +use aead::{AeadCore, AeadInPlace}; +use blake2::{digest::Update, digest::VariableOutput, Blake2bVar}; use crypto_box_rs::{self as cbox, SalsaBox}; use crate::{ @@ -22,9 +22,9 @@ pub const CBOX_KEY_LENGTH: usize = crate::alg::x25519::PUBLIC_KEY_LENGTH; /// The length of the salsa box tag pub const CBOX_TAG_LENGTH: usize = TagSize::::USIZE; -type NonceSize = ::NonceSize; +type NonceSize = ::NonceSize; -type TagSize = ::TagSize; +type TagSize = ::TagSize; #[inline] fn secret_key_from(kp: &X25519KeyPair) -> Result { @@ -53,7 +53,8 @@ pub fn crypto_box( ) -> Result<(), Error> { let sender_sk = secret_key_from(sender_sk)?; let nonce = nonce_from(nonce)?; - let box_inst = SalsaBox::new(&recip_pk.public, &sender_sk); + let pk = recip_pk.public.to_bytes().into(); + let box_inst = SalsaBox::new(&pk, &sender_sk); let tag = box_inst .encrypt_in_place_detached(nonce, &[], buffer.as_mut()) .map_err(|_| err_msg!(Encryption, "Crypto box AEAD encryption error"))?; @@ -76,7 +77,8 @@ pub fn crypto_box_open( } // the tag is prepended let tag = GenericArray::clone_from_slice(&buffer.as_ref()[..CBOX_TAG_LENGTH]); - let box_inst = SalsaBox::new(&sender_pk.public, &recip_sk); + let pk = sender_pk.public.to_bytes().into(); + let box_inst = SalsaBox::new(&pk, &recip_sk); box_inst .decrypt_in_place_detached(nonce, &[], &mut buffer.as_mut()[CBOX_TAG_LENGTH..], &tag) .map_err(|_| err_msg!(Encryption, "Crypto box AEAD decryption error"))?; @@ -89,11 +91,11 @@ pub fn crypto_box_seal_nonce( ephemeral_pk: &[u8], recip_pk: &[u8], ) -> Result<[u8; CBOX_NONCE_LENGTH], Error> { - let mut key_hash = VarBlake2b::new(CBOX_NONCE_LENGTH).unwrap(); + let mut key_hash = Blake2bVar::new(CBOX_NONCE_LENGTH).unwrap(); key_hash.update(ephemeral_pk); key_hash.update(recip_pk); let mut nonce = [0u8; CBOX_NONCE_LENGTH]; - key_hash.finalize_variable(|hash| nonce.copy_from_slice(hash)); + key_hash.finalize_variable(&mut nonce).unwrap(); Ok(nonce) } diff --git a/askar-crypto/src/kdf/argon2.rs b/askar-crypto/src/kdf/argon2.rs index 9fb62b45..aac17486 100644 --- a/askar-crypto/src/kdf/argon2.rs +++ b/askar-crypto/src/kdf/argon2.rs @@ -68,17 +68,16 @@ impl KeyDerivation for Argon2<'_> { "Output length exceeds max for argon2i hash" )); } - let context = argon2::Argon2::new( - None, - self.params.time_cost, - self.params.mem_cost, - 1, + let mut pbuild = argon2::ParamsBuilder::new(); + pbuild.m_cost(self.params.mem_cost).unwrap(); + pbuild.t_cost(self.params.time_cost).unwrap(); + argon2::Argon2::new( + self.params.alg, self.params.version, + pbuild.params().unwrap(), ) - .map_err(|_| err_msg!(Unexpected, "Error creating hasher"))?; - context - .hash_password_into(self.params.alg, self.password, self.salt, &[], key_output) - .map_err(|_| err_msg!(Unexpected, "Error deriving key")) + .hash_password_into(self.password, self.salt, key_output) + .map_err(|_| err_msg!(Unexpected, "Error deriving key")) } } diff --git a/askar-crypto/src/kdf/concat.rs b/askar-crypto/src/kdf/concat.rs index 3effa53c..7a1707ea 100644 --- a/askar-crypto/src/kdf/concat.rs +++ b/askar-crypto/src/kdf/concat.rs @@ -2,7 +2,7 @@ use core::{fmt::Debug, marker::PhantomData}; -use digest::Digest; +use digest::{Digest, FixedOutputReset}; use crate::generic_array::{typenum::Unsigned, GenericArray}; @@ -29,7 +29,7 @@ pub struct ConcatKDFParams<'p> { impl ConcatKDF where - H: Digest, + H: Digest + FixedOutputReset, { /// Perform the key derivation and write the result to the provided buffer pub fn derive_key( @@ -98,7 +98,10 @@ impl ConcatKDFHash { } /// Complete this pass of the key derivation, returning the result - pub fn finish_pass(&mut self) -> GenericArray { + pub fn finish_pass(&mut self) -> GenericArray + where + H: FixedOutputReset, + { self.hasher.finalize_reset() } } diff --git a/askar-crypto/src/random.rs b/askar-crypto/src/random.rs index 37d7477b..e7e8cada 100644 --- a/askar-crypto/src/random.rs +++ b/askar-crypto/src/random.rs @@ -4,7 +4,7 @@ use core::fmt::{self, Debug, Formatter}; use aead::generic_array::{typenum::Unsigned, GenericArray}; use chacha20::{ - cipher::{NewStreamCipher, SyncStreamCipher}, + cipher::{NewCipher, StreamCipher}, ChaCha20, }; use rand::{CryptoRng, RngCore, SeedableRng}; @@ -14,7 +14,7 @@ use crate::buffer::SecretBytes; use crate::error::Error; /// The expected length of a seed for `fill_random_deterministic` -pub const DETERMINISTIC_SEED_LENGTH: usize = ::KeySize::USIZE; +pub const DETERMINISTIC_SEED_LENGTH: usize = ::KeySize::USIZE; /// Combined trait for CryptoRng and RngCore pub trait Rng: CryptoRng + RngCore + Debug {} diff --git a/src/protect/hmac_key.rs b/src/protect/hmac_key.rs index 3c8f543e..611640b7 100644 --- a/src/protect/hmac_key.rs +++ b/src/protect/hmac_key.rs @@ -3,10 +3,8 @@ use std::{ marker::PhantomData, }; -use hmac::{ - digest::{BlockInput, FixedOutput, Reset, Update}, - Hmac, Mac, NewMac, -}; +use digest::crypto_common::BlockSizeUser; +use hmac::{digest::Digest, Mac, SimpleHmac}; use serde::{Deserialize, Serialize}; use crate::{ @@ -77,7 +75,7 @@ impl> KeyGen for HmacKey { } pub trait HmacDerive { - type Hash: BlockInput + Default + Reset + Update + Clone + FixedOutput; + type Hash: Digest + BlockSizeUser; type Key: AsRef<[u8]>; fn hmac_deriver<'d>(&'d self, inputs: &'d [&'d [u8]]) @@ -86,7 +84,7 @@ pub trait HmacDerive { impl> HmacDerive for HmacKey where - H: BlockInput + Default + Reset + Update + Clone + FixedOutput, + H: Digest + BlockSizeUser, { type Hash = H; type Key = Self; @@ -113,7 +111,7 @@ pub struct HmacDeriver<'d, H, K: ?Sized> { impl KeyDerivation for HmacDeriver<'_, H, K> where K: AsRef<[u8]> + ?Sized, - H: BlockInput + Default + Reset + Update + Clone + FixedOutput, + H: Digest + BlockSizeUser, { fn derive_key_bytes(&mut self, key_output: &mut [u8]) -> Result<(), crypto::Error> { if key_output.len() > H::OutputSize::USIZE { @@ -122,7 +120,7 @@ where "invalid length for hmac output", )); } - let mut hmac = Hmac::::new_from_slice(self.key.as_ref()).map_err(|_| { + let mut hmac = SimpleHmac::::new_from_slice(self.key.as_ref()).map_err(|_| { crypto::Error::from_msg(crypto::ErrorKind::Encryption, "invalid length for hmac key") })?; for msg in self.inputs { diff --git a/wrappers/python/aries_askar/version.py b/wrappers/python/aries_askar/version.py index 2a0a134c..ab939630 100644 --- a/wrappers/python/aries_askar/version.py +++ b/wrappers/python/aries_askar/version.py @@ -1,3 +1,3 @@ """aries_askar library wrapper version.""" -__version__ = "0.2.2" +__version__ = "0.2.3"