HPKE DHKEM-P256 BoringSSL Rust

Change-Id: I39c8a586c85ef84d7483620bb300a7228c4050d5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/76087
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
main-with-bazel
Fernando Lobato Meeser 2 months ago committed by Boringssl LUCI CQ
parent 6b1c6f324d
commit 0147d7f283
  1. 70
      rust/bssl-crypto/src/hpke.rs

@ -78,8 +78,10 @@ use alloc::vec::Vec;
/// Supported KEM algorithms with values detailed in RFC 9180.
#[derive(Clone, Copy)]
pub enum Kem {
#[allow(missing_docs)]
X25519HkdfSha256 = 32,
/// KEM using DHKEM P-256 and HKDF-SHA256.
P256HkdfSha256 = 16, // 0x0010
/// KEM using DHKEM X25519 and HKDF-SHA256.
X25519HkdfSha256 = 32, // 0x0020
}
impl Kem {
@ -87,11 +89,21 @@ impl Kem {
// Safety: this function returns a pointer to static data.
unsafe {
match self {
Kem::P256HkdfSha256 => bssl_sys::EVP_hpke_p256_hkdf_sha256(),
Kem::X25519HkdfSha256 => bssl_sys::EVP_hpke_x25519_hkdf_sha256(),
}
}
}
fn from_rfc_id(n: u16) -> Option<Kem> {
match n {
n if n == Kem::P256HkdfSha256 as u16 => Some(Self::P256HkdfSha256),
n if n == Kem::X25519HkdfSha256 as u16 => Some(Self::X25519HkdfSha256),
_ => None,
}
}
/// Generate a public and private key for this KEM.
pub fn generate_keypair(&self) -> (Vec<u8>, Vec<u8>) {
let mut key = scoped::EvpHpkeKey::new();
@ -196,13 +208,12 @@ pub struct Params {
impl Params {
/// New `Params` from KEM, KDF, and AEAD enums.
pub fn new(_kem: Kem, _kdf: Kdf, aead: Aead) -> Self {
// Safety: EVP_hpke_x25519_hkdf_sha256 and EVP_hpke_hkdf_sha256 just
// return pointers to static data.
pub fn new(kem: Kem, _kdf: Kdf, aead: Aead) -> Self {
// Safety: EVP_hpke_hkdf_sha256 just returns pointer to static data.
unsafe {
Self {
// Only one KEM and KDF are supported thus far.
kem: bssl_sys::EVP_hpke_x25519_hkdf_sha256(),
kem: kem.as_ffi_ptr(),
// Only one KDF is supported thus far.
kdf: bssl_sys::EVP_hpke_hkdf_sha256(),
aead: aead.as_ffi_ptr(),
}
@ -211,11 +222,11 @@ impl Params {
/// New `Params` from KEM, KDF, and AEAD IDs as detailed in RFC 9180.
pub fn new_from_rfc_ids(kem_id: u16, kdf_id: u16, aead_id: u16) -> Option<Self> {
let kem = Kem::X25519HkdfSha256;
let kem = Kem::from_rfc_id(kem_id)?;
let kdf = Kdf::HkdfSha256;
let aead = Aead::from_rfc_id(aead_id)?;
if kem_id != kem as u16 || kdf_id != kdf as u16 {
if kdf_id != kdf as u16 {
return None;
}
Some(Self::new(kem, kdf, aead))
@ -439,7 +450,7 @@ impl RecipientContext {
#[cfg(test)]
mod test {
use super::*;
use crate::test_helpers::decode_hex;
use crate::test_helpers::{decode_hex, decode_hex_into_vec};
struct TestVector {
kem_id: u16,
@ -447,9 +458,9 @@ mod test {
aead_id: u16,
info: [u8; 20],
seed_for_testing: [u8; 32], // skEm
recipient_pub_key: [u8; 32], // pkRm
recipient_pub_key: Vec<u8>, // pkRm
recipient_priv_key: [u8; 32], // skRm
encapsulated_key: [u8; 32], // enc
encapsulated_key: Vec<u8>, // enc
plaintext: [u8; 29], // pt
associated_data: [u8; 7], // aad
ciphertext: [u8; 45], // ct
@ -465,9 +476,9 @@ mod test {
aead_id: 1,
info: decode_hex("4f6465206f6e2061204772656369616e2055726e"),
seed_for_testing: decode_hex("52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736"),
recipient_pub_key: decode_hex("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d"),
recipient_pub_key: decode_hex_into_vec("3948cfe0ad1ddb695d780e59077195da6c56506b027329794ab02bca80815c4d"),
recipient_priv_key: decode_hex("4612c550263fc8ad58375df3f557aac531d26850903e55a9f23f21d8534e8ac8"),
encapsulated_key: decode_hex("37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431"),
encapsulated_key: decode_hex_into_vec("37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431"),
plaintext: decode_hex("4265617574792069732074727574682c20747275746820626561757479"),
associated_data: decode_hex("436f756e742d30"),
ciphertext: decode_hex("f938558b5d72f1a23810b4be2ab4f84331acc02fc97babc53a52ae8218a355a96d8770ac83d07bea87e13c512a"),
@ -484,9 +495,9 @@ mod test {
aead_id: 3,
info: decode_hex("4f6465206f6e2061204772656369616e2055726e"),
seed_for_testing: decode_hex("f4ec9b33b792c372c1d2c2063507b684ef925b8c75a42dbcbf57d63ccd381600"),
recipient_pub_key: decode_hex("4310ee97d88cc1f088a5576c77ab0cf5c3ac797f3d95139c6c84b5429c59662a"),
recipient_pub_key: decode_hex_into_vec("4310ee97d88cc1f088a5576c77ab0cf5c3ac797f3d95139c6c84b5429c59662a"),
recipient_priv_key: decode_hex("8057991eef8f1f1af18f4a9491d16a1ce333f695d4db8e38da75975c4478e0fb"),
encapsulated_key: decode_hex("1afa08d3dec047a643885163f1180476fa7ddb54c6a8029ea33f95796bf2ac4a"),
encapsulated_key: decode_hex_into_vec("1afa08d3dec047a643885163f1180476fa7ddb54c6a8029ea33f95796bf2ac4a"),
plaintext: decode_hex("4265617574792069732074727574682c20747275746820626561757479"),
associated_data: decode_hex("436f756e742d30"),
ciphertext: decode_hex("1c5250d8034ec2b784ba2cfd69dbdb8af406cfe3ff938e131f0def8c8b60b4db21993c62ce81883d2dd1b51a28"),
@ -495,9 +506,28 @@ mod test {
}
}
// https://www.rfc-editor.org/rfc/rfc9180.html#appendix-A.3
fn p256_hkdf_sha256_hkdf_sha256_aes_128_gcm() -> TestVector {
TestVector {
kem_id: 16,
kdf_id: 1,
aead_id: 1,
info: decode_hex("4f6465206f6e2061204772656369616e2055726e"),
seed_for_testing: decode_hex("4270e54ffd08d79d5928020af4686d8f6b7d35dbe470265f1f5aa22816ce860e"),
recipient_pub_key: decode_hex_into_vec("04fe8c19ce0905191ebc298a9245792531f26f0cece2460639e8bc39cb7f706a826a779b4cf969b8a0e539c7f62fb3d30ad6aa8f80e30f1d128aafd68a2ce72ea0"),
recipient_priv_key: decode_hex("f3ce7fdae57e1a310d87f1ebbde6f328be0a99cdbcadf4d6589cf29de4b8ffd2"),
encapsulated_key: decode_hex_into_vec("04a92719c6195d5085104f469a8b9814d5838ff72b60501e2c4466e5e67b325ac98536d7b61a1af4b78e5b7f951c0900be863c403ce65c9bfcb9382657222d18c4"),
plaintext: decode_hex("4265617574792069732074727574682c20747275746820626561757479"),
associated_data: decode_hex("436f756e742d30"),
ciphertext: decode_hex("5ad590bb8baa577f8619db35a36311226a896e7342a6d836d8b7bcd2f20b6c7f9076ac232e3ab2523f39513434"),
exporter_context: decode_hex("54657374436f6e74657874"),
exported_value: decode_hex("d8f1ea7942adbba7412c6d431c62d01371ea476b823eb697e1f6e6cae1dab85a"),
}
}
#[test]
fn all_algorithms() {
let kems = vec![Kem::X25519HkdfSha256];
let kems = vec![Kem::X25519HkdfSha256, Kem::P256HkdfSha256];
let kdfs = vec![Kdf::HkdfSha256];
let aeads = vec![Aead::Aes128Gcm, Aead::Aes256Gcm, Aead::Chacha20Poly1305];
let plaintext: &[u8] = b"plaintext";
@ -579,6 +609,7 @@ mod test {
for test in vec![
x25519_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
x25519_hkdf_sha256_hkdf_sha256_chacha20_poly1305(),
p256_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
] {
let params = Params::new_from_rfc_ids(test.kem_id, test.kdf_id, test.aead_id).unwrap();
@ -601,6 +632,7 @@ mod test {
for test in vec![
x25519_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
x25519_hkdf_sha256_hkdf_sha256_chacha20_poly1305(),
p256_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
] {
let params = Params::new_from_rfc_ids(test.kem_id, test.kdf_id, test.aead_id).unwrap();
@ -622,6 +654,7 @@ mod test {
for test in vec![
x25519_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
x25519_hkdf_sha256_hkdf_sha256_chacha20_poly1305(),
p256_hkdf_sha256_hkdf_sha256_aes_128_gcm(),
] {
let params = Params::new_from_rfc_ids(test.kem_id, test.kdf_id, test.aead_id).unwrap();
@ -641,7 +674,8 @@ mod test {
&test.recipient_priv_key,
&test.encapsulated_key,
&test.info,
).unwrap();
)
.unwrap();
assert_eq!(
test.exported_value.as_ref(),
recipient_ctx.export(&test.exporter_context, test.exported_value.len())

Loading…
Cancel
Save