/// Key schedule maintenance for TLS1.3

use ring::{aead, hkdf::{self, KeyType as _}, hmac, digest};
use crate::error::TLSError;
use crate::cipher::{Iv, IvLen};
use crate::msgs::base::PayloadU8;
use crate::KeyLog;

/// The kinds of secret we can extract from `KeySchedule`.
#[derive(Debug, Clone, Copy, PartialEq)]
enum SecretKind {
    ResumptionPSKBinderKey,
    ClientEarlyTrafficSecret,
    ClientHandshakeTrafficSecret,
    ServerHandshakeTrafficSecret,
    ClientApplicationTrafficSecret,
    ServerApplicationTrafficSecret,
    ExporterMasterSecret,
    ResumptionMasterSecret,
    DerivedSecret,
}

impl SecretKind {
    fn to_bytes(self) -> &'static [u8] {
        match self {
            SecretKind::ResumptionPSKBinderKey => b"res binder",
            SecretKind::ClientEarlyTrafficSecret => b"c e traffic",
            SecretKind::ClientHandshakeTrafficSecret => b"c hs traffic",
            SecretKind::ServerHandshakeTrafficSecret => b"s hs traffic",
            SecretKind::ClientApplicationTrafficSecret => b"c ap traffic",
            SecretKind::ServerApplicationTrafficSecret => b"s ap traffic",
            SecretKind::ExporterMasterSecret => b"exp master",
            SecretKind::ResumptionMasterSecret => b"res master",
            SecretKind::DerivedSecret => b"derived",
        }
    }

    fn log_label(self) -> Option<&'static str> {
        use self::SecretKind::*;
        Some(match self {
            ClientEarlyTrafficSecret => "CLIENT_EARLY_TRAFFIC_SECRET",
            ClientHandshakeTrafficSecret => "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
            ServerHandshakeTrafficSecret => "SERVER_HANDSHAKE_TRAFFIC_SECRET",
            ClientApplicationTrafficSecret => "CLIENT_TRAFFIC_SECRET_0",
            ServerApplicationTrafficSecret => "SERVER_TRAFFIC_SECRET_0",
            ExporterMasterSecret => "EXPORTER_SECRET",
            _ => { return None; }
        })
    }
}

/// This is the TLS1.3 key schedule.  It stores the current secret and
/// the type of hash.  This isn't used directly; but only through the
/// typestates.
struct KeySchedule {
    current: hkdf::Prk,
    algorithm: ring::hkdf::Algorithm,
}

// We express the state of a contained KeySchedule using these
// typestates.  This means we can write code that cannot accidentally
// (eg) encrypt application data using a KeySchedule solely constructed
// with an empty or trivial secret, or extract the wrong kind of secrets
// at a given point.

/// KeySchedule for early data stage.
pub struct KeyScheduleEarly {
    ks: KeySchedule,
}

impl KeyScheduleEarly {
    pub fn new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeyScheduleEarly {
        KeyScheduleEarly { ks: KeySchedule::new(algorithm, secret) }
    }

    pub fn client_early_traffic_secret(&self,
                                       hs_hash: &[u8],
                                       key_log: &dyn KeyLog,
                                       client_random: &[u8; 32]) -> hkdf::Prk {
        self.ks.derive_logged_secret(SecretKind::ClientEarlyTrafficSecret,
                                     hs_hash, key_log, client_random)
    }

    pub fn resumption_psk_binder_key_and_sign_verify_data(&self, hs_hash: &[u8]) -> Vec<u8> {
        let resumption_psk_binder_key = self.ks.derive_for_empty_hash(SecretKind::ResumptionPSKBinderKey);
        self.ks.sign_verify_data(&resumption_psk_binder_key, hs_hash)
    }

    pub fn into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake {
        self.ks.input_secret(secret);
        KeyScheduleHandshake {
            ks: self.ks,
            current_client_traffic_secret: None,
            current_server_traffic_secret: None,
        }
    }
}

/// KeySchedule for skipping early data stage.  No secrets can be extracted
/// (since there are none), but the handshake secret can be input.
pub struct KeyScheduleNonSecret {
    ks: KeySchedule,
}

