Skip to content

Commit

Permalink
refactor Hash and Hpke
Browse files Browse the repository at this point in the history
  • Loading branch information
rainliu committed Sep 3, 2023
1 parent 77e1f2a commit f81e5bf
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 114 deletions.
2 changes: 1 addition & 1 deletion rmls/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ homepage = "https://rmls.io"
repository = "https://github.com/webrtc-rs/rmls"

[features]
default = ["RustCryptoProvider"] #"RingCryptoProvider"
default = ["RustCryptoProvider"]#, "RingCryptoProvider"]
RingCryptoProvider = ["ring", "signature", "ecdsa", "p256", "p384"] #TODO: use "ring" only for RingCryptoProvider
RustCryptoProvider = ["sha2", "hmac", "hkdf", "ed25519-dalek", "ecdsa", "sec1", "signature", "aead", "aes-gcm", "chacha20poly1305", "p256", "p384"]

Expand Down
24 changes: 21 additions & 3 deletions rmls/src/crypto/provider/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ mod rust;
#[cfg(feature = "RustCryptoProvider")]
pub use self::rust::RustCryptoProvider;

use crate::crypto::cipher_suite::CipherSuite;
use crate::utilities::error::*;
use crate::utilities::serde::*;
use crate::crypto::{cipher_suite::CipherSuite, *};

use bytes::{BufMut, Bytes, BytesMut};
use hpke::{Deserializable, Serializable};
Expand All @@ -21,6 +19,25 @@ use rand_core::SeedableRng;
/// [RFC9420 Sec.5.1.2](https://www.rfc-editor.org/rfc/rfc9420.html#section-5.1.2) MLS prefix string - "MLS 1.0 "
const MLS_PREFIX: &str = "MLS 1.0 ";

/// [RFC9420 Sec.17.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-17.1) HashScheme
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub enum HashScheme {
#[default]
SHA256,
SHA384,
SHA512,
}

/// [RFC9420 Sec.17.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-17.1) HpkeSuite
///
/// It is an HPKE cipher suite consisting of a KEM, KDF, and AEAD algorithm.
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub struct HpkeSuite {
pub(super) kem: Kem,
pub(super) kdf: Kdf,
pub(super) aead: Aead,
}

/// [RFC9420 Sec.17.1](https://www.rfc-editor.org/rfc/rfc9420.html#section-17.1) SignatureScheme
#[allow(non_camel_case_types)]
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
Expand All @@ -39,6 +56,7 @@ pub enum SignatureScheme {
ED448 = 0x0808,
}

/// Rand trait provides randomness
pub trait Rand: Send + Sync {
fn fill(&self, buf: &mut [u8]) -> Result<()>;
}
Expand Down
50 changes: 25 additions & 25 deletions rmls/src/crypto/provider/ring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,88 +3,88 @@ mod hpke;
mod rand;
mod signature;

use self::hash::HashScheme;
use self::hpke::HpkeSuite;
use self::hash::HashSchemeWrapper;
use self::hpke::HpkeSuiteWrapper;
use self::rand::RandChacha;
use self::signature::SignatureSchemeWrapper;
use super::*;
use crate::crypto::*;

struct CipherSuiteDescription {
hash: HashScheme,
hpke: HpkeSuite,
hash: HashSchemeWrapper,
hpke: HpkeSuiteWrapper,
signature: SignatureSchemeWrapper,
}

