1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use crate::{cipher_suite::TLS_AES_128_GCM_SHA256 as CipherSuite, header_key::HeaderKey};
use s2n_quic_core::crypto::{self, packet_protection, scatter, HeaderProtectionMask, Key};

#[derive(Debug)]
pub struct ZeroRttKey(CipherSuite);

impl ZeroRttKey {
    /// Create a ZeroRTT cipher suite with a given secret
    pub fn new(secret: crate::Prk) -> (Self, ZeroRttHeaderKey) {
        let (key, header_key) = CipherSuite::new(secret);
        let key = Self(key);
        let header_key = ZeroRttHeaderKey(header_key);
        (key, header_key)
    }
}

impl crypto::ZeroRttKey for ZeroRttKey {}

impl Key for ZeroRttKey {
    fn decrypt(
        &self,
        packet_number: u64,
        header: &[u8],
        payload: &mut [u8],
    ) -> Result<(), packet_protection::Error> {
        self.0.decrypt(packet_number, header, payload)
    }

    fn encrypt(
        &self,
        packet_number: u64,
        header: &[u8],
        payload: &mut scatter::Buffer,
    ) -> Result<(), packet_protection::Error> {
        self.0.encrypt(packet_number, header, payload)
    }

    fn tag_len(&self) -> usize {
        self.0.tag_len()
    }

    fn aead_confidentiality_limit(&self) -> u64 {
        self.0.aead_confidentiality_limit()
    }

    fn aead_integrity_limit(&self) -> u64 {
        self.0.aead_integrity_limit()
    }

    #[inline]
    fn cipher_suite(&self) -> s2n_quic_core::crypto::tls::CipherSuite {
        self.0.cipher_suite()
    }
}

#[derive(Debug)]
pub struct ZeroRttHeaderKey(HeaderKey);

impl crypto::HeaderKey for ZeroRttHeaderKey {
    fn opening_header_protection_mask(&self, sample: &[u8]) -> HeaderProtectionMask {
        self.0.opening_header_protection_mask(sample)
    }

    fn opening_sample_len(&self) -> usize {
        self.0.opening_sample_len()
    }

    fn sealing_header_protection_mask(&self, sample: &[u8]) -> HeaderProtectionMask {
        self.0.sealing_header_protection_mask(sample)
    }

    fn sealing_sample_len(&self) -> usize {
        self.0.sealing_sample_len()
    }
}

impl crypto::ZeroRttHeaderKey for ZeroRttHeaderKey {}