impl KeyScheduleNonSecret {
    pub fn new(algorithm: hkdf::Algorithm) -> KeyScheduleNonSecret {
        KeyScheduleNonSecret { ks: KeySchedule::new_with_empty_secret(algorithm) }
    }

    pub fn into_handshake(mut self, secret: &[u8]) -> KeyScheduleHandshake {
        self.ks.input_secret(secret);
        KeyScheduleHandshake {
            ks: self.ks,
            current_client_traffic_secret: None,
            current_server_traffic_secret: None,
        }
    }
}

/// KeySchedule during handshake.
pub struct KeyScheduleHandshake {
    ks: KeySchedule,
    current_client_traffic_secret: Option<hkdf::Prk>,
    current_server_traffic_secret: Option<hkdf::Prk>,
}

impl KeyScheduleHandshake {
    pub fn client_handshake_traffic_secret(&mut self, hs_hash: &[u8],
                                           key_log: &dyn KeyLog,
                                           client_random: &[u8; 32]) -> hkdf::Prk {
        let secret = self.ks.derive_logged_secret(SecretKind::ClientHandshakeTrafficSecret,
                                                  hs_hash, key_log, client_random);
        self.current_client_traffic_secret = Some(secret.clone());
        secret
    }

    pub fn server_handshake_traffic_secret(&mut self, hs_hash: &[u8],
                                           key_log: &dyn KeyLog,
                                           client_random: &[u8; 32]) -> hkdf::Prk {
        let secret = self.ks.derive_logged_secret(SecretKind::ServerHandshakeTrafficSecret,
                                                  hs_hash, key_log, client_random);
        self.current_server_traffic_secret = Some(secret.clone());
        secret
    }

    pub fn sign_server_finish(&self, hs_hash: &[u8]) -> Vec<u8> {
        self.ks.sign_finish(self.current_server_traffic_secret.as_ref().unwrap(), hs_hash)
    }

    pub fn into_traffic_with_client_finished_pending(mut self) -> KeyScheduleTrafficWithClientFinishedPending {
        self.ks.input_empty();
        KeyScheduleTrafficWithClientFinishedPending {
            ks: self.ks,
            handshake_client_traffic_secret: self.current_client_traffic_secret.unwrap(),
            current_client_traffic_secret: None,
            current_server_traffic_secret: None,
            current_exporter_secret: None
        }
    }
}

/// KeySchedule during traffic stage, retaining the ability to calculate the client's
/// finished verify_data, and incrementally generate the first traffic keys.
pub struct KeyScheduleTrafficWithClientFinishedPending {
    ks: KeySchedule,
    handshake_client_traffic_secret: hkdf::Prk,
    current_client_traffic_secret: Option<hkdf::Prk>,
    current_server_traffic_secret: Option<hkdf::Prk>,
    current_exporter_secret: Option<hkdf::Prk>,
}

impl KeyScheduleTrafficWithClientFinishedPending {
    pub fn sign_client_finish(&self, hs_hash: &[u8]) -> Vec<u8> {
        self.ks.sign_finish(&self.handshake_client_traffic_secret, hs_hash)
    }

    pub fn server_application_traffic_secret(&mut self, hs_hash: &[u8],
                                             key_log: &dyn KeyLog,
                                             client_random: &[u8; 32]) -> hkdf::Prk {
        let secret = self.ks.derive_logged_secret(SecretKind::ServerApplicationTrafficSecret,
                                                  hs_hash, key_log, client_random);
        self.current_server_traffic_secret = Some(secret.clone());
        secret
    }

    pub fn client_application_traffic_secret(&mut self, hs_hash: &[u8],
                                             key_log: &dyn KeyLog,
                                             client_random: &[u8; 32]) -> hkdf::Prk {
        let secret = self.ks.derive_logged_secret(SecretKind::ClientApplicationTrafficSecret,
                                                  hs_hash, key_log, client_random);
        self.current_client_traffic_secret = Some(secret.clone());
        secret
    }

    pub fn exporter_master_secret(&mut self, hs_hash: &[u8],
                                  key_log: &dyn KeyLog,
                                  client_random: &[u8; 32]) {
        let secret = self.ks.derive_logged_secret(SecretKind::ExporterMasterSecret,
                                                  hs_hash, key_log, client_random);
        self.current_exporter_secret = Some(secret);
    }

