• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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