openmls/ciphersuite/
kdf_label.rs

1use tls_codec::Serialize;
2
3use super::*;
4
5/// `KdfLabel` is later serialized and used in the `label` field of
6/// `kdf_expand_label`.
7///
8/// ```c
9/// // draft-ietf-mls-protocol-16
10/// struct {
11///     uint16 length = Length;
12///     opaque label<V> = "MLS 1.0 " + Label;
13///     opaque context<V> = Context;
14/// } KDFLabel;
15/// ```
16#[derive(Debug, TlsSerialize, TlsSize)]
17pub(in crate::ciphersuite) struct KdfLabel {
18    length: u16,
19    label: VLBytes,
20    context: VLBytes,
21}
22
23impl KdfLabel {
24    /// Serialize this label.
25    /// Returns the serialized label as byte vector or returns a [`CryptoError`]
26    /// if the parameters are invalid.
27    pub(in crate::ciphersuite) fn serialized_label(
28        context: &[u8],
29        label: String,
30        length: usize,
31    ) -> Result<Vec<u8>, CryptoError> {
32        if length > u16::MAX as usize {
33            debug_assert!(
34                false,
35                "Library error: Trying to derive a key with a too large length field!"
36            );
37            return Err(CryptoError::KdfLabelTooLarge);
38        }
39        let kdf_label = KdfLabel {
40            length: length as u16,
41            label: label.as_bytes().into(),
42            context: context.into(),
43        };
44        log::trace!("{kdf_label:?}");
45        kdf_label
46            .tls_serialize_detached()
47            .map_err(|_| CryptoError::KdfSerializationError)
48    }
49}