blob: 8d1db1d515c92fef8d86778414f318ca187ee8ff [file] [log] [blame]
#![forbid(unsafe_code)]
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![deny(missing_docs, clippy::indexing_slicing, clippy::panic)]
//! Crate which provides impls for CryptoProvider backed by openssl
use cfg_if::cfg_if;
pub use openssl;
use openssl::hash::MessageDigest;
use openssl::md::MdRef;
use openssl::rand::rand_bytes;
use crypto_provider::CryptoRng;
/// Contains the openssl backed AES implementations for CryptoProvider
mod aes;
/// Contains the openssl backed ed25519 impl for key generation, verification, and signing
mod ed25519;
cfg_if! {
if #[cfg(feature = "boringssl")] {
/// Contains the boringssl backed hkdf impl for CryptoProvider
mod hkdf_boringssl;
use hkdf_boringssl as hkdf;
/// Contains the boringssl backed hmac impl for CryptoProvider
mod hmac_boringssl;
use hmac_boringssl as hmac;
} else {
/// Contains the openssl backed hkdf impl for CryptoProvider
mod hkdf_openssl;
use hkdf_openssl as hkdf;
/// Contains the openssl backed hmac impl for CryptoProvider
mod hmac_openssl;
use hmac_openssl as hmac;
}
}
/// Contains the openssl backed NIST-P256 impl for CryptoProvider
mod p256;
/// Contains the openssl backed SHA2 impl for CryptoProvider
mod sha2;
/// Contains the openssl backed X25519 impl for CryptoProvider
mod x25519;
/// The the openssl backed struct which implements CryptoProvider
#[derive(Default, Clone, Debug, PartialEq, Eq)]
pub struct Openssl;
/// The trait which defines a has used in openssl crypto operations
pub trait OpenSslHash {
/// gets the message digest algorithm to be used by the hmac implementation
fn get_digest() -> MessageDigest;
/// gets a reference to a message digest algorithm to be used by the hkdf implementation
fn get_md() -> &'static MdRef;
}
impl crypto_provider::CryptoProvider for Openssl {
type HkdfSha256 = hkdf::Hkdf<sha2::OpenSslSha256>;
type HmacSha256 = hmac::Hmac<sha2::OpenSslSha256>;
type HkdfSha512 = hkdf::Hkdf<sha2::OpenSslSha512>;
type HmacSha512 = hmac::Hmac<sha2::OpenSslSha512>;
type AesCbcPkcs7Padded = aes::OpenSslAesCbcPkcs7;
type X25519 = x25519::X25519Ecdh;
type P256 = p256::P256Ecdh;
type Sha256 = sha2::OpenSslSha256;
type Sha512 = sha2::OpenSslSha512;
type Aes128 = aes::Aes128;
type Aes256 = aes::Aes256;
type AesCtr128 = aes::OpenSslAesCtr128;
type AesCtr256 = aes::OpenSslAesCtr256;
type Ed25519 = ed25519::Ed25519;
type Aes128GcmSiv = crypto_provider_stubs::Aes128Stubs;
type Aes256GcmSiv = crypto_provider_stubs::Aes256Stubs;
type Aes128Gcm = crypto_provider_stubs::Aes128Stubs;
type Aes256Gcm = crypto_provider_stubs::Aes256Stubs;
type CryptoRng = OpenSslRng;
fn constant_time_eq(a: &[u8], b: &[u8]) -> bool {
a.len() == b.len() && openssl::memcmp::eq(a, b)
}
}
/// OpenSSL implemented random number generator
pub struct OpenSslRng;
impl CryptoRng for OpenSslRng {
fn new() -> Self {
OpenSslRng {}
}
fn next_u64(&mut self) -> u64 {
let mut buf = [0; 8];
rand_bytes(&mut buf).unwrap();
u64::from_be_bytes(buf)
}
fn fill(&mut self, dest: &mut [u8]) {
rand_bytes(dest).expect("Error in generating random bytes")
}
}
#[cfg(test)]
mod tests {
use core::marker::PhantomData;
use crypto_provider_test::sha2::*;
use crypto_provider_test::{prelude::*, *};
use crate::Openssl;
#[apply(sha2_test_cases)]
fn sha2_tests(testcase: CryptoProviderTestCase<Openssl>) {
testcase(PhantomData);
}
#[apply(constant_time_eq_test_cases)]
fn constant_time_eq_tests(testcase: CryptoProviderTestCase<Openssl>) {
testcase(PhantomData);
}
}