diff options
Diffstat (limited to 'nearby/crypto/crypto_provider_openssl')
9 files changed, 105 insertions, 70 deletions
diff --git a/nearby/crypto/crypto_provider_openssl/Cargo.toml b/nearby/crypto/crypto_provider_openssl/Cargo.toml index 84d4380..19ef3e4 100644 --- a/nearby/crypto/crypto_provider_openssl/Cargo.toml +++ b/nearby/crypto/crypto_provider_openssl/Cargo.toml @@ -4,6 +4,9 @@ version.workspace = true edition.workspace = true publish.workspace = true +[lints] +workspace = true + [dependencies] crypto_provider = { workspace = true, features = ["alloc", "std"] } crypto_provider_stubs.workspace = true diff --git a/nearby/crypto/crypto_provider_openssl/src/aes.rs b/nearby/crypto/crypto_provider_openssl/src/aes.rs index f5d5b00..857be74 100644 --- a/nearby/crypto/crypto_provider_openssl/src/aes.rs +++ b/nearby/crypto/crypto_provider_openssl/src/aes.rs @@ -26,10 +26,13 @@ use openssl::symm::{Cipher, Crypter, Mode}; -use crypto_provider::aes::{ - cbc::{AesCbcIv, DecryptionError}, - ctr::NonceAndCounter, - Aes, Aes128Key, Aes256Key, AesBlock, AesCipher, AesDecryptCipher, AesEncryptCipher, AesKey, +use crypto_provider::{ + aes::{ + cbc::{AesCbcIv, DecryptionError, EncryptionError}, + ctr::NonceAndCounter, + Aes, Aes128Key, Aes256Key, AesBlock, AesCipher, AesDecryptCipher, AesEncryptCipher, AesKey, + }, + tinyvec::SliceVec, }; /// Uber struct which contains impls for AES-128 fns @@ -68,7 +71,7 @@ impl AesEncryptCipher for Aes128Cipher { let mut crypter = Crypter::new(Cipher::aes_128_ecb(), Mode::Encrypt, self.0.as_slice(), None).unwrap(); crypter.pad(false); - crypter.update(block, &mut output).unwrap(); + let _ = crypter.update(block, &mut output).unwrap(); block.copy_from_slice(&output[..crypto_provider::aes::BLOCK_SIZE]); } } @@ -80,7 +83,7 @@ impl AesDecryptCipher for Aes128Cipher { let mut crypter = Crypter::new(Cipher::aes_128_ecb(), Mode::Decrypt, self.0.as_slice(), None).unwrap(); crypter.pad(false); - crypter.update(block, &mut output).unwrap(); + let _ = crypter.update(block, &mut output).unwrap(); block.copy_from_slice(&output[..crypto_provider::aes::BLOCK_SIZE]); } } @@ -103,7 +106,7 @@ impl AesEncryptCipher for Aes256Cipher { let mut crypter = Crypter::new(Cipher::aes_256_ecb(), Mode::Encrypt, self.0.as_slice(), None).unwrap(); crypter.pad(false); - crypter.update(block, &mut output).unwrap(); + let _ = crypter.update(block, &mut output).unwrap(); block.copy_from_slice(&output[..crypto_provider::aes::BLOCK_SIZE]); } } @@ -115,7 +118,7 @@ impl AesDecryptCipher for Aes256Cipher { let mut crypter = Crypter::new(Cipher::aes_256_ecb(), Mode::Decrypt, self.0.as_slice(), None).unwrap(); crypter.pad(false); - crypter.update(block, &mut output).unwrap(); + let _ = crypter.update(block, &mut output).unwrap(); block.copy_from_slice(&output[..crypto_provider::aes::BLOCK_SIZE]); } } @@ -126,7 +129,23 @@ pub struct OpenSslAesCbcPkcs7; impl crypto_provider::aes::cbc::AesCbcPkcs7Padded for OpenSslAesCbcPkcs7 { fn encrypt(key: &crypto_provider::aes::Aes256Key, iv: &AesCbcIv, message: &[u8]) -> Vec<u8> { openssl::symm::encrypt(Cipher::aes_256_cbc(), key.as_slice(), Some(iv.as_slice()), message) - .unwrap() + // The output buffer is allocated by the openssl crate and guarantees to have enough + // space to hold the output value and does not overlap with the input slice. + .expect("encrypt should always succeed") + } + + fn encrypt_in_place( + key: &Aes256Key, + iv: &AesCbcIv, + message: &mut SliceVec<u8>, + ) -> Result<(), EncryptionError> { + let encrypted = Self::encrypt(key, iv, message); + if encrypted.len() > message.capacity() { + return Err(EncryptionError::PaddingFailed); + } + message.clear(); + message.extend_from_slice(&encrypted); + Ok(()) } fn decrypt( @@ -142,12 +161,22 @@ impl crypto_provider::aes::cbc::AesCbcPkcs7Padded for OpenSslAesCbcPkcs7 { ) .map_err(|_| DecryptionError::BadPadding) } + + fn decrypt_in_place( + key: &Aes256Key, + iv: &AesCbcIv, + ciphertext: &mut SliceVec<u8>, + ) -> Result<(), DecryptionError> { + Self::decrypt(key, iv, ciphertext).map(|result| { + ciphertext.clear(); + ciphertext.extend_from_slice(&result); + }) + } } /// OpenSSL implementation of AES-CTR-128 pub struct OpenSslAesCtr128 { enc_cipher: Crypter, - dec_cipher: Crypter, } impl crypto_provider::aes::ctr::AesCtr for OpenSslAesCtr128 { @@ -161,33 +190,19 @@ impl crypto_provider::aes::ctr::AesCtr for OpenSslAesCtr128 { Some(&nonce_and_counter.as_block_array()), ) .unwrap(), - dec_cipher: Crypter::new( - Cipher::aes_128_ctr(), - Mode::Decrypt, - key.as_slice(), - Some(&nonce_and_counter.as_block_array()), - ) - .unwrap(), } } - fn encrypt(&mut self, data: &mut [u8]) { + fn apply_keystream(&mut self, data: &mut [u8]) { let mut in_slice = vec![0u8; data.len()]; in_slice.copy_from_slice(data); let _ = self.enc_cipher.update(&in_slice, data); } - - fn decrypt(&mut self, data: &mut [u8]) { - let mut in_slice = vec![0u8; data.len()]; - in_slice.copy_from_slice(data); - let _ = self.dec_cipher.update(&in_slice, data); - } } /// OpenSSL implementation of AES-CTR-256 pub struct OpenSslAesCtr256 { enc_cipher: Crypter, - dec_cipher: Crypter, } impl crypto_provider::aes::ctr::AesCtr for OpenSslAesCtr256 { @@ -201,27 +216,14 @@ impl crypto_provider::aes::ctr::AesCtr for OpenSslAesCtr256 { Some(&nonce_and_counter.as_block_array()), ) .unwrap(), - dec_cipher: Crypter::new( - Cipher::aes_256_ctr(), - Mode::Decrypt, - key.as_slice(), - Some(&nonce_and_counter.as_block_array()), - ) - .unwrap(), } } - fn encrypt(&mut self, data: &mut [u8]) { + fn apply_keystream(&mut self, data: &mut [u8]) { let mut in_slice = vec![0u8; data.len()]; in_slice.copy_from_slice(data); let _ = self.enc_cipher.update(&in_slice, data); } - - fn decrypt(&mut self, data: &mut [u8]) { - let mut in_slice = vec![0u8; data.len()]; - in_slice.copy_from_slice(data); - let _ = self.dec_cipher.update(&in_slice, data); - } } #[cfg(test)] diff --git a/nearby/crypto/crypto_provider_openssl/src/ed25519.rs b/nearby/crypto/crypto_provider_openssl/src/ed25519.rs index 110daf2..111348a 100644 --- a/nearby/crypto/crypto_provider_openssl/src/ed25519.rs +++ b/nearby/crypto/crypto_provider_openssl/src/ed25519.rs @@ -13,7 +13,8 @@ // limitations under the License. use crypto_provider::ed25519::{ - InvalidBytes, RawPrivateKey, RawPublicKey, RawSignature, Signature as _, SignatureError, + InvalidBytes, RawPrivateKey, RawPrivateKeyPermit, RawPublicKey, RawSignature, Signature as _, + SignatureError, }; use openssl::pkey::{Id, PKey, Private}; use openssl::sign::{Signer, Verifier}; @@ -32,7 +33,7 @@ impl crypto_provider::ed25519::KeyPair for KeyPair { type PublicKey = PublicKey; type Signature = Signature; - fn private_key(&self) -> RawPrivateKey { + fn raw_private_key(&self, _permit: &RawPrivateKeyPermit) -> RawPrivateKey { let private_key = self.0.raw_private_key().unwrap(); let mut public_key = self.0.raw_public_key().unwrap(); let mut result = private_key; @@ -40,7 +41,7 @@ impl crypto_provider::ed25519::KeyPair for KeyPair { result.try_into().unwrap() } - fn from_private_key(bytes: &RawPrivateKey) -> Self { + fn from_raw_private_key(bytes: &RawPrivateKey, _permit: &RawPrivateKeyPermit) -> Self { Self(PKey::private_key_from_raw_bytes(bytes, Id::ED25519).unwrap()) } diff --git a/nearby/crypto/crypto_provider_openssl/src/hkdf_openssl.rs b/nearby/crypto/crypto_provider_openssl/src/hkdf_openssl.rs index d429a4d..b726f5f 100644 --- a/nearby/crypto/crypto_provider_openssl/src/hkdf_openssl.rs +++ b/nearby/crypto/crypto_provider_openssl/src/hkdf_openssl.rs @@ -42,7 +42,9 @@ impl<H: OpenSslHash> crypto_provider::hkdf::Hkdf for Hkdf<H> { let md = H::get_md(); ctx.derive_init().expect("hkdf derive init should not fail"); ctx.set_hkdf_md(md).expect("hkdf set md should not fail"); - self.salt.as_ref().map(|salt| ctx.set_hkdf_salt(salt.as_slice())); + let _ = self.salt.as_ref().map(|salt| { + ctx.set_hkdf_salt(salt.as_slice()).expect("setting the salt is infallible") + }); ctx.set_hkdf_key(self.ikm.as_slice()).expect("should be able to set key"); ctx.add_hkdf_info(&info_components.concat()).expect("should be able to add info"); ctx.derive(Some(okm)).map_err(|_| InvalidLength).map(|_| ()) diff --git a/nearby/crypto/crypto_provider_openssl/src/hmac_boringssl.rs b/nearby/crypto/crypto_provider_openssl/src/hmac_boringssl.rs index 9b86726..5272995 100644 --- a/nearby/crypto/crypto_provider_openssl/src/hmac_boringssl.rs +++ b/nearby/crypto/crypto_provider_openssl/src/hmac_boringssl.rs @@ -50,7 +50,7 @@ impl<const N: usize, H: Hash<N>> crypto_provider::hmac::Hmac<N> for Hmac<H> { fn finalize(mut self) -> [u8; N] { let mut buf = [0_u8; N]; - self.ctx.finalize(&mut buf).expect("wrong length"); + let _ = self.ctx.finalize(&mut buf).expect("wrong length"); buf } diff --git a/nearby/crypto/crypto_provider_openssl/src/lib.rs b/nearby/crypto/crypto_provider_openssl/src/lib.rs index d8157d2..04b4e4c 100644 --- a/nearby/crypto/crypto_provider_openssl/src/lib.rs +++ b/nearby/crypto/crypto_provider_openssl/src/lib.rs @@ -12,10 +12,13 @@ // 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. -#![deny(missing_docs, clippy::indexing_slicing, clippy::panic)] //! Crate which provides impls for CryptoProvider backed by openssl +// This crate treats allocation errors as handleable, which leads to unwraps everywhere, so they +// have to be allowed here. This will be fixed when we can migrate over to the new boringssl bindings +#![allow(clippy::expect_used, clippy::unwrap_used)] + use cfg_if::cfg_if; pub use openssl; use openssl::hash::MessageDigest; @@ -82,6 +85,8 @@ impl crypto_provider::CryptoProvider for Openssl { type Ed25519 = ed25519::Ed25519; type Aes128GcmSiv = crypto_provider_stubs::Aes128Stubs; type Aes256GcmSiv = crypto_provider_stubs::Aes256Stubs; + type Aes128Gcm = crypto_provider_stubs::Aes128Stubs; + type Aes256Gcm = crypto_provider_stubs::Aes256Stubs; type CryptoRng = OpenSslRng; fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { @@ -113,7 +118,7 @@ mod tests { use core::marker::PhantomData; use crypto_provider_test::sha2::*; - use crypto_provider_test::*; + use crypto_provider_test::{prelude::*, *}; use crate::Openssl; diff --git a/nearby/crypto/crypto_provider_openssl/src/p256.rs b/nearby/crypto/crypto_provider_openssl/src/p256.rs index 2f5b0b1..17dd6ce 100644 --- a/nearby/crypto/crypto_provider_openssl/src/p256.rs +++ b/nearby/crypto/crypto_provider_openssl/src/p256.rs @@ -12,8 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crypto_provider::elliptic_curve::{EcdhProvider, EphemeralSecret}; -use crypto_provider::p256::P256; +use crypto_provider::{ + elliptic_curve::{EcdhProvider, EphemeralSecret}, + p256::{PointCompression, P256}, + tinyvec::ArrayVec, +}; use openssl::bn::{BigNum, BigNumContext}; use openssl::derive::Deriver; use openssl::ec::{EcGroup, EcKey, EcPoint, PointConversionForm}; @@ -65,15 +68,24 @@ impl crypto_provider::p256::P256PublicKey for P256PublicKey { Ok(Self(eckey.try_into()?)) } - fn to_sec1_bytes(&self) -> Vec<u8> { + fn to_sec1_bytes(&self, point_compression: PointCompression) -> ArrayVec<[u8; 65]> { + let point_conversion_form = match point_compression { + PointCompression::Compressed => PointConversionForm::COMPRESSED, + PointCompression::Uncompressed => PointConversionForm::UNCOMPRESSED, + }; let ecgroup = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let mut bncontext = BigNumContext::new().unwrap(); - self.0 - .ec_key() - .unwrap() - .public_key() - .to_bytes(&ecgroup, PointConversionForm::COMPRESSED, &mut bncontext) - .unwrap() + let mut bytes = ArrayVec::<[u8; 65]>::new(); + bytes.extend_from_slice( + &self + .0 + .ec_key() + .unwrap() + .public_key() + .to_bytes(&ecgroup, point_conversion_form, &mut bncontext) + .unwrap(), + ); + bytes } fn from_affine_coordinates(x: &[u8; 32], y: &[u8; 32]) -> Result<Self, Self::Error> { @@ -115,6 +127,7 @@ impl EphemeralSecret<P256> for P256EphemeralSecret { type Impl = P256Ecdh; type Error = Error; type Rng = (); + type EncodedPublicKey = ArrayVec<[u8; 65]>; fn generate_random(_rng: &mut Self::Rng) -> Self { let ecgroup = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); @@ -122,15 +135,20 @@ impl EphemeralSecret<P256> for P256EphemeralSecret { Self(eckey.try_into().unwrap()) } - fn public_key_bytes(&self) -> Vec<u8> { + fn public_key_bytes(&self) -> Self::EncodedPublicKey { let ecgroup = EcGroup::from_curve_name(Nid::X9_62_PRIME256V1).unwrap(); let mut bncontext = BigNumContext::new().unwrap(); - self.0 - .ec_key() - .unwrap() - .public_key() - .to_bytes(&ecgroup, PointConversionForm::COMPRESSED, &mut bncontext) - .unwrap() + let mut bytes = Self::EncodedPublicKey::new(); + bytes.extend_from_slice( + &self + .0 + .ec_key() + .unwrap() + .public_key() + .to_bytes(&ecgroup, PointConversionForm::COMPRESSED, &mut bncontext) + .unwrap(), + ); + bytes } fn diffie_hellman( @@ -178,7 +196,7 @@ mod tests { use crypto_provider_test::p256::*; #[apply(p256_test_cases)] - fn p256_tests(testcase: CryptoProviderTestCase<P256Ecdh>) { - testcase(PhantomData::<P256Ecdh>) + fn p256_tests(testcase: CryptoProviderTestCase<P256Ecdh>, _name: &str) { + testcase(PhantomData) } } diff --git a/nearby/crypto/crypto_provider_openssl/src/sha2.rs b/nearby/crypto/crypto_provider_openssl/src/sha2.rs index 92e663e..68fee79 100644 --- a/nearby/crypto/crypto_provider_openssl/src/sha2.rs +++ b/nearby/crypto/crypto_provider_openssl/src/sha2.rs @@ -38,7 +38,8 @@ impl crypto_provider::sha2::Sha256 for OpenSslSha256 { mdctx.digest_init(Self::get_md()).unwrap(); mdctx.digest_update(input).unwrap(); let mut buf = [0_u8; 32]; - mdctx.digest_final(&mut buf).unwrap(); + let size = mdctx.digest_final(&mut buf).unwrap(); + debug_assert_eq!(size, 32); buf } } @@ -63,7 +64,8 @@ impl crypto_provider::sha2::Sha512 for OpenSslSha512 { mdctx.digest_init(Self::get_md()).unwrap(); mdctx.digest_update(input).unwrap(); let mut buf = [0_u8; 64]; - mdctx.digest_final(&mut buf).unwrap(); + let size = mdctx.digest_final(&mut buf).unwrap(); + debug_assert_eq!(size, 64); buf } } diff --git a/nearby/crypto/crypto_provider_openssl/src/x25519.rs b/nearby/crypto/crypto_provider_openssl/src/x25519.rs index ff6f3b0..2cb4cab 100644 --- a/nearby/crypto/crypto_provider_openssl/src/x25519.rs +++ b/nearby/crypto/crypto_provider_openssl/src/x25519.rs @@ -30,14 +30,15 @@ impl PartialEq for X25519PublicKey { impl PublicKey<X25519> for X25519PublicKey { type Error = ErrorStack; + type EncodedPublicKey = [u8; 32]; fn from_bytes(bytes: &[u8]) -> Result<Self, Self::Error> { let key = PKey::public_key_from_raw_bytes(bytes, Id::X25519)?; Ok(X25519PublicKey(key)) } - fn to_bytes(&self) -> Vec<u8> { - self.0.raw_public_key().unwrap() + fn to_bytes(&self) -> Self::EncodedPublicKey { + self.0.raw_public_key().unwrap().try_into().unwrap() } } @@ -48,14 +49,15 @@ impl EphemeralSecret<X25519> for X25519PrivateKey { type Impl = X25519Ecdh; type Error = ErrorStack; type Rng = (); + type EncodedPublicKey = [u8; 32]; fn generate_random(_rng: &mut Self::Rng) -> Self { let private_key = openssl::pkey::PKey::generate_x25519().unwrap(); Self(private_key) } - fn public_key_bytes(&self) -> Vec<u8> { - self.0.raw_public_key().unwrap() + fn public_key_bytes(&self) -> Self::EncodedPublicKey { + self.0.raw_public_key().unwrap().try_into().unwrap() } fn diffie_hellman( |