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 //! Crypto abstraction trait only crate, which provides traits for cryptographic primitives
16 
17 #![no_std]
18 
19 use core::fmt::Debug;
20 
21 use crate::aes::{Aes128Key, Aes256Key};
22 
23 /// mod containing hmac trait
24 pub mod hkdf;
25 
26 /// mod containing hkdf trait
27 pub mod hmac;
28 
29 /// mod containing X25519 trait
30 pub mod x25519;
31 
32 /// mod containing traits for NIST-P256 elliptic curve implementation.
33 pub mod p256;
34 
35 /// mod containing traits for elliptic curve cryptography.
36 pub mod elliptic_curve;
37 
38 /// mod containing SHA256 trait.
39 pub mod sha2;
40 
41 /// mod containing aes trait.
42 pub mod aes;
43 
44 /// mod containing aead trait.
45 pub mod aead;
46 
47 /// mod containing traits for ed25519 key generation, signing, and verification
48 pub mod ed25519;
49 
50 pub use tinyvec;
51 
52 /// Uber crypto trait which defines the traits for all crypto primitives as associated types
53 pub trait CryptoProvider: Clone + Debug + PartialEq + Eq + Send {
54     /// The Hkdf type which implements the hkdf trait
55     type HkdfSha256: hkdf::Hkdf;
56     /// The Hmac type which implements the hmac trait
57     type HmacSha256: hmac::Hmac<32>;
58     /// The Hkdf type which implements the hkdf trait
59     type HkdfSha512: hkdf::Hkdf;
60     /// The Hmac type which implements the hmac trait
61     type HmacSha512: hmac::Hmac<64>;
62     /// The AES-CBC-PKCS7 implementation to use
63     type AesCbcPkcs7Padded: aes::cbc::AesCbcPkcs7Padded;
64     /// The X25519 implementation to use for ECDH.
65     type X25519: elliptic_curve::EcdhProvider<x25519::X25519>;
66     /// The P256 implementation to use for ECDH.
67     type P256: p256::P256EcdhProvider;
68     /// The SHA256 hash implementation.
69     type Sha256: sha2::Sha256;
70     /// The SHA512 hash implementation.
71     type Sha512: sha2::Sha512;
72     /// Plain AES-128 implementation (without block cipher mode).
73     type Aes128: aes::Aes<Key = Aes128Key>;
74     /// Plain AES-256 implementation (without block cipher mode).
75     type Aes256: aes::Aes<Key = Aes256Key>;
76     /// AES-128 with CTR block mode
77     type AesCtr128: aes::ctr::AesCtr<Key = aes::Aes128Key>;
78     /// AES-256 with CTR block mode
79     type AesCtr256: aes::ctr::AesCtr<Key = aes::Aes256Key>;
80     /// The trait defining ed25519, a Edwards-curve Digital Signature Algorithm signature scheme
81     /// using SHA-512 (SHA-2) and Curve25519
82     type Ed25519: ed25519::Ed25519Provider;
83     /// The trait defining AES-128-GCM-SIV, a nonce-misuse resistant AEAD with a key size of 16 bytes.
84     type Aes128GcmSiv: aead::AesGcmSiv + aead::AeadInit<Aes128Key>;
85     /// The trait defining AES-256-GCM-SIV, a nonce-misuse resistant AEAD with a key size of 32 bytes.
86     type Aes256GcmSiv: aead::AesGcmSiv + aead::AeadInit<Aes256Key>;
87     /// The trait defining AES-128-GCM, an AEAD with a key size of 16 bytes.
88     type Aes128Gcm: aead::AesGcm + aead::AeadInit<Aes128Key>;
89     /// The trait defining AES-256-GCM, an AEAD with a key size of 32 bytes.
90     type Aes256Gcm: aead::AesGcm + aead::AeadInit<Aes256Key>;
91     /// The cryptographically secure random number generator
92     type CryptoRng: CryptoRng;
93 
94     /// Compares the two given slices, in constant time, and returns true if they are equal.
constant_time_eq(a: &[u8], b: &[u8]) -> bool95     fn constant_time_eq(a: &[u8], b: &[u8]) -> bool;
96 }
97 
98 /// Wrapper to a cryptographically secure pseudo random number generator
99 pub trait CryptoRng {
100     /// Returns an instance of the rng
new() -> Self101     fn new() -> Self;
102 
103     /// Return the next random u64
next_u64(&mut self) -> u64104     fn next_u64(&mut self) -> u64;
105 
106     /// Fill dest with random data
fill(&mut self, dest: &mut [u8])107     fn fill(&mut self, dest: &mut [u8]);
108 
109     /// Generate a random entity
gen<F: FromCryptoRng>(&mut self) -> F where Self: Sized,110     fn gen<F: FromCryptoRng>(&mut self) -> F
111     where
112         Self: Sized,
113     {
114         F::new_random::<Self>(self)
115     }
116 }
117 
118 /// If impls want to opt out of passing a Rng they can simply use `()` for the Rng associated type
119 impl CryptoRng for () {
new() -> Self120     fn new() -> Self {}
121 
next_u64(&mut self) -> u64122     fn next_u64(&mut self) -> u64 {
123         unimplemented!()
124     }
125 
fill(&mut self, _dest: &mut [u8])126     fn fill(&mut self, _dest: &mut [u8]) {
127         unimplemented!()
128     }
129 }
130 
131 /// For types that can be created from a `CryptoRng`
132 pub trait FromCryptoRng {
133     /// Construct a new `Self` with random data from `rng`
new_random<R: CryptoRng>(rng: &mut R) -> Self134     fn new_random<R: CryptoRng>(rng: &mut R) -> Self;
135 }
136 
137 impl<const N: usize> FromCryptoRng for [u8; N] {
new_random<R: CryptoRng>(rng: &mut R) -> Self138     fn new_random<R: CryptoRng>(rng: &mut R) -> Self {
139         let mut arr = [0; N];
140         rng.fill(&mut arr);
141         arr
142     }
143 }
144 
145 impl FromCryptoRng for u8 {
new_random<R: CryptoRng>(rng: &mut R) -> Self146     fn new_random<R: CryptoRng>(rng: &mut R) -> Self {
147         let arr: [u8; 1] = rng.gen();
148         arr[0]
149     }
150 }
151