    pub fn into_traffic(self) -> KeyScheduleTraffic {
        KeyScheduleTraffic {
            ks: self.ks,
            current_client_traffic_secret: self.current_client_traffic_secret.unwrap(),
            current_server_traffic_secret: self.current_server_traffic_secret.unwrap(),
            current_exporter_secret: self.current_exporter_secret.unwrap(),
        }
    }
}


/// KeySchedule during traffic stage.  All traffic & exporter keys are guaranteed
/// to be available.
pub struct KeyScheduleTraffic {
    ks: KeySchedule,
    current_client_traffic_secret: hkdf::Prk,
    current_server_traffic_secret: hkdf::Prk,
    current_exporter_secret: hkdf::Prk,
}

impl KeyScheduleTraffic {
    pub fn next_server_application_traffic_secret(&mut self) -> hkdf::Prk {
        let secret = self.ks.derive_next(&self.current_server_traffic_secret);
        self.current_server_traffic_secret = secret.clone();
        secret
    }

    pub fn next_client_application_traffic_secret(&mut self) -> hkdf::Prk {
        let secret = self.ks.derive_next(&self.current_client_traffic_secret);
        self.current_client_traffic_secret = secret.clone();
        secret
    }

    pub fn resumption_master_secret_and_derive_ticket_psk(&self, hs_hash: &[u8], nonce: &[u8]) -> Vec<u8> {
        let resumption_master_secret = self.ks.derive(self.ks.algorithm(),
                                                      SecretKind::ResumptionMasterSecret,
                                                      hs_hash);
        self.ks.derive_ticket_psk(&resumption_master_secret, nonce)
    }

    pub fn export_keying_material(&self,
                                  out: &mut [u8],
                                  label: &[u8],
                                  context: Option<&[u8]>) -> Result<(), TLSError> {
        self.ks.export_keying_material(&self.current_exporter_secret,
                                       out, label, context)
    }
}

impl KeySchedule {
    fn new(algorithm: hkdf::Algorithm, secret: &[u8]) -> KeySchedule {
        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
        let zeroes = &zeroes[..algorithm.len()];
        let salt = hkdf::Salt::new(algorithm, &zeroes);
        KeySchedule {
            current: salt.extract(secret),
            algorithm,
        }
    }

    #[inline]
    fn algorithm(&self) -> hkdf::Algorithm { self.algorithm }

    fn new_with_empty_secret(algorithm: hkdf::Algorithm) -> KeySchedule {
        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
        Self::new(algorithm, &zeroes[..algorithm.len()])
    }

    /// Input the empty secret.
    fn input_empty(&mut self) {
        let zeroes = [0u8; digest::MAX_OUTPUT_LEN];
        self.input_secret(&zeroes[..self.algorithm.len()]);
    }

    /// Input the given secret.
    fn input_secret(&mut self, secret: &[u8]) {
        let salt: hkdf::Salt = self.derive_for_empty_hash(SecretKind::DerivedSecret);
        self.current = salt.extract(secret);
    }

    /// Derive a secret of given `kind`, using current handshake hash `hs_hash`.
    fn derive<T, L>(&self, key_type: L, kind: SecretKind, hs_hash: &[u8]) -> T
        where
            T: for <'a> From<hkdf::Okm<'a, L>>,
            L: hkdf::KeyType,
    {
        hkdf_expand(&self.current, key_type, kind.to_bytes(), hs_hash)
    }

    fn derive_logged_secret(&self, kind: SecretKind, hs_hash: &[u8],
                            key_log: &dyn KeyLog, client_random: &[u8; 32])
        -> hkdf::Prk
    {
        let log_label = kind.log_label().expect("not a loggable secret");
        if key_log.will_log(log_label) {
            let secret = self.derive::<PayloadU8, _>(PayloadU8Len(self.algorithm.len()), kind, hs_hash)
                .into_inner();
            key_log.log(log_label, client_random, &secret);
        }
        self.derive(self.algorithm, kind, hs_hash)
    }

