1 #![forbid(unsafe_code)] 2 // Copyright 2023 Google LLC 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 #![deny(missing_docs, clippy::indexing_slicing, clippy::panic)] 16 17 //! Crate which provides impls for CryptoProvider backed by openssl 18 19 use cfg_if::cfg_if; 20 use crypto_provider::CryptoRng; 21 pub use openssl; 22 use openssl::hash::MessageDigest; 23 use openssl::md::MdRef; 24 use openssl::rand::rand_bytes; 25 26 /// Contains the openssl backed AES implementations for CryptoProvider 27 mod aes; 28 /// Contains the openssl backed ed25519 impl for key generation, verification, and signing 29 mod ed25519; 30 31 cfg_if! { 32 if #[cfg(feature = "boringssl")] { 33 /// Contains the boringssl backed hkdf impl for CryptoProvider 34 mod hkdf_boringssl; 35 use hkdf_boringssl as hkdf; 36 /// Contains the boringssl backed hmac impl for CryptoProvider 37 mod hmac_boringssl; 38 use hmac_boringssl as hmac; 39 } else { 40 /// Contains the openssl backed hkdf impl for CryptoProvider 41 mod hkdf_openssl; 42 use hkdf_openssl as hkdf; 43 /// Contains the openssl backed hmac impl for CryptoProvider 44 mod hmac_openssl; 45 use hmac_openssl as hmac; 46 } 47 } 48 /// Contains the openssl backed NIST-P256 impl for CryptoProvider 49 mod p256; 50 /// Contains the openssl backed SHA2 impl for CryptoProvider 51 mod sha2; 52 /// Contains the openssl backed X25519 impl for CryptoProvider 53 mod x25519; 54 55 /// The the openssl backed struct which implements CryptoProvider 56 #[derive(Default, Clone, Debug, PartialEq, Eq)] 57 pub struct Openssl; 58 59 /// The trait which defines a has used in openssl crypto operations 60 pub trait OpenSslHash { 61 /// gets the message digest algorithm to be used by the hmac implementation get_digest() -> MessageDigest62 fn get_digest() -> MessageDigest; 63 /// gets a reference to a message digest algorithm to be used by the hkdf implementation get_md() -> &'static MdRef64 fn get_md() -> &'static MdRef; 65 } 66 67 impl crypto_provider::CryptoProvider for Openssl { 68 type HkdfSha256 = hkdf::Hkdf<sha2::OpenSslSha256>; 69 type HmacSha256 = hmac::Hmac<sha2::OpenSslSha256>; 70 type HkdfSha512 = hkdf::Hkdf<sha2::OpenSslSha512>; 71 type HmacSha512 = hmac::Hmac<sha2::OpenSslSha512>; 72 type AesCbcPkcs7Padded = aes::OpenSslAesCbcPkcs7; 73 type X25519 = x25519::X25519Ecdh; 74 type P256 = p256::P256Ecdh; 75 type Sha256 = sha2::OpenSslSha256; 76 type Sha512 = sha2::OpenSslSha512; 77 type Aes128 = aes::Aes128; 78 type Aes256 = aes::Aes256; 79 type AesCtr128 = aes::OpenSslAesCtr128; 80 type AesCtr256 = aes::OpenSslAesCtr256; 81 type Ed25519 = ed25519::Ed25519; 82 type CryptoRng = OpenSslRng; 83 constant_time_eq(a: &[u8], b: &[u8]) -> bool84 fn constant_time_eq(a: &[u8], b: &[u8]) -> bool { 85 a.len() == b.len() && openssl::memcmp::eq(a, b) 86 } 87 } 88 89 /// OpenSSL implemented random number generator 90 pub struct OpenSslRng; 91 92 impl CryptoRng for OpenSslRng { new() -> Self93 fn new() -> Self { 94 OpenSslRng {} 95 } 96 next_u64(&mut self) -> u6497 fn next_u64(&mut self) -> u64 { 98 let mut buf = [0; 8]; 99 rand_bytes(&mut buf).unwrap(); 100 u64::from_be_bytes(buf) 101 } 102 fill(&mut self, dest: &mut [u8])103 fn fill(&mut self, dest: &mut [u8]) { 104 rand_bytes(dest).expect("Error in generating random bytes") 105 } 106 } 107 108 #[cfg(test)] 109 mod tests { 110 use crate::Openssl; 111 use core::marker::PhantomData; 112 use crypto_provider::sha2::testing::*; 113 use crypto_provider::testing::*; 114 115 #[apply(sha2_test_cases)] sha2_tests(testcase: CryptoProviderTestCase<Openssl>)116 fn sha2_tests(testcase: CryptoProviderTestCase<Openssl>) { 117 testcase(PhantomData); 118 } 119 120 #[apply(constant_time_eq_test_cases)] constant_time_eq_tests(testcase: CryptoProviderTestCase<Openssl>)121 fn constant_time_eq_tests(testcase: CryptoProviderTestCase<Openssl>) { 122 testcase(PhantomData); 123 } 124 } 125