1 // Copyright 2023 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #![no_std] 15 #![forbid(unsafe_code)] 16 #![deny( 17 missing_docs, 18 clippy::indexing_slicing, 19 clippy::unwrap_used, 20 clippy::panic, 21 clippy::expect_used 22 )] 23 24 //! Crate which provides impls for CryptoProvider backed by RustCrypto crates 25 26 /// Contains the RustCrypto backed AES impl for CryptoProvider 27 pub mod aes; 28 /// Contains the RustCrypto backed impl for ed25519 key generation, signing, and verification 29 mod ed25519; 30 /// Contains the RustCrypto backed hkdf impl for CryptoProvider 31 mod hkdf_rc; 32 /// Contains the RustCrypto backed hmac impl for CryptoProvider 33 mod hmac_rc; 34 /// Contains the RustCrypto backed P256 impl for CryptoProvider 35 mod p256; 36 /// Contains the RustCrypto backed SHA2 impl for CryptoProvider 37 mod sha2_rc; 38 /// Contains the RustCrypto backed X25519 impl for CryptoProvider 39 mod x25519; 40 41 pub use hkdf; 42 pub use hmac; 43 44 use cfg_if::cfg_if; 45 use core::{fmt::Debug, marker::PhantomData}; 46 use rand::{Rng, RngCore, SeedableRng}; 47 use rand_core::CryptoRng; 48 use subtle::ConstantTimeEq; 49 50 cfg_if! { 51 if #[cfg(feature = "std")] { 52 /// Providing a type alias for compatibility with existing usage of RustCrypto 53 /// by default we use StdRng for the underlying csprng 54 pub type RustCrypto = RustCryptoImpl<rand::rngs::StdRng>; 55 } else { 56 /// A no_std compatible implementation of CryptoProvider backed by RustCrypto crates 57 pub type RustCrypto = RustCryptoImpl<rand_chacha::ChaCha20Rng>; 58 } 59 } 60 61 /// The the RustCrypto backed struct which implements CryptoProvider 62 #[derive(Default, Clone, Debug, PartialEq, Eq)] 63 pub struct RustCryptoImpl<R: CryptoRng + SeedableRng + RngCore> { 64 _marker: PhantomData<R>, 65 } 66 67 impl<R: CryptoRng + SeedableRng + RngCore> RustCryptoImpl<R> { 68 /// Create a new instance of RustCrypto new() -> Self69 pub fn new() -> Self { 70 Self { 71 _marker: Default::default(), 72 } 73 } 74 } 75 76 impl<R: CryptoRng + SeedableRng + RngCore + Eq + PartialEq + Debug + Clone + Send> 77 crypto_provider::CryptoProvider for RustCryptoImpl<R> 78 { 79 type HkdfSha256 = hkdf_rc::Hkdf<sha2::Sha256>; 80 type HmacSha256 = hmac_rc::Hmac<sha2::Sha256>; 81 type HkdfSha512 = hkdf_rc::Hkdf<sha2::Sha512>; 82 type HmacSha512 = hmac_rc::Hmac<sha2::Sha512>; 83 #[cfg(feature = "alloc")] 84 type AesCbcPkcs7Padded = aes::cbc::AesCbcPkcs7Padded; 85 type X25519 = x25519::X25519Ecdh<R>; 86 type P256 = p256::P256Ecdh<R>; 87 type Sha256 = sha2_rc::RustCryptoSha256; 88 type Sha512 = sha2_rc::RustCryptoSha512; 89 type Aes128 = aes::Aes128; 90 type Aes256 = aes::Aes256; 91 type AesCtr128 = aes::AesCtr128; 92 type AesCtr256 = aes::AesCtr256; 93 type Ed25519 = ed25519::Ed25519; 94 type CryptoRng = RcRng<R>; 95 constant_time_eq(a: &[u8], b: &[u8]) -> bool96 fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { 97 a.ct_eq(b).into() 98 } 99 } 100 101 /// A RustCrypto wrapper for RNG 102 pub struct RcRng<R>(R); 103 104 impl<R: rand_core::CryptoRng + RngCore + SeedableRng> crypto_provider::CryptoRng for RcRng<R> { new() -> Self105 fn new() -> Self { 106 Self(R::from_entropy()) 107 } 108 next_u64(&mut self) -> u64109 fn next_u64(&mut self) -> u64 { 110 self.0.next_u64() 111 } 112 fill(&mut self, dest: &mut [u8])113 fn fill(&mut self, dest: &mut [u8]) { 114 self.0.fill(dest) 115 } 116 } 117 118 #[cfg(test)] 119 mod testing; 120 121 #[cfg(test)] 122 mod tests { 123 use crate::RustCrypto; 124 use core::marker::PhantomData; 125 use crypto_provider::sha2::testing::*; 126 127 #[apply(sha2_test_cases)] sha2_tests(testcase: CryptoProviderTestCase<RustCrypto>)128 fn sha2_tests(testcase: CryptoProviderTestCase<RustCrypto>) { 129 testcase(PhantomData::<RustCrypto>); 130 } 131 } 132