static CIPHER_SUITE_DESCRIPTIONS: [CipherSuiteDescription; 7 /*CipherSuite::MLS_256_DHKEMP384_AES256GCM_SHA384_P384*/] = [
//1: CipherSuite::MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519,
CipherSuiteDescription {
hash: HashScheme::SHA256,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA256),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_X25519_HKDF_SHA256,
kdf: Kdf::KDF_HKDF_SHA256,
aead: Aead::AEAD_AES128GCM,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ED25519),
},
//2: CipherSuite::MLS_128_DHKEMP256_AES128GCM_SHA256_P256,
CipherSuiteDescription {
hash: HashScheme::SHA256,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA256),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_P256_HKDF_SHA256,
kdf: Kdf::KDF_HKDF_SHA256,
aead: Aead::AEAD_AES128GCM,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ECDSA_SECP256R1_SHA256),
},
//3: CipherSuite::MLS_128_DHKEMX25519_CHACHA20POLY1305_SHA256_Ed25519,
CipherSuiteDescription {
hash: HashScheme::SHA256,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA256),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_X25519_HKDF_SHA256,
kdf: Kdf::KDF_HKDF_SHA256,
aead: Aead::AEAD_ChaCha20Poly1305,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ED25519),
},
//4: CipherSuite::MLS_256_DHKEMX448_AES256GCM_SHA512_Ed448,
CipherSuiteDescription {
hash: HashScheme::SHA512,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA512),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_X448_HKDF_SHA512,
kdf: Kdf::KDF_HKDF_SHA512,
aead: Aead::AEAD_AES256GCM,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ED448),
},
//5: CipherSuite::MLS_256_DHKEMP521_AES256GCM_SHA512_P521,
CipherSuiteDescription {
hash: HashScheme::SHA512,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA512),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_P521_HKDF_SHA512,
kdf: Kdf::KDF_HKDF_SHA512,
aead: Aead::AEAD_AES256GCM,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ECDSA_SECP521R1_SHA512),
},
//6: CipherSuite::MLS_256_DHKEMX448_CHACHA20POLY1305_SHA512_Ed448,
CipherSuiteDescription {
hash: HashScheme::SHA512,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA512),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_X448_HKDF_SHA512,
kdf: Kdf::KDF_HKDF_SHA512,
aead: Aead::AEAD_ChaCha20Poly1305,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ED448),
},
//7: CipherSuite::MLS_256_DHKEMP384_AES256GCM_SHA384_P384,
CipherSuiteDescription {
hash: HashScheme::SHA384,
hpke: HpkeSuite {
hash: HashSchemeWrapper(HashScheme::SHA384),
hpke: HpkeSuiteWrapper(HpkeSuite {
kem: Kem::KEM_P384_HKDF_SHA384,
kdf: Kdf::KDF_HKDF_SHA384,
aead: Aead::AEAD_AES256GCM,
},
}),
signature: SignatureSchemeWrapper(SignatureScheme::ECDSA_SECP384R1_SHA384),
},
];
Expand Down
15 changes: 6 additions & 9 deletions rmls/src/crypto/provider/ring/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,14 @@ use ring::{
hmac,
};

use crate::crypto::provider::HashScheme;

#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub(super) enum HashScheme {
#[default]
SHA256,
SHA384,
SHA512,
}
pub(super) struct HashSchemeWrapper(pub(super) HashScheme);

