Fix AES256 using wrong hash
Add TLS 1.2 Move aead crypter to boring-additions crate
This commit is contained in:
parent
5c45b9426b
commit
319029f2d4
17 changed files with 424 additions and 51 deletions
|
|
@ -1,5 +1,7 @@
|
|||
[workspace]
|
||||
members = [
|
||||
# things that should probably be in boring crate
|
||||
"boring-additions",
|
||||
# the main library and tests
|
||||
"boring-rustls-provider",
|
||||
# tests and example code
|
||||
|
|
@ -13,4 +15,6 @@ default-members = [
|
|||
resolver = "2"
|
||||
|
||||
[workspace.dependencies]
|
||||
boring = { version = "4.0", default-features = false }
|
||||
boring-sys = { version = "4.0", default-features = false }
|
||||
rustls = { version = "=0.22.0-alpha.4", default-features = false }
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Further, the rustls crypto provider API is still not stable it seems. This works
|
|||
Currently, supports only TLS 1.3:
|
||||
```
|
||||
AES_128_GCM_SHA256
|
||||
AES_256_GCM_SHA256
|
||||
AES_256_GCM_SHA384
|
||||
CHACHA20_POLY1305_SHA256
|
||||
```
|
||||
|
||||
|
|
|
|||
18
boring-additions/Cargo.toml
Normal file
18
boring-additions/Cargo.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "boring-additions"
|
||||
version = "0.0.1"
|
||||
authors = ["Jan Rüth <boring-rustls-provider@djiehmail.com>"]
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
description = "Boring additions"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
aead = { version = "0.5", default_features = false, features = ["alloc"] }
|
||||
boring = { workspace = true }
|
||||
boring-sys = { workspace = true }
|
||||
foreign-types = "0.5"
|
||||
|
||||
|
||||
|
||||
|
||||
29
boring-additions/src/helper.rs
Normal file
29
boring-additions/src/helper.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
use std::os::raw::c_int;
|
||||
|
||||
use boring::error::ErrorStack;
|
||||
|
||||
/// Check the value returned from a BoringSSL ffi call
|
||||
/// that returns a pointer.
|
||||
///
|
||||
/// If the pointer is null, this method returns the BoringSSL
|
||||
/// ErrorStack as Err, the pointer otherwise.
|
||||
pub(crate) fn cvt_p<T>(r: *mut T) -> Result<*mut T, ErrorStack> {
|
||||
if r.is_null() {
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the value returned from a BoringSSL ffi call that
|
||||
/// returns a integer.
|
||||
///
|
||||
/// Returns the BoringSSL Errorstack when the result is <= 0.
|
||||
/// And forwards the return code otherwise
|
||||
pub(crate) fn cvt(r: c_int) -> Result<i32, ErrorStack> {
|
||||
if r <= 0 {
|
||||
Err(ErrorStack::get())
|
||||
} else {
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
2
boring-additions/src/lib.rs
Normal file
2
boring-additions/src/lib.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
pub mod aead;
|
||||
pub(crate) mod helper;
|
||||
|
|
@ -8,16 +8,19 @@ description = "Boringssl rustls provider"
|
|||
publish = false
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["tls12"]
|
||||
# Use a FIPS-validated version of boringssl.
|
||||
#fips = ["boring/fips", "boring-sys/fips"]
|
||||
logging = ["log"]
|
||||
fips-only = []
|
||||
tls12 = ["rustls/tls12"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
aead = {version = "0.5", default_features = false, features = ["alloc"] }
|
||||
boring = { version = "4.0", default-features = false }
|
||||
boring-sys = { version = "4.0", default-features = false }
|
||||
boring = { workspace = true }
|
||||
boring-additions = { path = "../boring-additions" }
|
||||
boring-sys = { workspace = true }
|
||||
foreign-types = "0.5"
|
||||
lazy_static = "1.4"
|
||||
log = { version = "0.4.4", optional = true }
|
||||
|
|
|
|||
|
|
@ -2,28 +2,37 @@ use std::marker::PhantomData;
|
|||
|
||||
use aead::{AeadCore, AeadInPlace, Nonce, Tag};
|
||||
use boring::error::ErrorStack;
|
||||
use rustls::crypto::cipher::{self, make_tls13_aad, Iv};
|
||||
use boring_additions::aead::Algorithm;
|
||||
use rustls::crypto::cipher::{self, make_tls12_aad, make_tls13_aad, Iv};
|
||||
use rustls::{ConnectionTrafficSecrets, ContentType, ProtocolVersion};
|
||||
|
||||
use crate::helper::error_stack_to_aead_error;
|
||||
|
||||
use self::aead2::Algorithm;
|
||||
|
||||
pub(crate) mod aead2;
|
||||
pub(crate) mod aes;
|
||||
pub(crate) mod chacha20;
|
||||
|
||||
pub(crate) trait BoringCipher {
|
||||
/// Constructs a new instance of this cipher as an AEAD algorithm
|
||||
fn new() -> Algorithm;
|
||||
/// The key size in bytes
|
||||
fn key_size() -> usize;
|
||||
/// The IV's fixed length (Not the full IV length, only the part that doesn't change).
|
||||
/// Together with [`BoringCipher::explicit_nonce_len`] it determines the total
|
||||
/// lengths of the used nonce.
|
||||
fn fixed_iv_len() -> usize;
|
||||
/// The lengths of the explicit nonce. (Not the full nonce length, only the part that changes)
|
||||
/// See also [`BoringCipher::fixed_iv_len`]
|
||||
fn explicit_nonce_len() -> usize;
|
||||
/// Extract keys
|
||||
fn extract_keys(key: cipher::AeadKey, iv: cipher::Iv) -> ConnectionTrafficSecrets;
|
||||
}
|
||||
|
||||
pub(crate) trait BoringAead: BoringCipher + AeadCore + Send + Sync {}
|
||||
|
||||
pub(crate) struct BoringAeadCrypter<T: BoringAead> {
|
||||
crypter: aead2::Crypter,
|
||||
crypter: boring_additions::aead::Crypter,
|
||||
iv: Iv,
|
||||
tls_version: ProtocolVersion,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
|
|
@ -41,7 +50,14 @@ impl<T: BoringAead> AeadCore for BoringAeadCrypter<T> {
|
|||
}
|
||||
|
||||
impl<T: BoringAead> BoringAeadCrypter<T> {
|
||||
pub fn new(iv: Iv, key: &[u8]) -> Result<Self, ErrorStack> {
|
||||
pub fn new(iv: Iv, key: &[u8], tls_version: ProtocolVersion) -> Result<Self, ErrorStack> {
|
||||
assert!(match tls_version {
|
||||
#[cfg(feature = "tls12")]
|
||||
ProtocolVersion::TLSv1_2 => true,
|
||||
ProtocolVersion::TLSv1_3 => true,
|
||||
_ => false,
|
||||
});
|
||||
|
||||
let cipher = <T as BoringCipher>::new();
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -50,8 +66,9 @@ impl<T: BoringAead> BoringAeadCrypter<T> {
|
|||
);
|
||||
|
||||
let crypter = BoringAeadCrypter {
|
||||
crypter: aead2::Crypter::new(cipher, key)?,
|
||||
crypter: boring_additions::aead::Crypter::new(cipher, key)?,
|
||||
iv,
|
||||
tls_version,
|
||||
phantom: PhantomData,
|
||||
};
|
||||
Ok(crypter)
|
||||
|
|
@ -104,17 +121,34 @@ where
|
|||
|
||||
let nonce = cipher::Nonce::new(&self.iv, seq);
|
||||
|
||||
let aad = cipher::make_tls13_aad(total_len);
|
||||
self.encrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, &mut payload)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
cipher::OpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
match self.tls_version {
|
||||
#[cfg(feature = "tls12")]
|
||||
ProtocolVersion::TLSv1_2 => {
|
||||
let aad = cipher::make_tls12_aad(seq, msg.typ, msg.version, total_len);
|
||||
self.encrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, &mut payload)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| cipher::OpaqueMessage::new(msg.typ, msg.version, payload))
|
||||
}
|
||||
ProtocolVersion::TLSv1_3 => {
|
||||
let aad = cipher::make_tls13_aad(total_len);
|
||||
self.encrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, &mut payload)
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
cipher::OpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
|
||||
// Next version seems to add this
|
||||
// fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
// payload_len + 1 + self.crypter.max_overhead()
|
||||
// }
|
||||
}
|
||||
|
||||
impl<T> cipher::MessageDecrypter for BoringAeadCrypter<T>
|
||||
|
|
@ -126,18 +160,26 @@ where
|
|||
mut m: cipher::OpaqueMessage,
|
||||
seq: u64,
|
||||
) -> Result<cipher::PlainMessage, rustls::Error> {
|
||||
let payload = m.payload_mut();
|
||||
|
||||
// construct nonce
|
||||
let nonce = cipher::Nonce::new(&self.iv, seq);
|
||||
|
||||
// construct the aad
|
||||
let aad = make_tls13_aad(payload.len());
|
||||
|
||||
// decrypt on clone to ensure this can be done in parallel
|
||||
self.decrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, payload)
|
||||
.map_err(|_| rustls::Error::DecryptError)
|
||||
.and_then(|_| m.into_tls13_unpadded_message())
|
||||
// construct the aad and decrypt
|
||||
match self.tls_version {
|
||||
#[cfg(feature = "tls12")]
|
||||
ProtocolVersion::TLSv1_2 => {
|
||||
let aad = make_tls12_aad(seq, m.typ, m.version, m.payload().len());
|
||||
self.decrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, m.payload_mut())
|
||||
.map_err(|_| rustls::Error::DecryptError)
|
||||
.map(|_| m.into_plain_message())
|
||||
}
|
||||
ProtocolVersion::TLSv1_3 => {
|
||||
let aad = make_tls13_aad(m.payload().len());
|
||||
self.decrypt_in_place(Nonce::<T>::from_slice(&nonce.0), &aad, m.payload_mut())
|
||||
.map_err(|_| rustls::Error::DecryptError)
|
||||
.and_then(|_| m.into_tls13_unpadded_message())
|
||||
}
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,13 +195,15 @@ impl<T: BoringCipher> Aead<T> {
|
|||
impl<T: BoringAead + 'static> cipher::Tls13AeadAlgorithm for Aead<T> {
|
||||
fn encrypter(&self, key: cipher::AeadKey, iv: cipher::Iv) -> Box<dyn cipher::MessageEncrypter> {
|
||||
Box::new(
|
||||
BoringAeadCrypter::<T>::new(iv, key.as_ref()).expect("failed to create AEAD crypter"),
|
||||
BoringAeadCrypter::<T>::new(iv, key.as_ref(), ProtocolVersion::TLSv1_3)
|
||||
.expect("failed to create AEAD crypter"),
|
||||
)
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: cipher::AeadKey, iv: cipher::Iv) -> Box<dyn cipher::MessageDecrypter> {
|
||||
Box::new(
|
||||
BoringAeadCrypter::<T>::new(iv, key.as_ref()).expect("failed to create AEAD crypter"),
|
||||
BoringAeadCrypter::<T>::new(iv, key.as_ref(), ProtocolVersion::TLSv1_3)
|
||||
.expect("failed to create AEAD crypter"),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -175,3 +219,45 @@ impl<T: BoringAead + 'static> cipher::Tls13AeadAlgorithm for Aead<T> {
|
|||
Ok(<T as BoringCipher>::extract_keys(key, iv))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "tls12")]
|
||||
impl<T: BoringAead + 'static> cipher::Tls12AeadAlgorithm for Aead<T> {
|
||||
fn encrypter(
|
||||
&self,
|
||||
key: cipher::AeadKey,
|
||||
iv: &[u8],
|
||||
_extra: &[u8],
|
||||
) -> Box<dyn cipher::MessageEncrypter> {
|
||||
Box::new(
|
||||
BoringAeadCrypter::<T>::new(Iv::copy(iv), key.as_ref(), ProtocolVersion::TLSv1_2)
|
||||
.expect("failed to create AEAD crypter"),
|
||||
)
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: cipher::AeadKey, iv: &[u8]) -> Box<dyn cipher::MessageDecrypter> {
|
||||
Box::new(
|
||||
BoringAeadCrypter::<T>::new(Iv::copy(iv), key.as_ref(), ProtocolVersion::TLSv1_2)
|
||||
.expect("failed to create AEAD crypter"),
|
||||
)
|
||||
}
|
||||
|
||||
fn key_block_shape(&self) -> cipher::KeyBlockShape {
|
||||
cipher::KeyBlockShape {
|
||||
enc_key_len: <T as BoringCipher>::key_size(),
|
||||
// there is no benefit of splitting these up here, we'd need to stich them anyways
|
||||
// by only setting fixed_iv_len we get the full lengths
|
||||
fixed_iv_len: <T as BoringCipher>::fixed_iv_len()
|
||||
+ <T as BoringCipher>::explicit_nonce_len(),
|
||||
explicit_nonce_len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: cipher::AeadKey,
|
||||
iv: &[u8],
|
||||
_explicit: &[u8],
|
||||
) -> Result<ConnectionTrafficSecrets, cipher::UnsupportedOperationError> {
|
||||
Ok(<T as BoringCipher>::extract_keys(key, Iv::copy(iv)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use super::{BoringAead, BoringCipher};
|
||||
use aead::consts::{U12, U16};
|
||||
use boring_additions::aead::Algorithm;
|
||||
use rustls::{crypto::cipher, ConnectionTrafficSecrets};
|
||||
|
||||
use super::{aead2::Algorithm, BoringAead, BoringCipher};
|
||||
|
||||
pub struct Aes128 {}
|
||||
|
||||
impl BoringAead for Aes128 {}
|
||||
|
|
@ -21,6 +21,14 @@ impl BoringCipher for Aes128 {
|
|||
fn extract_keys(key: cipher::AeadKey, iv: cipher::Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes128Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn fixed_iv_len() -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn explicit_nonce_len() -> usize {
|
||||
8
|
||||
}
|
||||
}
|
||||
|
||||
impl aead::AeadCore for Aes128 {
|
||||
|
|
@ -47,6 +55,14 @@ impl BoringCipher for Aes256 {
|
|||
fn extract_keys(key: cipher::AeadKey, iv: cipher::Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes256Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn fixed_iv_len() -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn explicit_nonce_len() -> usize {
|
||||
8
|
||||
}
|
||||
}
|
||||
|
||||
impl aead::AeadCore for Aes256 {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use super::{BoringAead, BoringCipher};
|
||||
use aead::{
|
||||
consts::{U12, U16},
|
||||
AeadCore,
|
||||
};
|
||||
use boring_additions::aead::Algorithm;
|
||||
use rustls::{crypto::cipher, ConnectionTrafficSecrets};
|
||||
|
||||
use super::{aead2::Algorithm, BoringAead, BoringCipher};
|
||||
|
||||
pub struct ChaCha20Poly1305 {}
|
||||
|
||||
impl BoringAead for ChaCha20Poly1305 {}
|
||||
|
|
@ -24,6 +24,14 @@ impl BoringCipher for ChaCha20Poly1305 {
|
|||
fn extract_keys(key: cipher::AeadKey, iv: cipher::Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Chacha20Poly1305 { key, iv }
|
||||
}
|
||||
|
||||
fn fixed_iv_len() -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn explicit_nonce_len() -> usize {
|
||||
8
|
||||
}
|
||||
}
|
||||
|
||||
impl AeadCore for ChaCha20Poly1305 {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustls::crypto::hash;
|
||||
|
||||
pub const SHA256: &dyn hash::Hash = &Hash(boring::nid::Nid::SHA256);
|
||||
pub const SHA384: &dyn hash::Hash = &Hash(boring::nid::Nid::SHA384);
|
||||
|
||||
pub struct Hash(pub boring::nid::Nid);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,13 @@ impl BoringHash for Sha256 {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Sha384();
|
||||
impl BoringHash for Sha384 {
|
||||
fn new() -> boring::hash::MessageDigest {
|
||||
boring::hash::MessageDigest::sha384()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Hkdf<T: BoringHash>(PhantomData<T>);
|
||||
|
||||
impl<T: BoringHash> Hkdf<T> {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use crate::helper::{cvt, cvt_p};
|
|||
|
||||
#[allow(unused)]
|
||||
pub const SHA256: &dyn crypto::hmac::Hmac = &BoringHmac(boring::nid::Nid::SHA256);
|
||||
pub const SHA384: &dyn crypto::hmac::Hmac = &BoringHmac(boring::nid::Nid::SHA384);
|
||||
|
||||
pub struct BoringHmac(pub boring::nid::Nid);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ mod hkdf;
|
|||
mod hmac;
|
||||
mod kx;
|
||||
mod sign;
|
||||
#[cfg(feature = "tls12")]
|
||||
mod tls12;
|
||||
mod tls13;
|
||||
mod verify;
|
||||
|
||||
|
|
@ -27,17 +29,23 @@ impl CryptoProvider for Provider {
|
|||
}
|
||||
|
||||
fn default_cipher_suites(&self) -> &'static [SupportedCipherSuite] {
|
||||
if boring::fips::enabled() {
|
||||
ALL_FIPS_SUITES
|
||||
} else {
|
||||
#[cfg(feature = "fips-only")]
|
||||
{
|
||||
ALL_FIPS_CIPHER_SUITES
|
||||
}
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
{
|
||||
ALL_CIPHER_SUITES
|
||||
}
|
||||
}
|
||||
|
||||
fn default_kx_groups(&self) -> &'static [&'static dyn SupportedKxGroup] {
|
||||
if boring::fips::enabled() {
|
||||
#[cfg(feature = "fips-only")]
|
||||
{
|
||||
ALL_FIPS_KX_GROUPS
|
||||
} else {
|
||||
}
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
{
|
||||
ALL_KX_GROUPS
|
||||
}
|
||||
}
|
||||
|
|
@ -52,22 +60,65 @@ impl CryptoProvider for Provider {
|
|||
}
|
||||
|
||||
fn signature_verification_algorithms(&self) -> rustls::WebPkiSupportedAlgorithms {
|
||||
verify::ALL_ALGORITHMS
|
||||
#[cfg(feature = "fips-only")]
|
||||
{
|
||||
verify::ALL_FIPS_ALGORITHMS
|
||||
}
|
||||
#[cfg(not(feature = "fips-only"))]
|
||||
{
|
||||
verify::ALL_ALGORITHMS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ALL_FIPS_SUITES: &[SupportedCipherSuite] = &[
|
||||
#[allow(unused)]
|
||||
static ALL_FIPS_CIPHER_SUITES: &[SupportedCipherSuite] = &[
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_256_GCM_SHA384),
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_128_GCM_SHA256),
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_256_GCM_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_ECDSA_AES256_GCM_SHA384),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_AES256_GCM_SHA384),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_ECDSA_AES128_GCM_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_AES128_GCM_SHA256),
|
||||
];
|
||||
|
||||
#[allow(unused)]
|
||||
static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_128_GCM_SHA256),
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_256_GCM_SHA256),
|
||||
SupportedCipherSuite::Tls13(&tls13::CHACHA20_POLY1305_SHA256),
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_256_GCM_SHA384),
|
||||
SupportedCipherSuite::Tls13(&tls13::AES_128_GCM_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_ECDSA_AES256_GCM_SHA384),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_AES256_GCM_SHA384),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_ECDSA_AES128_GCM_SHA256),
|
||||
#[cfg(feature = "tls12")]
|
||||
SupportedCipherSuite::Tls12(&tls12::ECDHE_RSA_AES128_GCM_SHA256),
|
||||
];
|
||||
|
||||
pub const ALL_FIPS_KX_GROUPS: &[&dyn SupportedKxGroup] = &[];
|
||||
/// Allowed KX curves for FIPS are recommended
|
||||
/// in [NIST SP 800-186](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-186.pdf)
|
||||
///
|
||||
/// See Sec. 3.1.2 Table 2
|
||||
/// Ordered in decending order of security strength
|
||||
#[allow(unused)]
|
||||
pub const ALL_FIPS_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
|
||||
&kx::Secp521r1 as _, // P-521 in FIPS lingo
|
||||
&kx::X448 as _, // Curve448 in FIPS lingo
|
||||
&kx::Secp384r1 as _, // P-384 in FIPS lingo
|
||||
&kx::X25519 as _, // Curve25519 in FIPS lingo
|
||||
&kx::Secp256r1 as _, // P-256 in FIPS lingo
|
||||
];
|
||||
|
||||
#[allow(unused)]
|
||||
pub const ALL_KX_GROUPS: &[&dyn SupportedKxGroup] = &[
|
||||
&kx::X25519 as _,
|
||||
&kx::X448 as _,
|
||||
|
|
|
|||
89
boring-rustls-provider/src/tls12.rs
Normal file
89
boring-rustls-provider/src/tls12.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
use rustls::{crypto, SignatureScheme, Tls12CipherSuite};
|
||||
|
||||
use crate::{aead, hash, hmac};
|
||||
|
||||
static ALL_ECDSA_SCHEMES: &[SignatureScheme] = &[
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
SignatureScheme::ED25519,
|
||||
SignatureScheme::ED448,
|
||||
];
|
||||
|
||||
static ALL_RSA_SCHEMES: &[SignatureScheme] = &[
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
SignatureScheme::RSA_PKCS1_SHA384,
|
||||
SignatureScheme::RSA_PKCS1_SHA512,
|
||||
SignatureScheme::RSA_PSS_SHA256,
|
||||
SignatureScheme::RSA_PSS_SHA384,
|
||||
SignatureScheme::RSA_PSS_SHA512,
|
||||
];
|
||||
|
||||
const PRF_SHA256: crypto::tls12::PrfUsingHmac<'_> = crypto::tls12::PrfUsingHmac(hmac::SHA256);
|
||||
const PRF_SHA384: crypto::tls12::PrfUsingHmac<'_> = crypto::tls12::PrfUsingHmac(hmac::SHA384);
|
||||
|
||||
pub static ECDHE_ECDSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
hash_provider: hash::SHA256,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
|
||||
prf_provider: &PRF_SHA256,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_ECDSA_SCHEMES,
|
||||
};
|
||||
|
||||
pub static ECDHE_RSA_AES128_GCM_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
hash_provider: hash::SHA256,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
|
||||
prf_provider: &PRF_SHA256,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_RSA_SCHEMES,
|
||||
};
|
||||
|
||||
pub static ECDHE_ECDSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
hash_provider: hash::SHA384,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
|
||||
prf_provider: &PRF_SHA384,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_ECDSA_SCHEMES,
|
||||
};
|
||||
|
||||
pub static ECDHE_RSA_AES256_GCM_SHA384: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
hash_provider: hash::SHA384,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
|
||||
prf_provider: &PRF_SHA384,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_RSA_SCHEMES,
|
||||
};
|
||||
|
||||
pub static ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: hash::SHA256,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::chacha20::ChaCha20Poly1305>::DEFAULT,
|
||||
prf_provider: &PRF_SHA256,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_ECDSA_SCHEMES,
|
||||
};
|
||||
|
||||
pub static ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: Tls12CipherSuite = Tls12CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: hash::SHA256,
|
||||
},
|
||||
aead_alg: &aead::Aead::<aead::chacha20::ChaCha20Poly1305>::DEFAULT,
|
||||
prf_provider: &PRF_SHA256,
|
||||
kx: crypto::KeyExchangeAlgorithm::ECDHE,
|
||||
sign: ALL_RSA_SCHEMES,
|
||||
};
|
||||
|
|
@ -11,12 +11,12 @@ pub static AES_128_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite {
|
|||
aead_alg: &aead::Aead::<aead::aes::Aes128>::DEFAULT,
|
||||
};
|
||||
|
||||
pub static AES_256_GCM_SHA256: Tls13CipherSuite = Tls13CipherSuite {
|
||||
pub static AES_256_GCM_SHA384: Tls13CipherSuite = Tls13CipherSuite {
|
||||
common: rustls::CipherSuiteCommon {
|
||||
suite: rustls::CipherSuite::TLS13_AES_128_GCM_SHA256,
|
||||
hash_provider: hash::SHA256,
|
||||
suite: rustls::CipherSuite::TLS13_AES_256_GCM_SHA384,
|
||||
hash_provider: hash::SHA384,
|
||||
},
|
||||
hkdf_provider: &hkdf::Hkdf::<hkdf::Sha256>::DEFAULT,
|
||||
hkdf_provider: &hkdf::Hkdf::<hkdf::Sha384>::DEFAULT,
|
||||
aead_alg: &aead::Aead::<aead::aes::Aes256>::DEFAULT,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ pub(crate) mod ec;
|
|||
mod ed;
|
||||
pub(crate) mod rsa;
|
||||
|
||||
#[allow(unused)]
|
||||
pub static ALL_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
|
||||
all: &[
|
||||
&rsa::BoringRsaVerifier::RSA_PKCS1_SHA256,
|
||||
|
|
@ -59,3 +60,60 @@ pub static ALL_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms
|
|||
(SignatureScheme::ED448, &[&ed::BoringEdVerifier::ED448]),
|
||||
],
|
||||
};
|
||||
|
||||
#[allow(unused)]
|
||||
pub static ALL_FIPS_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
|
||||
all: &[
|
||||
&rsa::BoringRsaVerifier::RSA_PKCS1_SHA256,
|
||||
&rsa::BoringRsaVerifier::RSA_PKCS1_SHA384,
|
||||
&rsa::BoringRsaVerifier::RSA_PKCS1_SHA512,
|
||||
&rsa::BoringRsaVerifier::RSA_PSS_SHA256,
|
||||
&rsa::BoringRsaVerifier::RSA_PSS_SHA384,
|
||||
&rsa::BoringRsaVerifier::RSA_PSS_SHA512,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP256_SHA256,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP384_SHA384,
|
||||
&ec::BoringEcVerifier::ECDSA_NISTP521_SHA512,
|
||||
//&ed::BoringEdVerifier::ED25519, // FIPS 186-5: requires SHA512 but boring doesn't want us to set a digest, correct?
|
||||
//&ed::BoringEdVerifier::ED448, // FIPS 186-5: requires SHAKE256 but boring doesn't want us to set a digest, correct?
|
||||
],
|
||||
mapping: &[
|
||||
(
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PKCS1_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::RSA_PKCS1_SHA384,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PKCS1_SHA384],
|
||||
),
|
||||
(
|
||||
SignatureScheme::RSA_PKCS1_SHA512,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PKCS1_SHA512],
|
||||
),
|
||||
(
|
||||
SignatureScheme::RSA_PSS_SHA256,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PSS_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::RSA_PSS_SHA384,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PSS_SHA384],
|
||||
),
|
||||
(
|
||||
SignatureScheme::RSA_PSS_SHA512,
|
||||
&[&rsa::BoringRsaVerifier::RSA_PSS_SHA512],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
&[&ec::BoringEcVerifier::ECDSA_NISTP256_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
&[&ec::BoringEcVerifier::ECDSA_NISTP384_SHA384],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP521_SHA512,
|
||||
&[&ec::BoringEcVerifier::ECDSA_NISTP521_SHA512],
|
||||
),
|
||||
// (SignatureScheme::ED25519, &[&ed::BoringEdVerifier::ED25519]),
|
||||
// (SignatureScheme::ED448, &[&ed::BoringEdVerifier::ED448]),
|
||||
],
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue