s2n_quic_core/crypto/
label.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use hex_literal::hex;
5
6//= https://www.rfc-editor.org/rfc/rfc9001#appendix-A.1
7//# The labels generated during the execution of the HKDF-Expand-Label
8//# function (that is, HkdfLabel.label) and part of the value given to
9//# the HKDF-Expand function in order to produce its output are:
10//#
11//# client in:  00200f746c73313320636c69656e7420696e00
12
13pub const CLIENT_IN: [u8; 19] = hex!("00200f746c73313320636c69656e7420696e00");
14
15//= https://www.rfc-editor.org/rfc/rfc9001#appendix-A.1
16//# server in:  00200f746c7331332073657276657220696e00
17
18pub const SERVER_IN: [u8; 19] = hex!("00200f746c7331332073657276657220696e00");
19
20//= https://www.rfc-editor.org/rfc/rfc9001#appendix-A.1
21//# quic key:  00100e746c7331332071756963206b657900
22
23pub const QUIC_KEY_16: [u8; 18] = hex!("00100e746c7331332071756963206b657900");
24
25//= https://www.rfc-editor.org/rfc/rfc9001#appendix-A.1
26//# quic iv:  000c0d746c733133207175696320697600
27
28pub const QUIC_IV_12: [u8; 17] = hex!("000c0d746c733133207175696320697600");
29
30//= https://www.rfc-editor.org/rfc/rfc9001#appendix-A.1
31//# quic hp:  00100d746c733133207175696320687000
32
33pub const QUIC_HP_16: [u8; 17] = hex!("00100d746c733133207175696320687000");
34
35//= https://www.rfc-editor.org/rfc/rfc9001#section-6.1
36//# Endpoints maintain separate read and write secrets for packet
37//# protection.  An endpoint initiates a key update by updating its
38//# packet protection write secret and using that to protect new packets.
39//#
40//# The endpoint creates a new write secret from the existing write
41//# secret as performed in Section 7.2 of [TLS13].  This uses the KDF
42//# function provided by TLS with a label of "quic ku".  The
43//# corresponding key and IV are created from that secret as defined in
44//# Section 5.1.  The header protection key is not updated.
45
46pub const QUIC_KU_16: [u8; 17] = hex!("00100d746c7331332071756963206b7500");
47
48// 32-byte labels
49
50pub const QUIC_KEY_32: [u8; 18] = hex!("00200e746c7331332071756963206b657900");
51pub const QUIC_HP_32: [u8; 17] = hex!("00200d746c733133207175696320687000");
52pub const QUIC_KU_32: [u8; 17] = hex!("00200d746c7331332071756963206b7500");
53
54// 48-byte labels
55pub const QUIC_KU_48: [u8; 17] = hex!("00300d746c7331332071756963206b7500");
56
57/// Computes the label given the key len
58pub fn compute_label<T: Extend<u8>>(len: usize, label: &[u8], out: &mut T) {
59    const TLS_LABEL: &[u8] = b"tls13 ";
60    let label_len = TLS_LABEL.len() + label.len();
61    debug_assert!(label_len <= u8::MAX as usize, "label is too long");
62
63    out.extend((len as u16).to_be_bytes().iter().cloned());
64    out.extend(Some(label_len as u8));
65    out.extend(TLS_LABEL.iter().cloned());
66    out.extend(label.iter().cloned());
67    out.extend(Some(0));
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn initial_test() {
76        assert_eq!(compute_vec_label(32, b"client in"), CLIENT_IN);
77        assert_eq!(compute_vec_label(32, b"server in"), SERVER_IN);
78    }
79
80    #[test]
81    fn len_16_test() {
82        assert_eq!(compute_vec_label(16, b"quic key"), QUIC_KEY_16);
83        assert_eq!(compute_vec_label(12, b"quic iv"), QUIC_IV_12);
84        assert_eq!(compute_vec_label(16, b"quic hp"), QUIC_HP_16);
85        assert_eq!(compute_vec_label(16, b"quic ku"), QUIC_KU_16);
86    }
87
88    #[test]
89    fn len_32_test() {
90        assert_eq!(compute_vec_label(32, b"quic key"), QUIC_KEY_32);
91        assert_eq!(compute_vec_label(32, b"quic hp"), QUIC_HP_32);
92        assert_eq!(compute_vec_label(32, b"quic ku"), QUIC_KU_32);
93    }
94
95    #[test]
96    fn len_48_test() {
97        assert_eq!(compute_vec_label(48, b"quic ku"), QUIC_KU_48);
98    }
99
100    fn compute_vec_label(len: usize, label: &[u8]) -> Vec<u8> {
101        let mut out = vec![];
102        compute_label(len, label, &mut out);
103        out
104    }
105}