    /// Derive a secret of given `kind` using the hash of the empty string
    /// for the handshake hash.  Useful only for
    /// `SecretKind::ResumptionPSKBinderKey` and
    /// `SecretKind::DerivedSecret`.
    fn derive_for_empty_hash<T>(&self, kind: SecretKind) -> T
        where
            T: for <'a> From<hkdf::Okm<'a, hkdf::Algorithm>>
    {
        let digest_alg = self.algorithm.hmac_algorithm().digest_algorithm();
        let empty_hash = digest::digest(digest_alg, &[]);
        self.derive(self.algorithm, kind, empty_hash.as_ref())
    }

    /// Sign the finished message consisting of `hs_hash` using a current
    /// traffic secret.
    fn sign_finish(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8> {
        self.sign_verify_data(base_key, hs_hash)
    }

    /// Sign the finished message consisting of `hs_hash` using the key material
    /// `base_key`.
    fn sign_verify_data(&self, base_key: &hkdf::Prk, hs_hash: &[u8]) -> Vec<u8> {
        let hmac_alg = self.algorithm.hmac_algorithm();
        let hmac_key = hkdf_expand(base_key, hmac_alg, b"finished", &[]);
        hmac::sign(&hmac_key, hs_hash)
            .as_ref()
            .to_vec()
    }

    /// Derive the next application traffic secret, returning it.
    fn derive_next(&self, base_key: &hkdf::Prk) -> hkdf::Prk {
        hkdf_expand(&base_key, self.algorithm, b"traffic upd", &[])
    }

    /// Derive the PSK to use given a resumption_master_secret and
    /// ticket_nonce.
    fn derive_ticket_psk(&self, rms: &hkdf::Prk, nonce: &[u8]) -> Vec<u8> {
        let payload: PayloadU8 = hkdf_expand(rms, PayloadU8Len(self.algorithm.len()), b"resumption", nonce);
        payload.into_inner()
    }

    fn export_keying_material(&self,
                              current_exporter_secret: &hkdf::Prk,
                              out: &mut [u8],
                              label: &[u8],
                              context: Option<&[u8]>) -> Result<(), TLSError> {
        let digest_alg = self.algorithm.hmac_algorithm().digest_algorithm();

        let h_empty = digest::digest(digest_alg, &[]);
        let secret: hkdf::Prk =
            hkdf_expand(current_exporter_secret, self.algorithm, label, h_empty.as_ref());

        let h_context = digest::digest(digest_alg, context.unwrap_or(&[]));

        // TODO: Test what happens when this fails
        hkdf_expand_info(&secret, PayloadU8Len(out.len()), b"exporter", h_context.as_ref(),
                         |okm| okm.fill(out))
            .map_err(|_| TLSError::General("exporting too much".to_string()))
    }
}

pub(crate) fn hkdf_expand<T, L>(secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8]) -> T
    where
        T: for <'a> From<hkdf::Okm<'a, L>>,
        L: hkdf::KeyType,
{
    hkdf_expand_info(secret, key_type, label, context, |okm| okm.into())
}

fn hkdf_expand_info<F, T, L>(secret: &hkdf::Prk, key_type: L, label: &[u8], context: &[u8], f: F)
        -> T
    where
        F: for<'b> FnOnce(hkdf::Okm<'b, L>) -> T,
        L: hkdf::KeyType
{
    const LABEL_PREFIX: &[u8] = b"tls13 ";

    let output_len = u16::to_be_bytes(key_type.len() as u16);
    let label_len = u8::to_be_bytes((LABEL_PREFIX.len() + label.len()) as u8);
    let context_len = u8::to_be_bytes(context.len() as u8);

    let info = &[&output_len[..], &label_len[..], LABEL_PREFIX, label, &context_len[..], context];
    let okm = secret.expand(info, key_type).unwrap();

    f(okm)
}

pub(crate) struct PayloadU8Len(pub(crate) usize);
impl hkdf::KeyType for PayloadU8Len {
    fn len(&self) -> usize { self.0 }
}

impl From<hkdf::Okm<'_, PayloadU8Len>> for PayloadU8 {
    fn from(okm: hkdf::Okm<PayloadU8Len>) -> Self {
        let mut r = vec![0u8;okm.len().0];
        okm.fill(&mut r[..]).unwrap();
        PayloadU8::new(r)
    }
}

