// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright by contributors to this project. // SPDX-License-Identifier: (Apache-2.0 OR MIT) use mls_rs_crypto_traits::KdfType; use alloc::vec::Vec; use core::fmt::{self, Debug}; #[derive(Clone, Eq, PartialEq)] pub(crate) struct HpkeKdf { suite_id: Vec, kdf: K, } impl Debug for HpkeKdf { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("HpkeKdf") .field( "suite_id", &mls_rs_core::debug::pretty_bytes(&self.suite_id), ) .field("kdf", &self.kdf) .finish() } } impl HpkeKdf { pub fn new(suite_id: Vec, kdf: K) -> Self { Self { suite_id, kdf } } pub fn extract_size(&self) -> usize { self.kdf.extract_size() } /* draft-irtf-cfrg-hpke-09 section 4 Cryptographic Dependencies */ #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] pub async fn labeled_extract( &self, salt: &[u8], label: &[u8], ikm: &[u8], ) -> Result, ::Error> { self.kdf .extract( salt, &[b"HPKE-v1" as &[u8], &self.suite_id, label, ikm].concat(), ) .await } /* draft-irtf-cfrg-hpke-09 section 4 Cryptographic Dependencies */ #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] pub async fn labeled_expand( &self, key: &[u8], label: &[u8], info: &[u8], len: usize, ) -> Result, ::Error> { let labeled_info = [ &(len as u16).to_be_bytes() as &[u8], b"HPKE-v1", &self.suite_id, label, info, ] .concat(); self.kdf.expand(key, &labeled_info, len).await } /* draft-irtf-cfrg-hpke-09 section 4.1 DH-Based KEM */ #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] pub async fn labeled_extract_then_expand( &self, ikm: &[u8], ctx: &[u8], len: usize, ) -> Result, ::Error> { let eae_prk = self.labeled_extract(&[], b"eae_prk", ikm).await?; self.labeled_expand(&eae_prk, b"shared_secret", ctx, len) .await } }