Project import generated by Copybara.
GitOrigin-RevId: 06b0c815d958bef0a60978d0766d65af839e37b6
Change-Id: Ifac0c45ae509ca8a8ed793fac5c981d4e23d3bf9
diff --git a/nearby/crypto/crypto_provider_rustcrypto/Cargo.toml b/nearby/crypto/crypto_provider_rustcrypto/Cargo.toml
index e0bf534..a0638ff 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/Cargo.toml
+++ b/nearby/crypto/crypto_provider_rustcrypto/Cargo.toml
@@ -6,15 +6,22 @@
[dependencies]
aead = "0.5.1"
-aes-gcm-siv = { version = "0.11.1", features = ["aes"] }
-crypto_provider.workspace = true
+aes-gcm-siv = { version = "0.11.1", features = [
+ "aes",
+], default-features = false }
+aes-gcm = { version = "0.10.3", features = [
+ "aes",
+], default-features = false }
+crypto_provider = { workspace = true }
hmac.workspace = true
hkdf.workspace = true
sha2.workspace = true
x25519-dalek.workspace = true
p256 = { workspace = true, features = ["ecdh"], default-features = false }
sec1.workspace = true
-ed25519-dalek = { workspace = true, default-features = false, features = ["rand_core"] }
+ed25519-dalek = { workspace = true, default-features = false, features = [
+ "rand_core",
+] }
rand = { workspace = true, default-features = false }
rand_core.workspace = true
subtle.workspace = true
@@ -31,5 +38,12 @@
[features]
default = ["alloc", "rand_chacha"]
-std = ["ed25519-dalek/default", "rand/std", "rand/std_rng", "crypto_provider/std", "crypto_provider/alloc"]
-alloc = ["aead/bytes"]
+std = [
+ "alloc",
+ "ed25519-dalek/default",
+ "rand/std",
+ "rand/std_rng",
+ "crypto_provider/std",
+ "crypto_provider/alloc",
+]
+alloc = ["aead/bytes", "aead/alloc", "cbc/alloc", "crypto_provider/alloc"]
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm.rs
new file mode 100644
index 0000000..f1d9e0f
--- /dev/null
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm.rs
@@ -0,0 +1,123 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+#[cfg(feature = "alloc")]
+use aead::Payload;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+// RustCrypto defined traits and types
+use aes::cipher::typenum::consts::{U12, U16};
+use aes::cipher::BlockCipher;
+use aes::cipher::BlockEncrypt;
+#[cfg(feature = "alloc")]
+use aes_gcm::aead::Aead as _;
+use aes_gcm::aead::KeyInit;
+use aes_gcm::AeadInPlace as _;
+
+// CryptoProvider traits and types
+use crypto_provider::aead::{Aead, AeadError, AeadInit};
+
+pub struct AesGcm<A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit>(
+ aes_gcm::AesGcm<A, U12>,
+);
+
+impl<A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit> crypto_provider::aead::AesGcm
+ for AesGcm<A>
+{
+}
+
+impl<K: crypto_provider::aes::AesKey, A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit>
+ AeadInit<K> for AesGcm<A>
+{
+ fn new(key: &K) -> Self {
+ Self(aes_gcm::AesGcm::<A, U12>::new(key.as_slice().into()))
+ }
+}
+
+impl<A: aes::cipher::BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit> Aead for AesGcm<A> {
+ const TAG_SIZE: usize = 16;
+ type Nonce = [u8; 12];
+ type Tag = [u8; 16];
+
+ #[cfg(feature = "alloc")]
+ fn encrypt(&self, msg: &[u8], aad: &[u8], nonce: &Self::Nonce) -> Result<Vec<u8>, AeadError> {
+ self.0
+ .encrypt(aes_gcm::Nonce::from_slice(nonce), Payload { msg, aad })
+ .map_err(|_| AeadError)
+ }
+
+ fn encrypt_detached(
+ &self,
+ msg: &mut [u8],
+ aad: &[u8],
+ nonce: &Self::Nonce,
+ ) -> Result<Self::Tag, AeadError> {
+ self.0
+ .encrypt_in_place_detached(aes_gcm::Nonce::from_slice(nonce), aad, msg)
+ .map(|arr| arr.into())
+ .map_err(|_| AeadError)
+ }
+
+ #[cfg(feature = "alloc")]
+ fn decrypt(&self, msg: &[u8], aad: &[u8], nonce: &Self::Nonce) -> Result<Vec<u8>, AeadError> {
+ self.0
+ .decrypt(aes_gcm::Nonce::from_slice(nonce), Payload { msg, aad })
+ .map_err(|_| AeadError)
+ }
+
+ fn decrypt_detached(
+ &self,
+ msg: &mut [u8],
+ aad: &[u8],
+ nonce: &Self::Nonce,
+ tag: &Self::Tag,
+ ) -> Result<(), AeadError> {
+ self.0
+ .decrypt_in_place_detached(aes_gcm::Nonce::from_slice(nonce), aad, msg, tag.into())
+ .map_err(|_| AeadError)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use core::marker::PhantomData;
+
+ use crypto_provider_test::aead::aes_gcm::*;
+ use crypto_provider_test::aes::*;
+
+ use super::*;
+
+ #[apply(aes_128_gcm_test_cases)]
+ fn aes_gcm_128_test(testcase: CryptoProviderTestCase<AesGcm<aes::Aes128>>) {
+ testcase(PhantomData);
+ }
+
+ #[apply(aes_128_gcm_test_cases_detached)]
+ fn aes_128_gcm_test_detached(testcase: CryptoProviderTestCase<AesGcm<aes::Aes128>>) {
+ testcase(PhantomData);
+ }
+
+ #[apply(aes_256_gcm_test_cases)]
+ fn aes_gcm_256_test(testcase: CryptoProviderTestCase<AesGcm<aes::Aes256>>) {
+ testcase(PhantomData);
+ }
+
+ #[apply(aes_256_gcm_test_cases_detached)]
+ fn aes_256_gcm_test_detached(testcase: CryptoProviderTestCase<AesGcm<aes::Aes256>>) {
+ testcase(PhantomData);
+ }
+}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm_siv.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm_siv.rs
index 402c2ed..408017f 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm_siv.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aead/aes_gcm_siv.rs
@@ -12,74 +12,118 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-use aes_gcm_siv::{AeadInPlace, Aes128GcmSiv, Aes256GcmSiv, KeyInit, Nonce};
+#[cfg(feature = "alloc")]
extern crate alloc;
+#[cfg(feature = "alloc")]
+use aead::Payload;
+#[cfg(feature = "alloc")]
use alloc::vec::Vec;
-use crypto_provider::aead::{Aead, AeadError};
-use crypto_provider::aead::aes_gcm_siv::AesGcmSiv;
-use crypto_provider::aes::{Aes128Key, Aes256Key, AesKey};
+// RustCrypto defined traits and types
+use aes::cipher::typenum::consts::U16;
+use aes::cipher::BlockCipher;
+use aes::cipher::BlockEncrypt;
+#[cfg(feature = "alloc")]
+use aes_gcm_siv::aead::Aead as _;
+use aes_gcm_siv::aead::KeyInit;
+use aes_gcm_siv::AeadInPlace as _;
-pub struct AesGcmSiv128(Aes128GcmSiv);
+// CryptoProvider traits and types
+use crypto_provider::aead::{Aead, AeadError, AeadInit};
-impl AesGcmSiv for AesGcmSiv128 {}
+pub struct AesGcmSiv<A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit>(
+ aes_gcm_siv::AesGcmSiv<A>,
+);
-impl Aead for AesGcmSiv128 {
- const TAG_SIZE: usize = 16;
- type Nonce = [u8; 12];
- type Key = Aes128Key;
+impl<A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit> crypto_provider::aead::AesGcmSiv
+ for AesGcmSiv<A>
+{
+}
- fn new(key: &Self::Key) -> Self {
- Self(Aes128GcmSiv::new(key.as_slice().into()))
- }
-
- fn encrypt(&self, msg: &mut Vec<u8>, aad: &[u8], nonce: &[u8; 12]) -> Result<(), AeadError> {
- self.0.encrypt_in_place(Nonce::from_slice(nonce), aad, msg).map_err(|_| AeadError)
- }
-
- fn decrypt(&self, msg: &mut Vec<u8>, aad: &[u8], nonce: &[u8; 12]) -> Result<(), AeadError> {
- self.0.decrypt_in_place(Nonce::from_slice(nonce), aad, msg).map_err(|_| AeadError)
+impl<K: crypto_provider::aes::AesKey, A: BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit>
+ AeadInit<K> for AesGcmSiv<A>
+{
+ fn new(key: &K) -> Self {
+ Self(aes_gcm_siv::AesGcmSiv::<A>::new(key.as_slice().into()))
}
}
-pub struct AesGcmSiv256(Aes256GcmSiv);
-
-impl AesGcmSiv for AesGcmSiv256 {}
-
-impl Aead for AesGcmSiv256 {
+impl<A: aes::cipher::BlockCipher<BlockSize = U16> + BlockEncrypt + KeyInit> Aead for AesGcmSiv<A> {
const TAG_SIZE: usize = 16;
type Nonce = [u8; 12];
- type Key = Aes256Key;
+ type Tag = [u8; 16];
- fn new(key: &Self::Key) -> Self {
- Self(Aes256GcmSiv::new(key.as_slice().into()))
+ #[cfg(feature = "alloc")]
+ fn encrypt(&self, msg: &[u8], aad: &[u8], nonce: &Self::Nonce) -> Result<Vec<u8>, AeadError> {
+ self.0
+ .encrypt(aes_gcm_siv::Nonce::from_slice(nonce), Payload { msg, aad })
+ .map_err(|_| AeadError)
}
- fn encrypt(&self, msg: &mut Vec<u8>, aad: &[u8], nonce: &[u8; 12]) -> Result<(), AeadError> {
- self.0.encrypt_in_place(Nonce::from_slice(nonce), aad, msg).map_err(|_| AeadError)
+ fn encrypt_detached(
+ &self,
+ msg: &mut [u8],
+ aad: &[u8],
+ nonce: &Self::Nonce,
+ ) -> Result<Self::Tag, AeadError> {
+ self.0
+ .encrypt_in_place_detached(aes_gcm_siv::Nonce::from_slice(nonce), aad, msg)
+ .map(|arr| arr.into())
+ .map_err(|_| AeadError)
}
- fn decrypt(&self, msg: &mut Vec<u8>, aad: &[u8], nonce: &[u8; 12]) -> Result<(), AeadError> {
- self.0.decrypt_in_place(Nonce::from_slice(nonce), aad, msg).map_err(|_| AeadError)
+ #[cfg(feature = "alloc")]
+ fn decrypt(&self, msg: &[u8], aad: &[u8], nonce: &Self::Nonce) -> Result<Vec<u8>, AeadError> {
+ self.0
+ .decrypt(aes_gcm_siv::Nonce::from_slice(nonce), Payload { msg, aad })
+ .map_err(|_| AeadError)
+ }
+
+ fn decrypt_detached(
+ &self,
+ msg: &mut [u8],
+ aad: &[u8],
+ nonce: &Self::Nonce,
+ tag: &Self::Tag,
+ ) -> Result<(), AeadError> {
+ self.0
+ .decrypt_in_place_detached(aes_gcm_siv::Nonce::from_slice(nonce), aad, msg, tag.into())
+ .map_err(|_| AeadError)
}
}
#[cfg(test)]
mod tests {
use core::marker::PhantomData;
-
use crypto_provider_test::aead::aes_gcm_siv::*;
use crypto_provider_test::aes::*;
-
- use super::*;
+ use crypto_provider_test::prelude::apply;
#[apply(aes_128_gcm_siv_test_cases)]
- fn aes_gcm_siv_128_test(testcase: CryptoProviderTestCase<AesGcmSiv128>) {
+ fn aes_gcm_siv_128_test(
+ testcase: CryptoProviderTestCase<crate::aead::aes_gcm_siv::AesGcmSiv<aes::Aes128>>,
+ ) {
+ testcase(PhantomData);
+ }
+
+ #[apply(aes_128_gcm_siv_test_cases_detached)]
+ fn aes_gcm_siv_128_test_detached(
+ testcase: CryptoProviderTestCase<crate::aead::aes_gcm_siv::AesGcmSiv<aes::Aes128>>,
+ ) {
testcase(PhantomData);
}
#[apply(aes_256_gcm_siv_test_cases)]
- fn aes_gcm_siv_256_test(testcase: CryptoProviderTestCase<AesGcmSiv256>) {
+ fn aes_gcm_siv_256_test(
+ testcase: CryptoProviderTestCase<crate::aead::aes_gcm_siv::AesGcmSiv<aes::Aes256>>,
+ ) {
+ testcase(PhantomData);
+ }
+
+ #[apply(aes_256_gcm_siv_test_cases_detached)]
+ fn aes_gcm_siv_256_test_detached(
+ testcase: CryptoProviderTestCase<crate::aead::aes_gcm_siv::AesGcmSiv<aes::Aes256>>,
+ ) {
testcase(PhantomData);
}
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aead/mod.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aead/mod.rs
index 7fc561b..e4c2c60 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/aead/mod.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aead/mod.rs
@@ -13,3 +13,5 @@
// limitations under the License.
pub(crate) mod aes_gcm_siv;
+
+pub(crate) mod aes_gcm;
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aes/cbc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aes/cbc.rs
deleted file mode 100644
index 06d7224..0000000
--- a/nearby/crypto/crypto_provider_rustcrypto/src/aes/cbc.rs
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2022 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-extern crate alloc;
-use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
-use aes::Aes256;
-use alloc::vec::Vec;
-use crypto_provider::aes::{
- cbc::{AesCbcIv, DecryptionError},
- Aes256Key, AesKey,
-};
-
-/// RustCrypto implementation of AES-CBC with PKCS7 padding
-pub enum AesCbcPkcs7Padded {}
-impl crypto_provider::aes::cbc::AesCbcPkcs7Padded for AesCbcPkcs7Padded {
- fn encrypt(key: &Aes256Key, iv: &AesCbcIv, message: &[u8]) -> Vec<u8> {
- let encryptor = cbc::Encryptor::<Aes256>::new(key.as_array().into(), iv.into());
- encryptor.encrypt_padded_vec_mut::<Pkcs7>(message)
- }
-
- fn decrypt(
- key: &Aes256Key,
- iv: &AesCbcIv,
- ciphertext: &[u8],
- ) -> Result<Vec<u8>, DecryptionError> {
- cbc::Decryptor::<Aes256>::new(key.as_array().into(), iv.into())
- .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
- .map_err(|_| DecryptionError::BadPadding)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::AesCbcPkcs7Padded;
- use core::marker::PhantomData;
- use crypto_provider_test::aes::cbc::*;
-
- #[apply(aes_256_cbc_test_cases)]
- fn aes_256_cbc_test(testcase: CryptoProviderTestCase<AesCbcPkcs7Padded>) {
- testcase(PhantomData);
- }
-}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/cbc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/cbc.rs
new file mode 100644
index 0000000..c6d74f0
--- /dev/null
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/cbc.rs
@@ -0,0 +1,102 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit};
+use aes::Aes256;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+use crypto_provider::{
+ aes::{
+ cbc::{AesCbcIv, DecryptionError, EncryptionError},
+ Aes256Key, AesKey,
+ },
+ tinyvec::SliceVec,
+};
+
+/// RustCrypto implementation of AES-CBC with PKCS7 padding
+pub enum AesCbcPkcs7Padded {}
+impl crypto_provider::aes::cbc::AesCbcPkcs7Padded for AesCbcPkcs7Padded {
+ #[cfg(feature = "alloc")]
+ fn encrypt(key: &Aes256Key, iv: &AesCbcIv, message: &[u8]) -> Vec<u8> {
+ let encryptor = cbc::Encryptor::<Aes256>::new(key.as_array().into(), iv.into());
+ encryptor.encrypt_padded_vec_mut::<Pkcs7>(message)
+ }
+
+ fn encrypt_in_place(
+ key: &Aes256Key,
+ iv: &AesCbcIv,
+ message: &mut SliceVec<u8>,
+ ) -> Result<(), EncryptionError> {
+ let encryptor = cbc::Encryptor::<Aes256>::new(key.as_array().into(), iv.into());
+ let message_len = message.len();
+ // Set the length so encrypt_padded_mut can write using the full capacity
+ // (Unlike `Vec.set_len`, `SliceVec.set_len` is safe and won't panic if len <= capacity)
+ message.set_len(message.capacity());
+ encryptor
+ .encrypt_padded_mut::<Pkcs7>(message, message_len)
+ .map(|result| result.len())
+ // `SliceVec.set_len` is safe, and won't panic because `encrypt_padded_mut` never
+ // returns a slice longer than the given buffer.
+ .map(|new_len| message.set_len(new_len))
+ .map_err(|_| {
+ message.set_len(message_len); // Set the buffer back to its original length
+ EncryptionError::PaddingFailed
+ })
+ }
+
+ #[cfg(feature = "alloc")]
+ fn decrypt(
+ key: &Aes256Key,
+ iv: &AesCbcIv,
+ ciphertext: &[u8],
+ ) -> Result<Vec<u8>, DecryptionError> {
+ cbc::Decryptor::<Aes256>::new(key.as_array().into(), iv.into())
+ .decrypt_padded_vec_mut::<Pkcs7>(ciphertext)
+ .map_err(|_| DecryptionError::BadPadding)
+ }
+
+ fn decrypt_in_place(
+ key: &Aes256Key,
+ iv: &AesCbcIv,
+ ciphertext: &mut SliceVec<u8>,
+ ) -> Result<(), DecryptionError> {
+ // Decrypted size is always smaller than the input size because of padding, so we don't need
+ // to set the length to the full capacity.
+ cbc::Decryptor::<Aes256>::new(key.as_array().into(), iv.into())
+ .decrypt_padded_mut::<Pkcs7>(ciphertext)
+ .map(|result| result.len())
+ // `SliceVec.set_len` is safe, and won't panic because decrypted result length is always
+ // smaller than the input size.
+ .map(|new_len| ciphertext.set_len(new_len))
+ .map_err(|_| {
+ ciphertext.as_mut().fill(0);
+ DecryptionError::BadPadding
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::AesCbcPkcs7Padded;
+ use core::marker::PhantomData;
+ use crypto_provider_test::aes::cbc::*;
+
+ #[apply(aes_256_cbc_test_cases)]
+ fn aes_256_cbc_test(testcase: CryptoProviderTestCase<AesCbcPkcs7Padded>) {
+ testcase(PhantomData);
+ }
+}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aes/ctr.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/ctr.rs
similarity index 88%
rename from nearby/crypto/crypto_provider_rustcrypto/src/aes/ctr.rs
rename to nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/ctr.rs
index 85cdac6..09ae557 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/aes/ctr.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/ctr.rs
@@ -33,11 +33,7 @@
}
}
- fn encrypt(&mut self, data: &mut [u8]) {
- self.cipher.apply_keystream(data);
- }
-
- fn decrypt(&mut self, data: &mut [u8]) {
+ fn apply_keystream(&mut self, data: &mut [u8]) {
self.cipher.apply_keystream(data);
}
}
@@ -59,11 +55,7 @@
}
}
- fn encrypt(&mut self, data: &mut [u8]) {
- self.cipher.apply_keystream(data);
- }
-
- fn decrypt(&mut self, data: &mut [u8]) {
+ fn apply_keystream(&mut self, data: &mut [u8]) {
self.cipher.apply_keystream(data);
}
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/aes/mod.rs b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/mod.rs
similarity index 98%
rename from nearby/crypto/crypto_provider_rustcrypto/src/aes/mod.rs
rename to nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/mod.rs
index c71f2ec..4c04bf5 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/aes/mod.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/aes_cp/mod.rs
@@ -22,7 +22,6 @@
};
/// Module implementing AES-CBC.
-#[cfg(feature = "alloc")]
pub(crate) mod cbc;
pub(crate) mod ctr;
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/ed25519.rs b/nearby/crypto/crypto_provider_rustcrypto/src/ed25519.rs
index d11a5ea..ce8089e 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/ed25519.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/ed25519.rs
@@ -15,8 +15,8 @@
use ed25519_dalek::Signer;
use crypto_provider::ed25519::{
- InvalidBytes, RawPrivateKey, RawPublicKey, RawSignature, Signature as _, SignatureError,
- PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH,
+ InvalidBytes, RawPrivateKey, RawPrivateKeyPermit, RawPublicKey, RawSignature, Signature as _,
+ SignatureError, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH,
};
pub struct Ed25519;
@@ -33,11 +33,11 @@
type PublicKey = PublicKey;
type Signature = Signature;
- fn private_key(&self) -> [u8; PRIVATE_KEY_LENGTH] {
+ fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> [u8; PRIVATE_KEY_LENGTH] {
self.0.to_bytes()
}
- fn from_private_key(bytes: &RawPrivateKey) -> Self {
+ fn from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self {
Self(ed25519_dalek::SigningKey::from_bytes(bytes))
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/hkdf_rc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/hkdf_cp.rs
similarity index 86%
rename from nearby/crypto/crypto_provider_rustcrypto/src/hkdf_rc.rs
rename to nearby/crypto/crypto_provider_rustcrypto/src/hkdf_cp.rs
index aba0d4a..48380fa 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/hkdf_rc.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/hkdf_cp.rs
@@ -22,7 +22,7 @@
use hmac::digest::{HashMarker, OutputSizeUser};
/// RustCrypto based hkdf implementation
-pub struct Hkdf<D>
+pub struct Hkdf<D>(hkdf::Hkdf<D>)
where
D: OutputSizeUser,
D: CoreProxy,
@@ -33,10 +33,7 @@
+ Default
+ Clone,
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
- Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
-{
- hkdf_impl: hkdf::Hkdf<D>,
-}
+ Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero;
impl<D> crypto_provider::hkdf::Hkdf for Hkdf<D>
where
@@ -52,7 +49,7 @@
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
fn new(salt: Option<&[u8]>, ikm: &[u8]) -> Self {
- Hkdf { hkdf_impl: hkdf::Hkdf::new(salt, ikm) }
+ Hkdf(hkdf::Hkdf::new(salt, ikm))
}
fn expand_multi_info(
@@ -60,11 +57,11 @@
info_components: &[&[u8]],
okm: &mut [u8],
) -> Result<(), InvalidLength> {
- self.hkdf_impl.expand_multi_info(info_components, okm).map_err(|_| InvalidLength)
+ self.0.expand_multi_info(info_components, okm).map_err(|_| InvalidLength)
}
fn expand(&self, info: &[u8], okm: &mut [u8]) -> Result<(), InvalidLength> {
- self.hkdf_impl.expand(info, okm).map_err(|_| InvalidLength)
+ self.0.expand(info, okm).map_err(|_| InvalidLength)
}
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/hmac_cp.rs
similarity index 72%
rename from nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs
rename to nearby/crypto/crypto_provider_rustcrypto/src/hmac_cp.rs
index dfda208..d8cef33 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/hmac_rc.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/hmac_cp.rs
@@ -23,7 +23,7 @@
use hmac::Mac;
/// RustCrypto based hmac implementation
-pub struct Hmac<D>
+pub struct Hmac<D>(hmac::Hmac<D>)
where
D: OutputSizeUser,
D: CoreProxy,
@@ -34,43 +34,38 @@
+ Default
+ Clone,
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
- Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
-{
- hmac_impl: hmac::Hmac<D>,
-}
+ Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero;
impl crypto_provider::hmac::Hmac<32> for Hmac<sha2::Sha256> {
#[allow(clippy::expect_used)]
fn new_from_key(key: [u8; 32]) -> Self {
hmac::Hmac::new_from_slice(&key)
- .map(|hmac| Self { hmac_impl: hmac })
+ .map(Self)
.expect("length will always be valid because input key is of fixed size")
}
fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
- hmac::Hmac::new_from_slice(key)
- .map(|hmac| Self { hmac_impl: hmac })
- .map_err(|_| InvalidLength)
+ hmac::Hmac::new_from_slice(key).map(Self).map_err(|_| InvalidLength)
}
fn update(&mut self, data: &[u8]) {
- self.hmac_impl.update(data);
+ self.0.update(data);
}
fn finalize(self) -> [u8; 32] {
- self.hmac_impl.finalize().into_bytes().into()
+ self.0.finalize().into_bytes().into()
}
fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
- self.hmac_impl.verify_slice(tag).map_err(|_| MacError)
+ self.0.verify_slice(tag).map_err(|_| MacError)
}
fn verify(self, tag: [u8; 32]) -> Result<(), MacError> {
- self.hmac_impl.verify(&tag.into()).map_err(|_| MacError)
+ self.0.verify(&tag.into()).map_err(|_| MacError)
}
fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
- self.hmac_impl.verify_truncated_left(tag).map_err(|_| MacError)
+ self.0.verify_truncated_left(tag).map_err(|_| MacError)
}
}
@@ -78,34 +73,32 @@
#[allow(clippy::expect_used)]
fn new_from_key(key: [u8; 64]) -> Self {
hmac::Hmac::new_from_slice(&key)
- .map(|hmac| Self { hmac_impl: hmac })
+ .map(Self)
.expect("length will always be valid because input key is of fixed size")
}
fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
- hmac::Hmac::new_from_slice(key)
- .map(|hmac| Self { hmac_impl: hmac })
- .map_err(|_| InvalidLength)
+ hmac::Hmac::new_from_slice(key).map(Self).map_err(|_| InvalidLength)
}
fn update(&mut self, data: &[u8]) {
- self.hmac_impl.update(data);
+ self.0.update(data);
}
fn finalize(self) -> [u8; 64] {
- self.hmac_impl.finalize().into_bytes().into()
+ self.0.finalize().into_bytes().into()
}
fn verify_slice(self, tag: &[u8]) -> Result<(), MacError> {
- self.hmac_impl.verify_slice(tag).map_err(|_| MacError)
+ self.0.verify_slice(tag).map_err(|_| MacError)
}
fn verify(self, tag: [u8; 64]) -> Result<(), MacError> {
- self.hmac_impl.verify(&tag.into()).map_err(|_| MacError)
+ self.0.verify(&tag.into()).map_err(|_| MacError)
}
fn verify_truncated_left(self, tag: &[u8]) -> Result<(), MacError> {
- self.hmac_impl.verify_truncated_left(tag).map_err(|_| MacError)
+ self.0.verify_truncated_left(tag).map_err(|_| MacError)
}
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/lib.rs b/nearby/crypto/crypto_provider_rustcrypto/src/lib.rs
index e95712c..628f679 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/lib.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/lib.rs
@@ -25,6 +25,7 @@
use core::{fmt::Debug, marker::PhantomData};
+pub use aes;
use cfg_if::cfg_if;
pub use hkdf;
pub use hmac;
@@ -35,17 +36,17 @@
/// Contains the RustCrypto backed impls for AES-GCM-SIV operations
mod aead;
/// Contains the RustCrypto backed AES impl for CryptoProvider
-pub mod aes;
+pub mod aes_cp;
/// Contains the RustCrypto backed impl for ed25519 key generation, signing, and verification
mod ed25519;
/// Contains the RustCrypto backed hkdf impl for CryptoProvider
-mod hkdf_rc;
+mod hkdf_cp;
/// Contains the RustCrypto backed hmac impl for CryptoProvider
-mod hmac_rc;
+mod hmac_cp;
/// Contains the RustCrypto backed P256 impl for CryptoProvider
mod p256;
/// Contains the RustCrypto backed SHA2 impl for CryptoProvider
-mod sha2_rc;
+mod sha2_cp;
/// Contains the RustCrypto backed X25519 impl for CryptoProvider
mod x25519;
@@ -54,9 +55,11 @@
/// Providing a type alias for compatibility with existing usage of RustCrypto
/// by default we use StdRng for the underlying csprng
pub type RustCrypto = RustCryptoImpl<rand::rngs::StdRng>;
- } else {
+ } else if #[cfg(feature = "rand_chacha")] {
/// A no_std compatible implementation of CryptoProvider backed by RustCrypto crates
pub type RustCrypto = RustCryptoImpl<rand_chacha::ChaCha20Rng>;
+ } else {
+ compile_error!("Must specify either --features std or --features rand_chacha");
}
}
@@ -76,23 +79,24 @@
impl<R: CryptoRng + SeedableRng + RngCore + Eq + PartialEq + Debug + Clone + Send>
crypto_provider::CryptoProvider for RustCryptoImpl<R>
{
- type HkdfSha256 = hkdf_rc::Hkdf<sha2::Sha256>;
- type HmacSha256 = hmac_rc::Hmac<sha2::Sha256>;
- type HkdfSha512 = hkdf_rc::Hkdf<sha2::Sha512>;
- type HmacSha512 = hmac_rc::Hmac<sha2::Sha512>;
- #[cfg(feature = "alloc")]
- type AesCbcPkcs7Padded = aes::cbc::AesCbcPkcs7Padded;
+ type HkdfSha256 = hkdf_cp::Hkdf<sha2::Sha256>;
+ type HmacSha256 = hmac_cp::Hmac<sha2::Sha256>;
+ type HkdfSha512 = hkdf_cp::Hkdf<sha2::Sha512>;
+ type HmacSha512 = hmac_cp::Hmac<sha2::Sha512>;
+ type AesCbcPkcs7Padded = aes_cp::cbc::AesCbcPkcs7Padded;
type X25519 = x25519::X25519Ecdh<R>;
type P256 = p256::P256Ecdh<R>;
- type Sha256 = sha2_rc::RustCryptoSha256;
- type Sha512 = sha2_rc::RustCryptoSha512;
- type Aes128 = aes::Aes128;
- type Aes256 = aes::Aes256;
- type AesCtr128 = aes::ctr::AesCtr128;
- type AesCtr256 = aes::ctr::AesCtr256;
+ type Sha256 = sha2_cp::RustCryptoSha256;
+ type Sha512 = sha2_cp::RustCryptoSha512;
+ type Aes128 = aes_cp::Aes128;
+ type Aes256 = aes_cp::Aes256;
+ type AesCtr128 = aes_cp::ctr::AesCtr128;
+ type AesCtr256 = aes_cp::ctr::AesCtr256;
type Ed25519 = ed25519::Ed25519;
- type Aes128GcmSiv = aead::aes_gcm_siv::AesGcmSiv128;
- type Aes256GcmSiv = aead::aes_gcm_siv::AesGcmSiv256;
+ type Aes128GcmSiv = aead::aes_gcm_siv::AesGcmSiv<aes::Aes128>;
+ type Aes256GcmSiv = aead::aes_gcm_siv::AesGcmSiv<aes::Aes256>;
+ type Aes128Gcm = aead::aes_gcm::AesGcm<aes::Aes128>;
+ type Aes256Gcm = aead::aes_gcm::AesGcm<aes::Aes256>;
type CryptoRng = RcRng<R>;
fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
@@ -124,6 +128,7 @@
mod tests {
use core::marker::PhantomData;
+ use crypto_provider_test::prelude::*;
use crypto_provider_test::sha2::*;
use crate::RustCrypto;
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/p256.rs b/nearby/crypto/crypto_provider_rustcrypto/src/p256.rs
index 539ccc0..98a6cd4 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/p256.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/p256.rs
@@ -12,14 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-extern crate alloc;
-
use crate::RcRng;
-use alloc::vec::Vec;
use core::marker::PhantomData;
use crypto_provider::{
elliptic_curve::{EcdhProvider, EphemeralSecret},
- p256::P256,
+ p256::{PointCompression, P256},
+ tinyvec::ArrayVec,
};
use p256::{
elliptic_curve,
@@ -52,8 +50,12 @@
p256::PublicKey::from_sec1_bytes(bytes).map(Self)
}
- fn to_sec1_bytes(&self) -> Vec<u8> {
- self.0.to_encoded_point(true).as_bytes().to_vec()
+ fn to_sec1_bytes(&self, point_compression: PointCompression) -> ArrayVec<[u8; 65]> {
+ let mut bytes = ArrayVec::<[u8; 65]>::new();
+ bytes.extend_from_slice(
+ self.0.to_encoded_point(point_compression == PointCompression::Compressed).as_bytes(),
+ );
+ bytes
}
#[allow(clippy::expect_used)]
@@ -87,6 +89,7 @@
type Impl = P256Ecdh<R>;
type Error = sec1::Error;
type Rng = RcRng<R>;
+ type EncodedPublicKey = ArrayVec<[u8; 65]>;
fn generate_random(rng: &mut Self::Rng) -> Self {
Self {
@@ -95,8 +98,10 @@
}
}
- fn public_key_bytes(&self) -> Vec<u8> {
- self.secret.public_key().to_encoded_point(false).as_bytes().into()
+ fn public_key_bytes(&self) -> Self::EncodedPublicKey {
+ let mut bytes = Self::EncodedPublicKey::new();
+ bytes.extend_from_slice(self.secret.public_key().to_encoded_point(false).as_bytes());
+ bytes
}
fn diffie_hellman(
@@ -136,7 +141,7 @@
use rand::rngs::StdRng;
#[apply(p256_test_cases)]
- fn p256_tests(testcase: CryptoProviderTestCase<P256Ecdh<StdRng>>) {
+ fn p256_tests(testcase: CryptoProviderTestCase<P256Ecdh<StdRng>>, _name: &str) {
testcase(PhantomData::<P256Ecdh<StdRng>>)
}
}
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/sha2_rc.rs b/nearby/crypto/crypto_provider_rustcrypto/src/sha2_cp.rs
similarity index 100%
rename from nearby/crypto/crypto_provider_rustcrypto/src/sha2_rc.rs
rename to nearby/crypto/crypto_provider_rustcrypto/src/sha2_cp.rs
diff --git a/nearby/crypto/crypto_provider_rustcrypto/src/x25519.rs b/nearby/crypto/crypto_provider_rustcrypto/src/x25519.rs
index 445e858..ad67777 100644
--- a/nearby/crypto/crypto_provider_rustcrypto/src/x25519.rs
+++ b/nearby/crypto/crypto_provider_rustcrypto/src/x25519.rs
@@ -12,10 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-extern crate alloc;
-
use crate::RcRng;
-use alloc::vec::Vec;
use core::marker::PhantomData;
use crypto_provider::elliptic_curve::{EcdhProvider, EphemeralSecret, PublicKey};
use crypto_provider::x25519::X25519;
@@ -45,6 +42,7 @@
type Impl = X25519Ecdh<R>;
type Error = Error;
type Rng = RcRng<R>;
+ type EncodedPublicKey = [u8; 32];
fn generate_random(rng: &mut Self::Rng) -> Self {
Self {
@@ -53,9 +51,9 @@
}
}
- fn public_key_bytes(&self) -> Vec<u8> {
+ fn public_key_bytes(&self) -> Self::EncodedPublicKey {
let pubkey: x25519_dalek::PublicKey = (&self.secret).into();
- pubkey.to_bytes().into()
+ pubkey.to_bytes()
}
fn diffie_hellman(
@@ -90,14 +88,15 @@
impl PublicKey<X25519> for X25519PublicKey {
type Error = Error;
+ type EncodedPublicKey = [u8; 32];
fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> {
let byte_sized: [u8; 32] = bytes.try_into().map_err(|_| Error::WrongSize)?;
Ok(Self(byte_sized.into()))
}
- fn to_bytes(&self) -> Vec<u8> {
- self.0.as_bytes().to_vec()
+ fn to_bytes(&self) -> Self::EncodedPublicKey {
+ self.0.to_bytes()
}
}