cryptic: reorganize symmetric ciphers
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@ $ env set initrd_addr_r 0x70000000
|
||||
$ env set bootargs "debug.serial-level=info"
|
||||
$ tftpboot ${initrd_addr_r} <BUILD-MACHINE-IP-ADDR>:initrd.tar
|
||||
$ tftpboot ${loadaddr} <BUILD-MACHINE-IP-ADDR>:kernel.bin
|
||||
$ load mmc 1:3 ${fdt_addr_r} dtbs/...-starfive/starfive/${fdtfile}
|
||||
$ load mmc 1:3 ${fdt_addr_r} dtbs/6.6.20-starfive/starfive/${fdtfile}
|
||||
$ fdt resize
|
||||
$ booti ${loadaddr} ${initrd_addr_r}:<initrd-size> ${fdt_addr_r}
|
||||
|
||||
|
||||
@@ -1,246 +0,0 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use aead::{consts::U16, AeadInPlace};
|
||||
use aes::cipher::{BlockCipher, BlockEncrypt, BlockSizeUser};
|
||||
use aes_gcm::{KeyInit, KeySizeUser};
|
||||
use chacha20poly1305::consts::U12;
|
||||
use rustls::{
|
||||
crypto::cipher::{
|
||||
make_tls12_aad, make_tls13_aad, AeadKey, InboundOpaqueMessage, InboundPlainMessage, Iv,
|
||||
KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce, OutboundOpaqueMessage,
|
||||
OutboundPlainMessage, PrefixedPayload, Tls12AeadAlgorithm, Tls13AeadAlgorithm,
|
||||
UnsupportedOperationError,
|
||||
},
|
||||
ConnectionTrafficSecrets, ContentType, ProtocolVersion,
|
||||
};
|
||||
|
||||
use crate::cipher::{DecryptBufferAdapter, EncryptBufferAdapter};
|
||||
|
||||
pub(crate) struct AesGcm<Aes>(PhantomData<Aes>);
|
||||
|
||||
struct Tls13Cipher<Aes>(aes_gcm::AesGcm<Aes, U12>, Iv);
|
||||
struct Tls12Cipher<Aes>(aes_gcm::AesGcm<Aes, U12>, Iv);
|
||||
|
||||
const AES_GCM_OVERHEAD: usize = 16;
|
||||
|
||||
pub(crate) static AES128GCM: AesGcm<aes::Aes128> = AesGcm(PhantomData);
|
||||
pub(crate) static AES256GCM: AesGcm<aes::Aes256> = AesGcm(PhantomData);
|
||||
|
||||
pub(crate) trait AesExtractKeys {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets;
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets;
|
||||
}
|
||||
|
||||
impl AesExtractKeys for aes::Aes128 {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes128Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets {
|
||||
let _ = explicit;
|
||||
ConnectionTrafficSecrets::Aes128Gcm {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AesExtractKeys for aes::Aes256 {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes256Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets {
|
||||
let _ = explicit;
|
||||
ConnectionTrafficSecrets::Aes256Gcm {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> Tls13AeadAlgorithm for AesGcm<Aes>
|
||||
where
|
||||
Aes: Send
|
||||
+ Sync
|
||||
+ AesExtractKeys
|
||||
+ BlockCipher
|
||||
+ BlockSizeUser<BlockSize = U16>
|
||||
+ BlockEncrypt
|
||||
+ 'static,
|
||||
aes_gcm::AesGcm<Aes, U12>: KeySizeUser + KeyInit,
|
||||
{
|
||||
fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
|
||||
Box::new(Tls13Cipher::<Aes>(
|
||||
aes_gcm::AesGcm::new_from_slice(key.as_ref()).unwrap(),
|
||||
iv,
|
||||
))
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
|
||||
Box::new(Tls13Cipher::<Aes>(
|
||||
aes_gcm::AesGcm::new_from_slice(key.as_ref()).unwrap(),
|
||||
iv,
|
||||
))
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: Iv,
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
Ok(Aes::tls13_wrap_keys(key, iv))
|
||||
}
|
||||
|
||||
fn key_len(&self) -> usize {
|
||||
aes_gcm::AesGcm::<Aes, U12>::key_size()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> Tls12AeadAlgorithm for AesGcm<Aes>
|
||||
where
|
||||
Aes: Send
|
||||
+ Sync
|
||||
+ AesExtractKeys
|
||||
+ BlockCipher
|
||||
+ BlockSizeUser<BlockSize = U16>
|
||||
+ BlockEncrypt
|
||||
+ 'static,
|
||||
aes_gcm::AesGcm<Aes, U12>: KeySizeUser + KeyInit,
|
||||
{
|
||||
fn encrypter(&self, key: AeadKey, iv: &[u8], extra: &[u8]) -> Box<dyn MessageEncrypter> {
|
||||
let _ = extra;
|
||||
Box::new(Tls12Cipher::<Aes>(
|
||||
aes_gcm::AesGcm::new_from_slice(key.as_ref()).unwrap(),
|
||||
Iv::copy(iv),
|
||||
))
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecrypter> {
|
||||
Box::new(Tls12Cipher::<Aes>(
|
||||
aes_gcm::AesGcm::new_from_slice(key.as_ref()).unwrap(),
|
||||
Iv::copy(iv),
|
||||
))
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: &[u8],
|
||||
explicit: &[u8],
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
Ok(Aes::tls12_wrap_keys(key, iv, explicit))
|
||||
}
|
||||
|
||||
fn key_block_shape(&self) -> KeyBlockShape {
|
||||
KeyBlockShape {
|
||||
enc_key_len: aes_gcm::AesGcm::<Aes, U12>::key_size(),
|
||||
fixed_iv_len: 12,
|
||||
explicit_nonce_len: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> MessageEncrypter for Tls13Cipher<Aes>
|
||||
where
|
||||
Aes: Send + Sync + BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt,
|
||||
{
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
payload.extend_from_slice(&msg.typ.to_array());
|
||||
let nonce = aes_gcm::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(total_len);
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
OutboundOpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + 1 + AES_GCM_OVERHEAD
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> MessageDecrypter for Tls13Cipher<Aes>
|
||||
where
|
||||
Aes: Send + Sync + BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt,
|
||||
{
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &mut msg.payload;
|
||||
let nonce = aes_gcm::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(payload.len());
|
||||
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
msg.into_tls13_unpadded_message()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> MessageEncrypter for Tls12Cipher<Aes>
|
||||
where
|
||||
Aes: Send + Sync + BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt,
|
||||
{
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
let nonce = chacha20poly1305::Nonce::from(Nonce::new(&self.1, 0).0);
|
||||
let aad = make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len());
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| OutboundOpaqueMessage::new(msg.typ, msg.version, payload))
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + AES_GCM_OVERHEAD
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> MessageDecrypter for Tls12Cipher<Aes>
|
||||
where
|
||||
Aes: Send + Sync + BlockCipher + BlockSizeUser<BlockSize = U16> + BlockEncrypt,
|
||||
{
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &msg.payload;
|
||||
let nonce = chacha20poly1305::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls12_aad(seq, msg.typ, msg.version, payload.len() - AES_GCM_OVERHEAD);
|
||||
|
||||
let payload = &mut msg.payload;
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
Ok(msg.into_plain_message())
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
use aead::AeadInPlace;
|
||||
use chacha20poly1305::{KeyInit, KeySizeUser};
|
||||
use rustls::{
|
||||
crypto::cipher::{
|
||||
make_tls12_aad, make_tls13_aad, AeadKey, InboundOpaqueMessage, InboundPlainMessage, Iv,
|
||||
KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce, OutboundOpaqueMessage,
|
||||
OutboundPlainMessage, PrefixedPayload, Tls12AeadAlgorithm, Tls13AeadAlgorithm,
|
||||
UnsupportedOperationError,
|
||||
},
|
||||
ConnectionTrafficSecrets, ContentType, ProtocolVersion,
|
||||
};
|
||||
|
||||
use crate::cipher::{DecryptBufferAdapter, EncryptBufferAdapter};
|
||||
|
||||
pub(crate) struct Chacha20Poly1305;
|
||||
|
||||
struct Tls13Cipher(chacha20poly1305::ChaCha20Poly1305, Iv);
|
||||
struct Tls12Cipher(chacha20poly1305::ChaCha20Poly1305, Iv);
|
||||
|
||||
const CHACHA20POLY1305_OVERHEAD: usize = 16;
|
||||
|
||||
impl Tls13AeadAlgorithm for Chacha20Poly1305 {
|
||||
fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
|
||||
Box::new(Tls13Cipher(
|
||||
chacha20poly1305::ChaCha20Poly1305::new_from_slice(key.as_ref()).unwrap(),
|
||||
iv,
|
||||
))
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
|
||||
Box::new(Tls13Cipher(
|
||||
chacha20poly1305::ChaCha20Poly1305::new_from_slice(key.as_ref()).unwrap(),
|
||||
iv,
|
||||
))
|
||||
}
|
||||
|
||||
fn key_len(&self) -> usize {
|
||||
chacha20poly1305::ChaCha20Poly1305::key_size()
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: Iv,
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
Ok(ConnectionTrafficSecrets::Chacha20Poly1305 { key, iv })
|
||||
}
|
||||
}
|
||||
|
||||
impl Tls12AeadAlgorithm for Chacha20Poly1305 {
|
||||
fn encrypter(&self, key: AeadKey, iv: &[u8], extra: &[u8]) -> Box<dyn MessageEncrypter> {
|
||||
let _ = extra;
|
||||
Box::new(Tls12Cipher(
|
||||
chacha20poly1305::ChaCha20Poly1305::new_from_slice(key.as_ref()).unwrap(),
|
||||
Iv::copy(iv),
|
||||
))
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecrypter> {
|
||||
Box::new(Tls12Cipher(
|
||||
chacha20poly1305::ChaCha20Poly1305::new_from_slice(key.as_ref()).unwrap(),
|
||||
Iv::copy(iv),
|
||||
))
|
||||
}
|
||||
|
||||
fn key_block_shape(&self) -> KeyBlockShape {
|
||||
KeyBlockShape {
|
||||
enc_key_len: 32,
|
||||
fixed_iv_len: 12,
|
||||
explicit_nonce_len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: &[u8],
|
||||
explicit: &[u8],
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
let _ = explicit;
|
||||
Ok(ConnectionTrafficSecrets::Chacha20Poly1305 {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageEncrypter for Tls13Cipher {
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
payload.extend_from_slice(&msg.typ.to_array());
|
||||
let nonce = aes_gcm::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(total_len);
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
OutboundOpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + 1 + CHACHA20POLY1305_OVERHEAD
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageDecrypter for Tls13Cipher {
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &mut msg.payload;
|
||||
let nonce = aes_gcm::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(payload.len());
|
||||
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
msg.into_tls13_unpadded_message()
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageEncrypter for Tls12Cipher {
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
let nonce = chacha20poly1305::Nonce::from(Nonce::new(&self.1, 0).0);
|
||||
let aad = make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len());
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| OutboundOpaqueMessage::new(msg.typ, msg.version, payload))
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + CHACHA20POLY1305_OVERHEAD
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageDecrypter for Tls12Cipher {
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &msg.payload;
|
||||
let nonce = chacha20poly1305::Nonce::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls12_aad(
|
||||
seq,
|
||||
msg.typ,
|
||||
msg.version,
|
||||
payload.len() - CHACHA20POLY1305_OVERHEAD,
|
||||
);
|
||||
|
||||
let payload = &mut msg.payload;
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
Ok(msg.into_plain_message())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use aes::cipher::typenum;
|
||||
use rustls::{
|
||||
crypto::cipher::{AeadKey, Iv},
|
||||
ConnectionTrafficSecrets,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
cipher::TlsAeadCipherAlgorithm,
|
||||
traits::{AeadDataInput, TlsExtractKeys},
|
||||
};
|
||||
|
||||
pub static TLS_AES128GCM: TlsAeadCipherAlgorithm<aes_gcm::AesGcm<aes::Aes128, typenum::U12>> =
|
||||
TlsAeadCipherAlgorithm(PhantomData);
|
||||
pub static TLS_AES256GCM: TlsAeadCipherAlgorithm<aes_gcm::AesGcm<aes::Aes256, typenum::U12>> =
|
||||
TlsAeadCipherAlgorithm(PhantomData);
|
||||
pub static TLS_CHACHA20POLY1305: TlsAeadCipherAlgorithm<chacha20poly1305::ChaCha20Poly1305> =
|
||||
TlsAeadCipherAlgorithm(PhantomData);
|
||||
|
||||
impl TlsExtractKeys for aes_gcm::AesGcm<aes::Aes128, typenum::U12> {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes128Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets {
|
||||
let _ = explicit;
|
||||
ConnectionTrafficSecrets::Aes128Gcm {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsExtractKeys for aes_gcm::AesGcm<aes::Aes256, typenum::U12> {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Aes256Gcm { key, iv }
|
||||
}
|
||||
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets {
|
||||
let _ = explicit;
|
||||
ConnectionTrafficSecrets::Aes256Gcm {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TlsExtractKeys for chacha20poly1305::ChaCha20Poly1305 {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets {
|
||||
ConnectionTrafficSecrets::Chacha20Poly1305 { key, iv }
|
||||
}
|
||||
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets {
|
||||
let _ = explicit;
|
||||
ConnectionTrafficSecrets::Chacha20Poly1305 {
|
||||
key,
|
||||
iv: Iv::new(iv[..].try_into().unwrap()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aes> AeadDataInput for aes_gcm::AesGcm<Aes, typenum::U12> {
|
||||
const ENCRYPTED_OVERHEAD: usize = 16;
|
||||
}
|
||||
|
||||
impl AeadDataInput for chacha20poly1305::ChaCha20Poly1305 {
|
||||
const ENCRYPTED_OVERHEAD: usize = 16;
|
||||
}
|
||||
@@ -1,7 +1,26 @@
|
||||
use rustls::crypto::cipher::{BorrowedPayload, PrefixedPayload};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub mod aes_gcm;
|
||||
pub mod chacha20poly1305;
|
||||
use aead::{generic_array::GenericArray, AeadInPlace, KeyInit};
|
||||
use rustls::{
|
||||
crypto::cipher::{
|
||||
make_tls12_aad, make_tls13_aad, AeadKey, BorrowedPayload, InboundOpaqueMessage,
|
||||
InboundPlainMessage, Iv, KeyBlockShape, MessageDecrypter, MessageEncrypter, Nonce,
|
||||
OutboundOpaqueMessage, OutboundPlainMessage, PrefixedPayload, Tls12AeadAlgorithm,
|
||||
Tls13AeadAlgorithm, UnsupportedOperationError,
|
||||
},
|
||||
ConnectionTrafficSecrets, ContentType, ProtocolVersion,
|
||||
};
|
||||
|
||||
use crate::traits::{AeadDataInput, TlsExtractKeys};
|
||||
|
||||
mod imp;
|
||||
|
||||
pub use imp::*;
|
||||
|
||||
pub(crate) struct Tls13Cipher<Aead>(pub Aead, pub Iv);
|
||||
pub(crate) struct Tls12Cipher<Aead>(pub Aead, pub Iv);
|
||||
|
||||
pub struct TlsAeadCipherAlgorithm<Aead>(PhantomData<Aead>);
|
||||
|
||||
struct EncryptBufferAdapter<'a>(&'a mut PrefixedPayload);
|
||||
struct DecryptBufferAdapter<'a, 'p>(&'a mut BorrowedPayload<'p>);
|
||||
@@ -51,3 +70,181 @@ impl aead::Buffer for DecryptBufferAdapter<'_, '_> {
|
||||
self.0.truncate(len);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> MessageEncrypter for Tls13Cipher<Aead>
|
||||
where
|
||||
Aead: Send + Sync + AeadInPlace + AeadDataInput + 'static,
|
||||
GenericArray<u8, Aead::NonceSize>: From<[u8; 12]>,
|
||||
{
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
payload.extend_from_slice(&msg.typ.to_array());
|
||||
let nonce = aead::Nonce::<Aead>::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(total_len);
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| {
|
||||
OutboundOpaqueMessage::new(
|
||||
ContentType::ApplicationData,
|
||||
ProtocolVersion::TLSv1_2,
|
||||
payload,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + Aead::ENCRYPTED_OVERHEAD + 1
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> MessageDecrypter for Tls13Cipher<Aead>
|
||||
where
|
||||
Aead: Send + Sync + AeadInPlace + AeadDataInput + 'static,
|
||||
GenericArray<u8, Aead::NonceSize>: From<[u8; 12]>,
|
||||
{
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &mut msg.payload;
|
||||
let nonce = aead::Nonce::<Aead>::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls13_aad(payload.len());
|
||||
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
msg.into_tls13_unpadded_message()
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> MessageEncrypter for Tls12Cipher<Aead>
|
||||
where
|
||||
Aead: Send + Sync + AeadInPlace + AeadDataInput + 'static,
|
||||
GenericArray<u8, Aead::NonceSize>: From<[u8; 12]>,
|
||||
{
|
||||
fn encrypt(
|
||||
&mut self,
|
||||
msg: OutboundPlainMessage<'_>,
|
||||
seq: u64,
|
||||
) -> Result<OutboundOpaqueMessage, rustls::Error> {
|
||||
let total_len = self.encrypted_payload_len(msg.payload.len());
|
||||
let mut payload = PrefixedPayload::with_capacity(total_len);
|
||||
|
||||
payload.extend_from_chunks(&msg.payload);
|
||||
let nonce = aead::Nonce::<Aead>::from(Nonce::new(&self.1, 0).0);
|
||||
let aad = make_tls12_aad(seq, msg.typ, msg.version, msg.payload.len());
|
||||
|
||||
self.0
|
||||
.encrypt_in_place(&nonce, &aad, &mut EncryptBufferAdapter(&mut payload))
|
||||
.map_err(|_| rustls::Error::EncryptError)
|
||||
.map(|_| OutboundOpaqueMessage::new(msg.typ, msg.version, payload))
|
||||
}
|
||||
|
||||
fn encrypted_payload_len(&self, payload_len: usize) -> usize {
|
||||
payload_len + Aead::ENCRYPTED_OVERHEAD
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> MessageDecrypter for Tls12Cipher<Aead>
|
||||
where
|
||||
Aead: Send + Sync + AeadInPlace + AeadDataInput + 'static,
|
||||
GenericArray<u8, Aead::NonceSize>: From<[u8; 12]>,
|
||||
{
|
||||
fn decrypt<'a>(
|
||||
&mut self,
|
||||
mut msg: InboundOpaqueMessage<'a>,
|
||||
seq: u64,
|
||||
) -> Result<InboundPlainMessage<'a>, rustls::Error> {
|
||||
let payload = &msg.payload;
|
||||
let nonce = aead::Nonce::<Aead>::from(Nonce::new(&self.1, seq).0);
|
||||
let aad = make_tls12_aad(
|
||||
seq,
|
||||
msg.typ,
|
||||
msg.version,
|
||||
payload.len() - Aead::ENCRYPTED_OVERHEAD,
|
||||
);
|
||||
|
||||
let payload = &mut msg.payload;
|
||||
self.0
|
||||
.decrypt_in_place(&nonce, &aad, &mut DecryptBufferAdapter(payload))
|
||||
.map_err(|_| rustls::Error::DecryptError)?;
|
||||
|
||||
Ok(msg.into_plain_message())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> Tls13AeadAlgorithm for TlsAeadCipherAlgorithm<Aead>
|
||||
where
|
||||
Aead: Send + Sync + TlsExtractKeys + KeyInit + 'static,
|
||||
Tls13Cipher<Aead>: MessageEncrypter + MessageDecrypter,
|
||||
{
|
||||
fn encrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageEncrypter> {
|
||||
let aead = Aead::new_from_slice(key.as_ref()).unwrap();
|
||||
let cipher = Tls13Cipher::<Aead>(aead, iv);
|
||||
Box::new(cipher)
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: Iv) -> Box<dyn MessageDecrypter> {
|
||||
let aead = Aead::new_from_slice(key.as_ref()).unwrap();
|
||||
let cipher = Tls13Cipher::<Aead>(aead, iv);
|
||||
Box::new(cipher)
|
||||
}
|
||||
|
||||
fn key_len(&self) -> usize {
|
||||
Aead::key_size()
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: Iv,
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
Ok(Aead::tls13_wrap_keys(key, iv))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Aead> Tls12AeadAlgorithm for TlsAeadCipherAlgorithm<Aead>
|
||||
where
|
||||
Aead: Send + Sync + TlsExtractKeys + KeyInit + 'static,
|
||||
Tls12Cipher<Aead>: MessageEncrypter + MessageDecrypter,
|
||||
{
|
||||
fn encrypter(&self, key: AeadKey, iv: &[u8], _extra: &[u8]) -> Box<dyn MessageEncrypter> {
|
||||
let aead = Aead::new_from_slice(key.as_ref()).unwrap();
|
||||
let cipher = Tls12Cipher::<Aead>(aead, Iv::copy(iv));
|
||||
Box::new(cipher)
|
||||
}
|
||||
|
||||
fn decrypter(&self, key: AeadKey, iv: &[u8]) -> Box<dyn MessageDecrypter> {
|
||||
let aead = Aead::new_from_slice(key.as_ref()).unwrap();
|
||||
let cipher = Tls12Cipher::<Aead>(aead, Iv::copy(iv));
|
||||
Box::new(cipher)
|
||||
}
|
||||
|
||||
fn key_block_shape(&self) -> KeyBlockShape {
|
||||
KeyBlockShape {
|
||||
enc_key_len: Aead::key_size(),
|
||||
fixed_iv_len: 12,
|
||||
explicit_nonce_len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_keys(
|
||||
&self,
|
||||
key: AeadKey,
|
||||
iv: &[u8],
|
||||
explicit: &[u8],
|
||||
) -> Result<ConnectionTrafficSecrets, UnsupportedOperationError> {
|
||||
Ok(Aead::tls12_wrap_keys(key, iv, explicit))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ pub mod hash;
|
||||
pub mod hmac;
|
||||
pub mod kx;
|
||||
pub mod rustls;
|
||||
pub mod traits;
|
||||
pub mod verify;
|
||||
|
||||
pub fn rustls_client() -> ConfigBuilder<ClientConfig, WantsVersions> {
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use rand::RngCore;
|
||||
use rustls::{
|
||||
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||
crypto::{
|
||||
tls12, tls13, CryptoProvider, GetRandomFailed, KeyExchangeAlgorithm, KeyProvider,
|
||||
SecureRandom, SupportedKxGroup, WebPkiSupportedAlgorithms,
|
||||
},
|
||||
pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime},
|
||||
sign::SigningKey,
|
||||
CipherSuite, CipherSuiteCommon, DigitallySignedStruct, SignatureScheme, SupportedCipherSuite,
|
||||
Tls12CipherSuite, Tls13CipherSuite,
|
||||
};
|
||||
|
||||
use crate::{cipher, hash, hmac, kx, verify};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Provider;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct InsecureServerCertificateVerifier;
|
||||
|
||||
impl ServerCertVerifier for InsecureServerCertificateVerifier {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
end_entity: &CertificateDer<'_>,
|
||||
intermediates: &[CertificateDer<'_>],
|
||||
server_name: &ServerName<'_>,
|
||||
ocsp_response: &[u8],
|
||||
now: UnixTime,
|
||||
) -> Result<ServerCertVerified, rustls::Error> {
|
||||
let _ = (end_entity, intermediates, server_name, ocsp_response, now);
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
let _ = (message, cert, dss);
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
let _ = (message, cert, dss);
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
SUPPORTED_SIGNATURE_SCHEMES.to_vec()
|
||||
}
|
||||
|
||||
fn requires_raw_public_keys(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn provider() -> CryptoProvider {
|
||||
CryptoProvider {
|
||||
cipher_suites: CIPHER_SUITES.to_vec(),
|
||||
kx_groups: KX_GROUPS.to_vec(),
|
||||
signature_verification_algorithms: SIGNATURE_VERIFICATION_ALGORITHMS,
|
||||
secure_random: &Provider,
|
||||
key_provider: &Provider,
|
||||
}
|
||||
}
|
||||
|
||||
impl SecureRandom for Provider {
|
||||
fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
|
||||
rand_core::OsRng
|
||||
.try_fill_bytes(buf)
|
||||
.map_err(|_| GetRandomFailed)
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyProvider for Provider {
|
||||
fn load_private_key(
|
||||
&self,
|
||||
key_der: PrivateKeyDer<'static>,
|
||||
) -> Result<Arc<dyn SigningKey>, rustls::Error> {
|
||||
let _ = key_der;
|
||||
todo!("TODO: implement signing key provider for TLS")
|
||||
}
|
||||
}
|
||||
|
||||
static CIPHER_SUITES: &[SupportedCipherSuite] = &[
|
||||
// TLSv1.3 suites
|
||||
TLS13_CHACHA20POLY1305_SHA256,
|
||||
TLS13_AES256GCM_SHA384,
|
||||
TLS13_AES128GCM_SHA256,
|
||||
// TLSv1.2 suites
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
];
|
||||
static KX_GROUPS: &[&dyn SupportedKxGroup] = &[&kx::X25519];
|
||||
static SIGNATURE_VERIFICATION_ALGORITHMS: WebPkiSupportedAlgorithms = WebPkiSupportedAlgorithms {
|
||||
all: &[
|
||||
verify::RSA_PSS_SHA256,
|
||||
verify::RSA_PKCS1_SHA256,
|
||||
verify::ECDSA_NISTP256_SHA256,
|
||||
verify::ECDSA_NISTP384_SHA384,
|
||||
],
|
||||
mapping: &[
|
||||
(SignatureScheme::RSA_PSS_SHA256, &[verify::RSA_PSS_SHA256]),
|
||||
(
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
&[verify::RSA_PKCS1_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
&[verify::ECDSA_NISTP256_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
&[verify::ECDSA_NISTP384_SHA384],
|
||||
),
|
||||
],
|
||||
};
|
||||
static SUPPORTED_SIGNATURE_SCHEMES: &[SignatureScheme] = &[
|
||||
SignatureScheme::RSA_PSS_SHA256,
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
];
|
||||
|
||||
// TLSv1.3
|
||||
pub static TLS13_CHACHA20POLY1305_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: u64::MAX,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA256),
|
||||
aead_alg: &cipher::chacha20poly1305::Chacha20Poly1305,
|
||||
quic: None,
|
||||
});
|
||||
pub static TLS13_AES128GCM_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_AES_128_GCM_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA256),
|
||||
aead_alg: &cipher::aes_gcm::AES128GCM,
|
||||
quic: None,
|
||||
});
|
||||
pub static TLS13_AES256GCM_SHA384: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_AES_256_GCM_SHA384,
|
||||
hash_provider: &hash::SHA384,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA384),
|
||||
aead_alg: &cipher::aes_gcm::AES256GCM,
|
||||
quic: None,
|
||||
});
|
||||
// TLSv1.2
|
||||
pub static TLS_ECDHE_RSA_WITH_CHACHA20POLY1305_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: u64::MAX,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA256),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::chacha20poly1305::Chacha20Poly1305,
|
||||
});
|
||||
pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA256),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::aes_gcm::AES128GCM,
|
||||
});
|
||||
pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
hash_provider: &hash::SHA384,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA384),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::aes_gcm::AES256GCM,
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
use rustls::{
|
||||
crypto::{tls12, tls13, KeyExchangeAlgorithm, SupportedKxGroup, WebPkiSupportedAlgorithms},
|
||||
CipherSuite, CipherSuiteCommon, SignatureScheme, SupportedCipherSuite, Tls12CipherSuite,
|
||||
Tls13CipherSuite,
|
||||
};
|
||||
|
||||
use crate::{cipher, hash, hmac, kx, verify};
|
||||
|
||||
pub(super) static CIPHER_SUITES: &[SupportedCipherSuite] = &[
|
||||
// TLSv1.3 suites
|
||||
TLS13_CHACHA20POLY1305_SHA256,
|
||||
TLS13_AES256GCM_SHA384,
|
||||
TLS13_AES128GCM_SHA256,
|
||||
// TLSv1.2 suites
|
||||
TLS_ECDHE_RSA_WITH_CHACHA20POLY1305_SHA256,
|
||||
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
];
|
||||
pub(super) static KX_GROUPS: &[&dyn SupportedKxGroup] = &[&kx::X25519];
|
||||
pub(super) static SIGNATURE_VERIFICATION_ALGORITHMS: WebPkiSupportedAlgorithms =
|
||||
WebPkiSupportedAlgorithms {
|
||||
all: &[
|
||||
verify::RSA_PSS_SHA256,
|
||||
verify::RSA_PKCS1_SHA256,
|
||||
verify::ECDSA_NISTP256_SHA256,
|
||||
verify::ECDSA_NISTP384_SHA384,
|
||||
],
|
||||
mapping: &[
|
||||
(SignatureScheme::RSA_PSS_SHA256, &[verify::RSA_PSS_SHA256]),
|
||||
(
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
&[verify::RSA_PKCS1_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
&[verify::ECDSA_NISTP256_SHA256],
|
||||
),
|
||||
(
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
&[verify::ECDSA_NISTP384_SHA384],
|
||||
),
|
||||
],
|
||||
};
|
||||
pub(super) static SUPPORTED_SIGNATURE_SCHEMES: &[SignatureScheme] = &[
|
||||
SignatureScheme::RSA_PSS_SHA256,
|
||||
SignatureScheme::RSA_PKCS1_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP256_SHA256,
|
||||
SignatureScheme::ECDSA_NISTP384_SHA384,
|
||||
];
|
||||
|
||||
// TLSv1.3
|
||||
pub static TLS13_CHACHA20POLY1305_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: u64::MAX,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA256),
|
||||
aead_alg: &cipher::TLS_CHACHA20POLY1305,
|
||||
quic: None,
|
||||
});
|
||||
pub static TLS13_AES128GCM_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_AES_128_GCM_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA256),
|
||||
aead_alg: &cipher::TLS_AES128GCM,
|
||||
quic: None,
|
||||
});
|
||||
pub static TLS13_AES256GCM_SHA384: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls13(&Tls13CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS13_AES_256_GCM_SHA384,
|
||||
hash_provider: &hash::SHA384,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
hkdf_provider: &tls13::HkdfUsingHmac(&hmac::HMAC_SHA384),
|
||||
aead_alg: &cipher::TLS_AES256GCM,
|
||||
quic: None,
|
||||
});
|
||||
// TLSv1.2
|
||||
pub static TLS_ECDHE_RSA_WITH_CHACHA20POLY1305_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: u64::MAX,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA256),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::TLS_CHACHA20POLY1305,
|
||||
});
|
||||
pub static TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
hash_provider: &hash::SHA256,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA256),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::TLS_AES128GCM,
|
||||
});
|
||||
pub static TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: SupportedCipherSuite =
|
||||
SupportedCipherSuite::Tls12(&Tls12CipherSuite {
|
||||
common: CipherSuiteCommon {
|
||||
suite: CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
hash_provider: &hash::SHA384,
|
||||
confidentiality_limit: 1 << 24,
|
||||
},
|
||||
prf_provider: &tls12::PrfUsingHmac(&hmac::HMAC_SHA384),
|
||||
kx: KeyExchangeAlgorithm::ECDHE,
|
||||
sign: SUPPORTED_SIGNATURE_SCHEMES,
|
||||
aead_alg: &cipher::TLS_AES256GCM,
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use rand::RngCore;
|
||||
use rustls::{
|
||||
crypto::{CryptoProvider, GetRandomFailed, KeyProvider, SecureRandom},
|
||||
pki_types::PrivateKeyDer,
|
||||
sign::SigningKey,
|
||||
};
|
||||
|
||||
pub(crate) use verifier::InsecureServerCertificateVerifier;
|
||||
|
||||
mod algorithms;
|
||||
mod verifier;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Provider;
|
||||
|
||||
pub fn provider() -> CryptoProvider {
|
||||
CryptoProvider {
|
||||
cipher_suites: algorithms::CIPHER_SUITES.to_vec(),
|
||||
kx_groups: algorithms::KX_GROUPS.to_vec(),
|
||||
signature_verification_algorithms: algorithms::SIGNATURE_VERIFICATION_ALGORITHMS,
|
||||
secure_random: &Provider,
|
||||
key_provider: &Provider,
|
||||
}
|
||||
}
|
||||
|
||||
impl SecureRandom for Provider {
|
||||
fn fill(&self, buf: &mut [u8]) -> Result<(), GetRandomFailed> {
|
||||
rand_core::OsRng
|
||||
.try_fill_bytes(buf)
|
||||
.map_err(|_| GetRandomFailed)
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyProvider for Provider {
|
||||
fn load_private_key(
|
||||
&self,
|
||||
key_der: PrivateKeyDer<'static>,
|
||||
) -> Result<Arc<dyn SigningKey>, rustls::Error> {
|
||||
let _ = key_der;
|
||||
todo!("TODO: implement signing key provider for TLS")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
use rustls::{
|
||||
client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier},
|
||||
pki_types::{CertificateDer, ServerName, UnixTime},
|
||||
DigitallySignedStruct, SignatureScheme,
|
||||
};
|
||||
|
||||
use crate::rustls::algorithms;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct InsecureServerCertificateVerifier;
|
||||
|
||||
impl ServerCertVerifier for InsecureServerCertificateVerifier {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
end_entity: &CertificateDer<'_>,
|
||||
intermediates: &[CertificateDer<'_>],
|
||||
server_name: &ServerName<'_>,
|
||||
ocsp_response: &[u8],
|
||||
now: UnixTime,
|
||||
) -> Result<ServerCertVerified, rustls::Error> {
|
||||
let _ = (end_entity, intermediates, server_name, ocsp_response, now);
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
let _ = (message, cert, dss);
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, rustls::Error> {
|
||||
let _ = (message, cert, dss);
|
||||
Ok(HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
algorithms::SUPPORTED_SIGNATURE_SCHEMES.to_vec()
|
||||
}
|
||||
|
||||
fn requires_raw_public_keys(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
use rustls::{
|
||||
crypto::cipher::{AeadKey, Iv},
|
||||
ConnectionTrafficSecrets,
|
||||
};
|
||||
|
||||
pub trait AeadDataInput {
|
||||
const ENCRYPTED_OVERHEAD: usize;
|
||||
}
|
||||
|
||||
pub trait IntoNonce<A: aead::AeadCore> {
|
||||
fn into_nonce(self, seq: u64) -> aead::Nonce<A>;
|
||||
}
|
||||
|
||||
pub trait TlsExtractKeys {
|
||||
fn tls13_wrap_keys(key: AeadKey, iv: Iv) -> ConnectionTrafficSecrets;
|
||||
fn tls12_wrap_keys(key: AeadKey, iv: &[u8], explicit: &[u8]) -> ConnectionTrafficSecrets;
|
||||
}
|
||||
Reference in New Issue
Block a user