impl crate::crypto::provider::Hash for HashScheme {
impl crate::crypto::provider::Hash for HashSchemeWrapper {
fn digest(&self, data: &[u8]) -> Bytes {
let d = match *self {
let d = match self.0 {
HashScheme::SHA256 => digest(&SHA256, data),
HashScheme::SHA384 => digest(&SHA384, data),
HashScheme::SHA512 => digest(&SHA512, data),
Expand All @@ -23,7 +20,7 @@ impl crate::crypto::provider::Hash for HashScheme {
}

fn mac(&self, key: &[u8], message: &[u8]) -> Bytes {
let hmac_key = match *self {
let hmac_key = match self.0 {
HashScheme::SHA256 => hmac::Key::new(hmac::HMAC_SHA256, key),
HashScheme::SHA384 => hmac::Key::new(hmac::HMAC_SHA384, key),
HashScheme::SHA512 => hmac::Key::new(hmac::HMAC_SHA512, key),
Expand Down
30 changes: 10 additions & 20 deletions rmls/src/crypto/provider/ring/hpke.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,11 @@ use ring::digest::{SHA256_OUTPUT_LEN, SHA384_OUTPUT_LEN, SHA512_OUTPUT_LEN};
use ring::hkdf::{KeyType, Prk, HKDF_SHA256, HKDF_SHA384, HKDF_SHA512};
use ring::hmac;

use crate::crypto::provider::HpkeSuite;
use crate::crypto::*;

// Suite is an HPKE cipher suite consisting of a KEM, KDF, and AEAD algorithm.
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
pub(super) struct HpkeSuite {
pub(super) kem: Kem,
pub(super) kdf: Kdf,
pub(super) aead: Aead,
}

impl HpkeSuite {
pub(super) fn new(kem: Kem, kdf: Kdf, aead: Aead) -> Self {
HpkeSuite { kem, kdf, aead }
}
}
pub(super) struct HpkeSuiteWrapper(pub(super) HpkeSuite);

/// Generic newtype wrapper that lets us implement traits for externally-defined
/// types.
Expand All @@ -31,9 +21,9 @@ impl KeyType for MyKeyType<u16> {
}
}

impl provider::Hpke for HpkeSuite {
impl provider::Hpke for HpkeSuiteWrapper {
fn kdf_expand(&self, secret: &[u8], info: &[u8], length: u16) -> Result<Bytes> {
let prk = match self.kdf {
let prk = match self.0.kdf {
Kdf::KDF_HKDF_SHA256 => Prk::new_less_safe(HKDF_SHA256, secret),
Kdf::KDF_HKDF_SHA384 => Prk::new_less_safe(HKDF_SHA384, secret),
Kdf::KDF_HKDF_SHA512 => Prk::new_less_safe(HKDF_SHA512, secret),
Expand All @@ -52,7 +42,7 @@ impl provider::Hpke for HpkeSuite {
}

fn kdf_extract(&self, secret: &[u8], salt: &[u8]) -> Result<Bytes> {
let salt = match self.kdf {
let salt = match self.0.kdf {
Kdf::KDF_HKDF_SHA256 => hmac::Key::new(hmac::HMAC_SHA256, salt),
Kdf::KDF_HKDF_SHA384 => hmac::Key::new(hmac::HMAC_SHA384, salt),
Kdf::KDF_HKDF_SHA512 => hmac::Key::new(hmac::HMAC_SHA512, salt),
Expand All @@ -61,7 +51,7 @@ impl provider::Hpke for HpkeSuite {
}

fn kdf_extract_size(&self) -> usize {
match self.kdf {
match self.0.kdf {
Kdf::KDF_HKDF_SHA256 => SHA256_OUTPUT_LEN,
Kdf::KDF_HKDF_SHA384 => SHA384_OUTPUT_LEN,
Kdf::KDF_HKDF_SHA512 => SHA512_OUTPUT_LEN,
Expand All @@ -70,7 +60,7 @@ impl provider::Hpke for HpkeSuite {

// key_size returns the size in bytes of the keys used by the AEAD cipher.
fn aead_key_size(&self) -> usize {
match self.aead {
match self.0.aead {
Aead::AEAD_AES128GCM => 16,
Aead::AEAD_AES256GCM => 32,
Aead::AEAD_ChaCha20Poly1305 => 32,
Expand All @@ -79,7 +69,7 @@ impl provider::Hpke for HpkeSuite {

// nonce_size returns the size in bytes of the nonce used by the AEAD cipher.
fn aead_nonce_size(&self) -> usize {
match self.aead {
match self.0.aead {
Aead::AEAD_AES128GCM | Aead::AEAD_AES256GCM | Aead::AEAD_ChaCha20Poly1305 => 12,
}
}
Expand All @@ -91,7 +81,7 @@ impl provider::Hpke for HpkeSuite {
ciphertext: &[u8],
additional_data: &[u8],
) -> Result<Bytes> {
let key = match self.aead {
let key = match self.0.aead {
Aead::AEAD_AES128GCM => {
let key = aead::UnboundKey::new(&AES_128_GCM, key)
.map_err(|err| Error::RingCryptoError(err.to_string()))?;
Expand Down Expand Up @@ -127,7 +117,7 @@ impl provider::Hpke for HpkeSuite {
plaintext: &[u8],
additional_data: &[u8],
) -> Result<Bytes> {
let key = match self.aead {
let key = match self.0.aead {
Aead::AEAD_AES128GCM => {
let key = aead::UnboundKey::new(&AES_128_GCM, key)
.map_err(|err| Error::RingCryptoError(err.to_string()))?;
Expand Down
Loading

0 comments on commit f81e5bf

Please sign in to comment.