1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 #[cfg(feature = "mock")]
6 use mockall::automock;
7 
8 use alloc::vec::Vec;
9 use mls_rs_core::{crypto::CipherSuite, error::IntoAnyError};
10 
11 /// A trait that provides the required KDF functions
12 #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
13 #[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
14 #[cfg_attr(
15     all(not(target_arch = "wasm32"), mls_build_async),
16     maybe_async::must_be_async
17 )]
18 #[cfg_attr(feature = "mock", automock(type Error = crate::mock::TestError;))]
19 pub trait KdfType: Send + Sync {
20     type Error: IntoAnyError + Send + Sync;
21 
22     /// KDF Id, as specified in RFC 9180, Section 5.1 and Table 3.
kdf_id(&self) -> u1623     fn kdf_id(&self) -> u16;
24 
expand(&self, prk: &[u8], info: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>25     async fn expand(&self, prk: &[u8], info: &[u8], len: usize) -> Result<Vec<u8>, Self::Error>;
extract(&self, salt: &[u8], ikm: &[u8]) -> Result<Vec<u8>, Self::Error>26     async fn extract(&self, salt: &[u8], ikm: &[u8]) -> Result<Vec<u8>, Self::Error>;
extract_size(&self) -> usize27     fn extract_size(&self) -> usize;
28 }
29 
30 /// Aead KDF as specified in RFC 9180, Table 3.
31 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
32 #[repr(u16)]
33 #[non_exhaustive]
34 pub enum KdfId {
35     HkdfSha256 = 0x0001,
36     HkdfSha384 = 0x0002,
37     HkdfSha512 = 0x0003,
38 }
39 
40 impl KdfId {
new(cipher_suite: CipherSuite) -> Option<Self>41     pub fn new(cipher_suite: CipherSuite) -> Option<Self> {
42         match cipher_suite {
43             CipherSuite::CURVE25519_AES128
44             | CipherSuite::P256_AES128
45             | CipherSuite::CURVE25519_CHACHA => Some(KdfId::HkdfSha256),
46             CipherSuite::P384_AES256 => Some(KdfId::HkdfSha384),
47             CipherSuite::CURVE448_CHACHA
48             | CipherSuite::CURVE448_AES256
49             | CipherSuite::P521_AES256 => Some(KdfId::HkdfSha512),
50             _ => None,
51         }
52     }
53 
extract_size(&self) -> usize54     pub fn extract_size(&self) -> usize {
55         match self {
56             KdfId::HkdfSha256 => 32,
57             KdfId::HkdfSha384 => 48,
58             KdfId::HkdfSha512 => 64,
59         }
60     }
61 }
62