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 15 #![no_std] 16 17 //! Crate which provides impls for CryptoProvider backed by RustCrypto crates 18 19 use core::{fmt::Debug, marker::PhantomData}; 20 21 pub use aes; 22 use cfg_if::cfg_if; 23 pub use hkdf; 24 pub use hmac; 25 use rand::{Rng, RngCore, SeedableRng}; 26 use rand_core::CryptoRng; 27 use subtle::ConstantTimeEq; 28 29 /// Contains the RustCrypto backed impls for AES-GCM-SIV operations 30 mod aead; 31 /// Contains the RustCrypto backed AES impl for CryptoProvider 32 pub mod aes_cp; 33 /// Contains the RustCrypto backed impl for ed25519 key generation, signing, and verification 34 mod ed25519; 35 /// Contains the RustCrypto backed hkdf impl for CryptoProvider 36 mod hkdf_cp; 37 /// Contains the RustCrypto backed hmac impl for CryptoProvider 38 mod hmac_cp; 39 /// Contains the RustCrypto backed P256 impl for CryptoProvider 40 mod p256; 41 /// Contains the RustCrypto backed SHA2 impl for CryptoProvider 42 mod sha2_cp; 43 /// Contains the RustCrypto backed X25519 impl for CryptoProvider 44 mod x25519; 45 46 cfg_if! { 47 if #[cfg(feature = "std")] { 48 /// Providing a type alias for compatibility with existing usage of RustCrypto 49 /// by default we use StdRng for the underlying csprng 50 pub type RustCrypto = RustCryptoImpl<rand::rngs::StdRng>; 51 } else if #[cfg(feature = "rand_chacha")] { 52 /// A no_std compatible implementation of CryptoProvider backed by RustCrypto crates 53 pub type RustCrypto = RustCryptoImpl<rand_chacha::ChaCha20Rng>; 54 } else { 55 compile_error!("Must specify either --features std or --features rand_chacha"); 56 } 57 } 58 59 /// The RustCrypto backed struct which implements CryptoProvider 60 #[derive(Default, Clone, Debug, PartialEq, Eq)] 61 pub struct RustCryptoImpl<R: CryptoRng + SeedableRng + RngCore> { 62 _marker: PhantomData<R>, 63 } 64 65 impl<R: CryptoRng + SeedableRng + RngCore> RustCryptoImpl<R> { 66 /// Create a new instance of RustCrypto new() -> Self67 pub fn new() -> Self { 68 Self { _marker: Default::default() } 69 } 70 } 71 72 impl<R: CryptoRng + SeedableRng + RngCore + Eq + PartialEq + Debug + Clone + Send> 73 crypto_provider::CryptoProvider for RustCryptoImpl<R> 74 { 75 type HkdfSha256 = hkdf_cp::Hkdf<sha2::Sha256>; 76 type HmacSha256 = hmac_cp::Hmac<sha2::Sha256>; 77 type HkdfSha512 = hkdf_cp::Hkdf<sha2::Sha512>; 78 type HmacSha512 = hmac_cp::Hmac<sha2::Sha512>; 79 type AesCbcPkcs7Padded = aes_cp::cbc::AesCbcPkcs7Padded; 80 type X25519 = x25519::X25519Ecdh<R>; 81 type P256 = p256::P256Ecdh<R>; 82 type Sha256 = sha2_cp::RustCryptoSha256; 83 type Sha512 = sha2_cp::RustCryptoSha512; 84 type Aes128 = aes_cp::Aes128; 85 type Aes256 = aes_cp::Aes256; 86 type AesCtr128 = aes_cp::ctr::AesCtr128; 87 type AesCtr256 = aes_cp::ctr::AesCtr256; 88 type Ed25519 = ed25519::Ed25519; 89 type Aes128GcmSiv = aead::aes_gcm_siv::AesGcmSiv<aes::Aes128>; 90 type Aes256GcmSiv = aead::aes_gcm_siv::AesGcmSiv<aes::Aes256>; 91 type Aes128Gcm = aead::aes_gcm::AesGcm<aes::Aes128>; 92 type Aes256Gcm = aead::aes_gcm::AesGcm<aes::Aes256>; 93 type CryptoRng = RcRng<R>; 94 constant_time_eq(a: &[u8], b: &[u8]) -> bool95 fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { 96 a.ct_eq(b).into() 97 } 98 } 99 100 /// A RustCrypto wrapper for RNG 101 pub struct RcRng<R>(R); 102 103 impl<R: rand_core::CryptoRng + RngCore + SeedableRng> crypto_provider::CryptoRng for RcRng<R> { new() -> Self104 fn new() -> Self { 105 Self(R::from_entropy()) 106 } 107 next_u64(&mut self) -> u64108 fn next_u64(&mut self) -> u64 { 109 self.0.next_u64() 110 } 111 fill(&mut self, dest: &mut [u8])112 fn fill(&mut self, dest: &mut [u8]) { 113 self.0.fill(dest) 114 } 115 } 116 117 #[cfg(test)] 118 mod testing; 119 120 #[cfg(test)] 121 mod tests { 122 use core::marker::PhantomData; 123 124 use crypto_provider_test::prelude::*; 125 use crypto_provider_test::sha2::*; 126 127 use crate::RustCrypto; 128 129 #[apply(sha2_test_cases)] sha2_tests(testcase: CryptoProviderTestCase<RustCrypto>)130 fn sha2_tests(testcase: CryptoProviderTestCase<RustCrypto>) { 131 testcase(PhantomData::<RustCrypto>); 132 } 133 } 134