pub fn derive_traffic_key(secret: &hkdf::Prk, aead_algorithm: &'static aead::Algorithm)
    -> aead::UnboundKey
{
    hkdf_expand(secret, aead_algorithm, b"key", &[])
}

pub(crate) fn derive_traffic_iv(secret: &hkdf::Prk) -> Iv {
    hkdf_expand(secret, IvLen, b"iv", &[])
}

#[cfg(test)]
mod test {
    use super::{KeySchedule, SecretKind, derive_traffic_key, derive_traffic_iv};
    use ring::{aead, hkdf};
    use crate::KeyLog;

    #[test]
    fn test_vectors() {
        /* These test vectors generated with OpenSSL. */
        let hs_start_hash = [
            0xec, 0x14, 0x7a, 0x06, 0xde, 0xa3, 0xc8, 0x84, 0x6c, 0x02, 0xb2, 0x23, 0x8e,
            0x41, 0xbd, 0xdc, 0x9d, 0x89, 0xf9, 0xae, 0xa1, 0x7b, 0x5e, 0xfd, 0x4d, 0x74,
            0x82, 0xaf, 0x75, 0x88, 0x1c, 0x0a
        ];

        let hs_full_hash = [
            0x75, 0x1a, 0x3d, 0x4a, 0x14, 0xdf, 0xab, 0xeb, 0x68, 0xe9, 0x2c, 0xa5, 0x91,
            0x8e, 0x24, 0x08, 0xb9, 0xbc, 0xb0, 0x74, 0x89, 0x82, 0xec, 0x9c, 0x32, 0x30,
            0xac, 0x30, 0xbb, 0xeb, 0x23, 0xe2
        ];

        let ecdhe_secret = [
            0xe7, 0xb8, 0xfe, 0xf8, 0x90, 0x3b, 0x52, 0x0c, 0xb9, 0xa1, 0x89, 0x71, 0xb6,
            0x9d, 0xd4, 0x5d, 0xca, 0x53, 0xce, 0x2f, 0x12, 0xbf, 0x3b, 0xef, 0x93, 0x15,
            0xe3, 0x12, 0x71, 0xdf, 0x4b, 0x40
        ];

        let client_hts = [
            0x61, 0x7b, 0x35, 0x07, 0x6b, 0x9d, 0x0e, 0x08, 0xcf, 0x73, 0x1d, 0x94, 0xa8,
            0x66, 0x14, 0x78, 0x41, 0x09, 0xef, 0x25, 0x55, 0x51, 0x92, 0x1d, 0xd4, 0x6e,
            0x04, 0x01, 0x35, 0xcf, 0x46, 0xab
        ];

        let client_hts_key = [
            0x62, 0xd0, 0xdd, 0x00, 0xf6, 0x96, 0x19, 0xd3, 0xb8, 0x19, 0x3a, 0xb4, 0xa0,
            0x95, 0x85, 0xa7
        ];

        let client_hts_iv = [
            0xff, 0xf7, 0x5d, 0xf5, 0xad, 0x35, 0xd5, 0xcb, 0x3c, 0x53, 0xf3, 0xa9
        ];

        let server_hts = [
            0xfc, 0xf7, 0xdf, 0xe6, 0x4f, 0xa2, 0xc0, 0x4f, 0x62, 0x35, 0x38, 0x7f, 0x43,
            0x4e, 0x01, 0x42, 0x23, 0x36, 0xd9, 0xc0, 0x39, 0xde, 0x68, 0x47, 0xa0, 0xb9,
            0xdd, 0xcf, 0x29, 0xa8, 0x87, 0x59
        ];

        let server_hts_key = [
            0x04, 0x67, 0xf3, 0x16, 0xa8, 0x05, 0xb8, 0xc4, 0x97, 0xee, 0x67, 0x04, 0x7b,
            0xbc, 0xbc, 0x54
        ];

        let server_hts_iv = [
            0xde, 0x83, 0xa7, 0x3e, 0x9d, 0x81, 0x4b, 0x04, 0xc4, 0x8b, 0x78, 0x09
        ];

        let client_ats = [
            0xc1, 0x4a, 0x6d, 0x79, 0x76, 0xd8, 0x10, 0x2b, 0x5a, 0x0c, 0x99, 0x51, 0x49,
            0x3f, 0xee, 0x87, 0xdc, 0xaf, 0xf8, 0x2c, 0x24, 0xca, 0xb2, 0x14, 0xe8, 0xbe,
            0x71, 0xa8, 0x20, 0x6d, 0xbd, 0xa5
        ];

        let client_ats_key = [
            0xcc, 0x9f, 0x5f, 0x98, 0x0b, 0x5f, 0x10, 0x30, 0x6c, 0xba, 0xd7, 0xbe, 0x98,
            0xd7, 0x57, 0x2e
        ];

        let client_ats_iv = [
            0xb8, 0x09, 0x29, 0xe8, 0xd0, 0x2c, 0x70, 0xf6, 0x11, 0x62, 0xed, 0x6b
        ];

        let server_ats = [
            0x2c, 0x90, 0x77, 0x38, 0xd3, 0xf8, 0x37, 0x02, 0xd1, 0xe4, 0x59, 0x8f, 0x48,
            0x48, 0x53, 0x1d, 0x9f, 0x93, 0x65, 0x49, 0x1b, 0x9f, 0x7f, 0x52, 0xc8, 0x22,
            0x29, 0x0d, 0x4c, 0x23, 0x21, 0x92
        ];

        let server_ats_key = [
            0x0c, 0xb2, 0x95, 0x62, 0xd8, 0xd8, 0x8f, 0x48, 0xb0, 0x2c, 0xbf, 0xbe, 0xd7,
            0xe6, 0x2b, 0xb3
        ];

        let server_ats_iv = [
            0x0d, 0xb2, 0x8f, 0x98, 0x85, 0x86, 0xa1, 0xb7, 0xe4, 0xd5, 0xc6, 0x9c
        ];

        let hkdf = hkdf::HKDF_SHA256;
        let mut ks = KeySchedule::new_with_empty_secret(hkdf);
        ks.input_secret(&ecdhe_secret);

        assert_traffic_secret(
            &ks,
            SecretKind::ClientHandshakeTrafficSecret,
            &hs_start_hash,
            &client_hts,
            &client_hts_key,
        &client_hts_iv);

        assert_traffic_secret(
            &ks,
            SecretKind::ServerHandshakeTrafficSecret,
            &hs_start_hash,
            &server_hts,
            &server_hts_key,
            &server_hts_iv);

        ks.input_empty();

        assert_traffic_secret(
            &ks,
            SecretKind::ClientApplicationTrafficSecret,
            &hs_full_hash,
            &client_ats,
            &client_ats_key,
            &client_ats_iv);

        assert_traffic_secret(
            &ks,
            SecretKind::ServerApplicationTrafficSecret,
            &hs_full_hash,
            &server_ats,
            &server_ats_key,
            &server_ats_iv);
    }

    fn assert_traffic_secret(
        ks: &KeySchedule,
        kind: SecretKind,
        hash: &[u8],
        expected_traffic_secret: &[u8],
        expected_key: &[u8],
        expected_iv: &[u8],
    ) {
        struct Log<'a>(&'a [u8]);
        impl KeyLog for Log<'_> {
            fn log(&self, _label: &str, _client_random: &[u8], secret: &[u8]) {
                assert_eq!(self.0, secret);
            }
        }
        let log = Log(expected_traffic_secret);
        let traffic_secret = ks.derive_logged_secret(kind, &hash, &log, &[0; 32]);

        // Since we can't test key equality, we test the output of sealing with the key instead.
        let aead_alg = &aead::AES_128_GCM;
        let key = derive_traffic_key(&traffic_secret, aead_alg);
        let seal_output = seal_zeroes(key);
        let expected_key = aead::UnboundKey::new(aead_alg, expected_key).unwrap();
        let expected_seal_output = seal_zeroes(expected_key);
        assert_eq!(seal_output, expected_seal_output);
        assert!(seal_output.len() >= 48); // Sanity check.

        let iv = derive_traffic_iv(&traffic_secret);
        assert_eq!(iv.value(), expected_iv);
    }

    fn seal_zeroes(key: aead::UnboundKey) -> Vec<u8> {
        let key = aead::LessSafeKey::new(key);
        let mut seal_output = vec![0; 32];
        key.seal_in_place_append_tag(
            aead::Nonce::assume_unique_for_key([0; aead::NONCE_LEN]),
            aead::Aad::empty(),
            &mut seal_output)
            .unwrap();
        seal_output
    }
}
