From 892fec9aafd2bd7d4d001c5e5c60587f0a69693b Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Fri, 25 Aug 2023 14:53:33 +0200 Subject: [PATCH 1/8] test: add test vectors from draft 03 --- Cargo.toml | 1 + src/crypto/aead.rs | 247 ++-- src/crypto/key_expansion.rs | 48 +- src/crypto/secret.rs | 48 +- src/header/mod.rs | 10 +- src/test_vectors/mod.rs | 134 ++- src/test_vectors/test-vectors.json | 1798 ++++++++++++++++++++++++---- 7 files changed, 1821 insertions(+), 465 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7e284ef..bb408fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ rand = "0.8" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" strum_macros = "0.25" +test-case = "3.1.0" [features] default = ["ring"] diff --git a/src/crypto/aead.rs b/src/crypto/aead.rs index fbdf9c6..051ecc7 100644 --- a/src/crypto/aead.rs +++ b/src/crypto/aead.rs @@ -34,167 +34,116 @@ pub trait AeadDecrypt { #[cfg(test)] mod test { - mod aes_gcm { - use crate::{ - crypto::{ - aead::AeadEncrypt, - cipher_suite::{CipherSuite, CipherSuiteVariant}, - key_expansion::KeyExpansion, - secret::Secret, - }, - header::{Header, HeaderFields}, - }; - use rand::{thread_rng, Rng}; - const KEY_MATERIAL: &str = "THIS_IS_RANDOM"; - - #[test] - fn encrypt_random_frame() { - let mut data = vec![0u8; 1024]; - thread_rng().fill(data.as_mut_slice()); - let header = Header::default(); - let cipher_suite = CipherSuite::from(CipherSuiteVariant::AesGcm256Sha512); - let secret = Secret::expand_from(&cipher_suite, KEY_MATERIAL.as_bytes()).unwrap(); - - let _tag = cipher_suite - .encrypt( - &mut data, - &secret, - &Vec::from(&header), - header.frame_count(), - ) - .unwrap(); - } + use crate::crypto::key_expansion::KeyExpansion; + use crate::header::{FrameCount, KeyId}; + use crate::test_vectors::{get_sframe_test_vector, SframeTest}; + use crate::util::test::assert_bytes_eq; + use crate::{ + crypto::{ + aead::AeadDecrypt, + aead::AeadEncrypt, + cipher_suite::{CipherSuite, CipherSuiteVariant}, + secret::Secret, + }, + header::{Header, HeaderFields}, + }; + + use test_case::test_case; + + use rand::{thread_rng, Rng}; + + const KEY_MATERIAL: &str = "THIS_IS_RANDOM"; + + #[test] + fn encrypt_random_frame() { + let mut data = vec![0u8; 1024]; + thread_rng().fill(data.as_mut_slice()); + let header = Header::default(); + let cipher_suite = CipherSuite::from(CipherSuiteVariant::AesGcm256Sha512); + let secret = Secret::expand_from(&cipher_suite, KEY_MATERIAL.as_bytes()).unwrap(); + + let _tag = cipher_suite + .encrypt( + &mut data, + &secret, + &Vec::from(&header), + header.frame_count(), + ) + .unwrap(); + } - mod test_vectors { - - use crate::crypto::key_expansion::KeyExpansion; - use crate::test_vectors::{get_test_vector, TestVector}; - - use crate::{ - crypto::{ - aead::{AeadDecrypt, AeadEncrypt}, - cipher_suite::{CipherSuite, CipherSuiteVariant}, - secret::Secret, - }, - header::{FrameCount, Header, HeaderFields, KeyId}, - util::test::assert_bytes_eq, - }; - - fn encrypt_test_vector(variant: CipherSuiteVariant) { - let test_vector = get_test_vector(&variant.to_string()); - let cipher_suite = CipherSuite::from(variant); - - let secret = prepare_secret(&cipher_suite, test_vector); - - for enc in &test_vector.encryptions { - let mut data = test_vector.plain_text.clone(); - let header = Header::with_frame_count( - KeyId::from(enc.key_id), - FrameCount::from(enc.frame_count), - ); - let header_buffer = Vec::from(&header); - let tag = cipher_suite - .encrypt(&mut data, &secret, &header_buffer, header.frame_count()) - .unwrap(); - let full_frame: Vec = header_buffer - .into_iter() - .chain(data.into_iter()) - .chain(tag.as_ref().iter().cloned()) - .collect(); - - assert_bytes_eq(&full_frame, &enc.cipher_text); - } - } + #[test_case(CipherSuiteVariant::AesGcm128Sha256; "AesGcm128Sha256")] + #[test_case(CipherSuiteVariant::AesGcm256Sha512; "AesGcm256Sha512")] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32"))] + fn encrypt_test_vector(variant: CipherSuiteVariant) { + let test_vec = get_sframe_test_vector(&variant.to_string()); + let cipher_suite = CipherSuite::from(variant); - fn decrypt_test_vector(variant: CipherSuiteVariant) { - let test_vector = get_test_vector(&variant.to_string()); - let cipher_suite = CipherSuite::from(variant); + let secret = prepare_secret(&cipher_suite, test_vec); - let secret = prepare_secret(&cipher_suite, test_vector); + let mut data_buffer = test_vec.plain_text.clone(); - for enc in &test_vector.encryptions { - let header = Header::with_frame_count( - KeyId::from(enc.key_id), - FrameCount::from(enc.frame_count), - ); - let header_buffer = Vec::from(&header); - let mut data = Vec::from(&enc.cipher_text[header.size()..]); + let header = Header::with_frame_count( + KeyId::from(test_vec.key_id), + FrameCount::from(test_vec.frame_count), + ); + let header_buffer = Vec::from(&header); - let decrypted = cipher_suite - .decrypt(&mut data, &secret, &header_buffer, header.frame_count()) - .unwrap(); + let aad_buffer = [header_buffer.as_slice(), test_vec.metadata.as_slice()].concat(); - assert_bytes_eq(decrypted, &test_vector.plain_text); - } - } + let tag = cipher_suite + .encrypt(&mut data_buffer, &secret, &aad_buffer, header.frame_count()) + .unwrap(); - fn prepare_secret(cipher_suite: &CipherSuite, test_vector: &TestVector) -> Secret { - if cipher_suite.is_ctr_mode() { - Secret::expand_from(cipher_suite, &test_vector.key_material).unwrap() - } else { - Secret::from_test_vector(test_vector) - } - } + let full_frame: Vec = header_buffer + .into_iter() + .chain(data_buffer.into_iter()) + .chain(tag.as_ref().iter().cloned()) + .collect(); - #[test] - fn encrypt_test_vector_aes_gcm_128_sha256() { - encrypt_test_vector(CipherSuiteVariant::AesGcm128Sha256); - } + assert_bytes_eq(&aad_buffer, &test_vec.aad); + assert_bytes_eq(&full_frame, &test_vec.cipher_text); + } - #[test] - fn should_decrypt_test_vector_aes_gcm_128_sha256() { - decrypt_test_vector(CipherSuiteVariant::AesGcm128Sha256); - } + #[test_case(CipherSuiteVariant::AesGcm128Sha256; "AesGcm128Sha256")] + #[test_case(CipherSuiteVariant::AesGcm256Sha512; "AesGcm256Sha512")] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32"))] + fn decrypt_test_vector(variant: CipherSuiteVariant) { + let test_vec = get_sframe_test_vector(&variant.to_string()); + let cipher_suite = CipherSuite::from(variant); - #[test] - fn encrypt_test_vectors_aes_gcm_256_sha512() { - encrypt_test_vector(CipherSuiteVariant::AesGcm256Sha512); - } + let secret = prepare_secret(&cipher_suite, test_vec); + let header = Header::with_frame_count( + KeyId::from(test_vec.key_id), + FrameCount::from(test_vec.frame_count), + ); + let header_buffer = Vec::from(&header); - #[test] - fn should_decrypt_test_vectors_aes_gcm_256_sha512() { - decrypt_test_vector(CipherSuiteVariant::AesGcm256Sha512); - } + let aad_buffer = [header_buffer.as_slice(), test_vec.metadata.as_slice()].concat(); + assert_bytes_eq(&aad_buffer, &test_vec.aad); + + let mut data = Vec::from(&test_vec.cipher_text[header.size()..]); + + let decrypted = cipher_suite + .decrypt(&mut data, &secret, &aad_buffer, header.frame_count()) + .unwrap(); + + assert_bytes_eq(decrypted, &test_vec.plain_text); + } - #[cfg(feature = "openssl")] - mod aes_ctr { - use crate::CipherSuiteVariant; - - use super::{decrypt_test_vector, encrypt_test_vector}; - - #[test] - fn should_encrypt_test_vectors_aes_ctr_64_hmac_sha256_64() { - encrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_64); - } - - #[test] - fn should_decrypt_test_vectors_aes_ctr_64_hmac_sha256_64() { - decrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_64); - } - - #[test] - fn should_encrypt_test_vectors_aes_ctr_64_hmac_sha256_32() { - encrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_32); - } - - #[test] - fn should_decrypt_test_vectors_aes_ctr_64_hmac_sha256_32() { - decrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_32); - } - - #[test] - // AesCtr128HmacSha256_80 is not available in the test vectors - #[ignore] - fn should_encrypt_test_vectors_aes_ctr_64_hmac_sha256_80() { - encrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_32); - } - - #[test] - // AesCtr128HmacSha256_80 is not available in the test vectors - #[ignore] - fn should_decrypt_test_vectors_aes_ctr_64_hmac_sha256_80() { - decrypt_test_vector(CipherSuiteVariant::AesCtr128HmacSha256_32); - } + fn prepare_secret(cipher_suite: &CipherSuite, test_vec: &SframeTest) -> Secret { + if cipher_suite.is_ctr_mode() { + // the test vectors do not provide the auth key, so we have to expand here + Secret::expand_from(cipher_suite, &test_vec.key_material).unwrap() + } else { + Secret { + key: test_vec.sframe_key.clone(), + salt: test_vec.sframe_salt.clone(), + auth: None, } } } diff --git a/src/crypto/key_expansion.rs b/src/crypto/key_expansion.rs index 0e83d0e..ef1dab4 100644 --- a/src/crypto/key_expansion.rs +++ b/src/crypto/key_expansion.rs @@ -23,46 +23,46 @@ pub const SFRAME_HDKF_SUB_AUTH_EXPAND_INFO: &[u8] = b"auth"; #[cfg(test)] mod test { + use super::KeyExpansion; use crate::crypto::cipher_suite::CipherSuite; use crate::crypto::secret::Secret; - use crate::test_vectors::get_test_vector; - + use crate::test_vectors::get_sframe_test_vector; use crate::{crypto::cipher_suite::CipherSuiteVariant, util::test::assert_bytes_eq}; - use super::KeyExpansion; + mod aes_gcm { + use super::*; - fn derive_correct_base_keys(variant: CipherSuiteVariant) { - let test_vector = get_test_vector(&variant.to_string()); - let secret = - Secret::expand_from(&CipherSuite::from(variant), &test_vector.key_material).unwrap(); + use test_case::test_case; - assert_bytes_eq(&secret.key, &test_vector.key); - assert_bytes_eq(&secret.salt, &test_vector.salt); - } + #[test_case(CipherSuiteVariant::AesGcm128Sha256; "AesGcm128Sha256")] + #[test_case(CipherSuiteVariant::AesGcm256Sha512; "AesGcm256Sha512")] + fn derive_correct_base_keys(variant: CipherSuiteVariant) { + let test_vec = get_sframe_test_vector(&variant.to_string()); + let secret = + Secret::expand_from(&CipherSuite::from(variant), &test_vec.key_material).unwrap(); - #[test] - fn derive_correct_keys_aes_gcm_128_sha256() { - derive_correct_base_keys(CipherSuiteVariant::AesGcm128Sha256); - } - - #[test] - fn derive_correct_keys_aes_gcm_256_sha512() { - derive_correct_base_keys(CipherSuiteVariant::AesGcm256Sha512); + assert_bytes_eq(&secret.key, &test_vec.sframe_key); + assert_bytes_eq(&secret.salt, &test_vec.sframe_salt); + } } #[cfg(feature = "openssl")] mod aes_ctr { use super::*; + use crate::test_vectors::get_aes_ctr_test_vector; + + use test_case::test_case; + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80")] + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64")] + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32")] fn derive_correct_sub_keys(variant: CipherSuiteVariant) { - let test_vector = get_test_vector(&variant.to_string()); + let test_vec = get_aes_ctr_test_vector(&variant.to_string()); let cipher_suite = CipherSuite::from(variant); - let secret = Secret::expand_from(&cipher_suite, &test_vector.key_material).unwrap(); + let secret = Secret::expand_from(&cipher_suite, &test_vec.key_material).unwrap(); - assert_bytes_eq(&secret.salt, &test_vector.salt); - // the subkeys stored in secret.key and secret.auth are not included in the test vectors - assert_eq!(secret.auth.unwrap().len(), cipher_suite.hash_len); - assert_eq!(secret.key.len(), cipher_suite.key_len); + assert_bytes_eq(&secret.auth.unwrap(), &test_vec.auth_key); + assert_bytes_eq(&secret.key, &test_vec.enc_key); } #[test] diff --git a/src/crypto/secret.rs b/src/crypto/secret.rs index 2194eda..3f4a3f3 100644 --- a/src/crypto/secret.rs +++ b/src/crypto/secret.rs @@ -20,48 +20,34 @@ impl Secret { iv } - - #[cfg(test)] - pub(crate) fn from_test_vector(test_vector: &crate::test_vectors::TestVector) -> Secret { - Secret { - key: test_vector.key.clone(), - salt: test_vector.salt.clone(), - auth: None, - } - } } #[cfg(test)] mod test { - use crate::crypto::cipher_suite::CipherSuite; - use crate::crypto::key_expansion::KeyExpansion; - use crate::test_vectors::get_test_vector; - + use crate::test_vectors::get_sframe_test_vector; use crate::{ crypto::cipher_suite::CipherSuiteVariant, header::FrameCount, util::test::assert_bytes_eq, }; use super::Secret; - + use test_case::test_case; const NONCE_LEN: usize = 12; - fn test_nonce(variant: CipherSuiteVariant) { - let tv = get_test_vector(&variant.to_string()); - - for enc in &tv.encryptions { - let secret = - Secret::expand_from(&CipherSuite::from(variant), &tv.key_material).unwrap(); - let nonce: [u8; NONCE_LEN] = secret.create_nonce(&FrameCount::from(enc.frame_count)); - assert_bytes_eq(&nonce, &enc.nonce); - } - } + #[test_case(CipherSuiteVariant::AesGcm128Sha256; "AesGcm128Sha256")] + #[test_case(CipherSuiteVariant::AesGcm256Sha512; "AesGcm256Sha512")] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64"))] + #[cfg_attr(feature = "openssl", test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32"))] + fn create_correct_nonce(variant: CipherSuiteVariant) { + let test_vec = get_sframe_test_vector(&variant.to_string()); + + let secret = Secret { + key: test_vec.sframe_key.clone(), + salt: test_vec.sframe_salt.clone(), + auth: None, + }; - #[test] - fn create_correct_nonce_aes_gcm_128_sha256() { - test_nonce(CipherSuiteVariant::AesGcm128Sha256); - } - #[test] - fn create_correct_nonce_aes_gcm_256_sha512() { - test_nonce(CipherSuiteVariant::AesGcm256Sha512); + let nonce: [u8; NONCE_LEN] = secret.create_nonce(&FrameCount::from(test_vec.frame_count)); + assert_bytes_eq(&nonce, &test_vec.nonce); } } diff --git a/src/header/mod.rs b/src/header/mod.rs index 4646145..6d8658d 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -254,25 +254,23 @@ mod test { #[test] fn serialize_test_vectors() { - crate::test_vectors::get_test_vector(&AesGcm128Sha256.to_string()) - .encryptions + crate::test_vectors::get_header_test_vectors() .iter() .for_each(|test_vector| { let header = Header::with_frame_count( KeyId::from(test_vector.key_id), FrameCount::from(test_vector.frame_count), ); - assert_bytes_eq(Vec::from(&header).as_slice(), &test_vector.header); + assert_bytes_eq(Vec::from(&header).as_slice(), &test_vector.encoded); }); } #[test] fn deserialize_test_vectors() { - crate::test_vectors::get_test_vector(&AesGcm256Sha512.to_string()) - .encryptions + crate::test_vectors::get_header_test_vectors() .iter() .for_each(|test_vector| { - let header = Header::deserialize(&test_vector.header).unwrap(); + let header = Header::deserialize(&test_vector.encoded).unwrap(); assert_eq!(header.key_id(), KeyId::from(test_vector.key_id)); assert_eq!(header.frame_count(), test_vector.frame_count); }); diff --git a/src/test_vectors/mod.rs b/src/test_vectors/mod.rs index d2fcfba..89596e8 100644 --- a/src/test_vectors/mod.rs +++ b/src/test_vectors/mod.rs @@ -5,8 +5,28 @@ extern crate serde; use phf::phf_map; -pub fn get_test_vector(cipher_suite_variant: &str) -> &'static TestVector { - TEST_VECTORS +#[derive(serde::Deserialize, Debug, Clone)] +pub struct TestVectors { + pub header: Vec, + pub aes_ctr_hmac: Vec, + pub sframe: Vec, +} + +pub fn get_header_test_vectors() -> &'static Vec { + &TEST_VECTORS.header +} + +pub fn get_aes_ctr_test_vector(cipher_suite_variant: &str) -> &'static AesCtrHmacTest { + &TEST_VECTORS + .aes_ctr_hmac + .iter() + .find(|v| v.cipher_suite_variant == cipher_suite_variant) + .unwrap() +} + +pub fn get_sframe_test_vector(cipher_suite_variant: &str) -> &'static SframeTest { + &TEST_VECTORS + .sframe .iter() .find(|v| v.cipher_suite_variant == cipher_suite_variant) .unwrap() @@ -14,54 +34,110 @@ pub fn get_test_vector(cipher_suite_variant: &str) -> &'static TestVector { const TEST_VECTORS_STR: &str = std::include_str!("test-vectors.json"); lazy_static::lazy_static! { -static ref TEST_VECTORS: Vec = { +static ref TEST_VECTORS: TestVectors = { parse_test_vectors() }; } const CIPHER_SUITE_NAME_FROM_ID: phf::Map = phf_map! { - // AesCtr128HmacSha256_80 is not included in the test vectors - 1u8 => "AesCtr128HmacSha256_32", + 1u8 => "AesCtr128HmacSha256_80", 2u8 => "AesCtr128HmacSha256_64", - 3u8 => "AesGcm128Sha256", - 4u8 => "AesGcm256Sha512", + 3u8 => "AesCtr128HmacSha256_32", + 4u8 => "AesGcm128Sha256", + 5u8 => "AesGcm256Sha512", }; #[derive(serde::Deserialize, Debug, Clone)] -pub struct EncryptionTestCase { +pub struct HeaderTest { #[serde(rename = "kid")] pub key_id: u64, #[serde(rename = "ctr")] pub frame_count: u64, #[serde(deserialize_with = "vec_from_hex_str")] - pub header: Vec, + pub encoded: Vec, +} + +#[derive(serde::Deserialize, Debug, Clone)] +pub struct AesCtrHmacTest { + #[serde( + rename = "cipher_suite", + deserialize_with = "cipher_suite_name_from_id" + )] + pub cipher_suite_variant: String, + + #[serde(rename = "key", deserialize_with = "vec_from_hex_str")] + pub base_key: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub aead_label: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub aead_secret: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub enc_key: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub auth_key: Vec, + #[serde(deserialize_with = "vec_from_hex_str")] pub nonce: Vec, - #[serde(rename = "ciphertext", deserialize_with = "vec_from_hex_str")] - pub cipher_text: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub aad: Vec, + + // TODO rename + #[serde(deserialize_with = "vec_from_hex_str")] + pub pt: Vec, + + // TODO rename + #[serde(deserialize_with = "vec_from_hex_str")] + pub ct: Vec, } #[derive(serde::Deserialize, Debug, Clone)] -pub struct TestVector { +pub struct SframeTest { #[serde( rename = "cipher_suite", deserialize_with = "cipher_suite_name_from_id" )] pub cipher_suite_variant: String, + #[serde(rename = "kid")] + pub key_id: u64, + + #[serde(rename = "ctr")] + pub frame_count: u64, + #[serde(rename = "base_key", deserialize_with = "vec_from_hex_str")] pub key_material: Vec, #[serde(deserialize_with = "vec_from_hex_str")] - pub key: Vec, + pub sframe_label: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub sframe_secret: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub sframe_key: Vec, #[serde(deserialize_with = "vec_from_hex_str")] - pub salt: Vec, + pub sframe_salt: Vec, - #[serde(rename = "plaintext", deserialize_with = "vec_from_hex_str")] + #[serde(deserialize_with = "vec_from_hex_str")] + pub metadata: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub nonce: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub aad: Vec, + + #[serde(rename = "pt", deserialize_with = "vec_from_hex_str")] pub plain_text: Vec, - pub encryptions: Vec, + #[serde(rename = "ct", deserialize_with = "vec_from_hex_str")] + pub cipher_text: Vec, } fn vec_from_hex_str<'de, D>(deserializer: D) -> Result, D::Error> @@ -88,20 +164,36 @@ where } } -fn parse_test_vectors() -> Vec { +fn parse_test_vectors() -> TestVectors { serde_json::from_str(TEST_VECTORS_STR).unwrap() } #[cfg(test)] mod test { - use super::{get_test_vector, CIPHER_SUITE_NAME_FROM_ID}; + use crate::test_vectors::{get_aes_ctr_test_vector, get_sframe_test_vector}; + use super::{get_header_test_vectors, CIPHER_SUITE_NAME_FROM_ID}; + + #[test] + fn should_parse_header_test_vectors() { + let header_tests = get_header_test_vectors(); + assert_ne!(header_tests.len(), 0); + } #[test] - fn should_parse_test_vectors() { + fn should_parse_sframe_test_vectors() { let valid_cipher_suite_variants = CIPHER_SUITE_NAME_FROM_ID.values(); for &variant in valid_cipher_suite_variants { - let vector = get_test_vector(variant); - assert_eq!(vector.cipher_suite_variant, variant); + let sframe_test = get_sframe_test_vector(variant); + assert_eq!(sframe_test.cipher_suite_variant, variant); + } + } + + #[test] + fn should_parse_aes_test_vectors() { + for cipher_suite_id in 1..=3u8 { + let &variant = CIPHER_SUITE_NAME_FROM_ID.get(&cipher_suite_id).unwrap(); + let aes_ctr_test = get_aes_ctr_test_vector(variant); + assert_eq!(aes_ctr_test.cipher_suite_variant, variant); } } } diff --git a/src/test_vectors/test-vectors.json b/src/test_vectors/test-vectors.json index 1edecde..382b9ce 100644 --- a/src/test_vectors/test-vectors.json +++ b/src/test_vectors/test-vectors.json @@ -1,234 +1,1564 @@ -[ - { - "cipher_suite": 1, - "base_key": "101112131415161718191a1b1c1d1e1f", - "key": "343d3290f5c0b936415bea9a43c6f5a2", - "salt": "42d662fbad5cd81eb3aad79a", - "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e", - "encryptions": [ - { - "kid": 7, - "ctr": 0, - "header": "0700", - "nonce": "42d662fbad5cd81eb3aad79a", - "ciphertext": "0700c5095af9dbbbed6a952de114ea7b42768509f1ffc9749abb1e95bf4514d8d82a0eef4b5ecac16fa193977fa1aa1c9fa5c7e730b934669c" - }, - { - "kid": 7, - "ctr": 1, - "header": "0701", - "nonce": "42d662fbad5cd81eb3aad79b", - "ciphertext": "0701559e262525382885c6c93be8f61a9064db2dd1e1e96ab1dbd829ca4af4f45f2b97a4889217a3f8a2159fb8201b7d71db01702b9caf8df6" - }, - { - "kid": 7, - "ctr": 2, - "header": "0702", - "nonce": "42d662fbad5cd81eb3aad798", - "ciphertext": "07020a8f21e052eaa09e50da0a909d156cc55b9ef2f2abbcca765f7af3cfb1af234e3eac1dbc376631c83cf1ff1f8ab339dbc41044742c668d" - }, - { - "kid": 15, - "ctr": 170, - "header": "080faa", - "nonce": "42d662fbad5cd81eb3aad730", - "ciphertext": "080faa9c65aa5b167873f25827f17bc34879a4aaa6b38dd9584472e1849d5da51555f288d08f03166a5f26af01794006255c88b589861e2f8e3e" - }, - { - "kid": 511, - "ctr": 170, - "header": "0901ffaa", - "nonce": "42d662fbad5cd81eb3aad730", - "ciphertext": "0901ffaa9c65aa5b167873f25827f17bc34879a4aaa6b38dd9584472e1849d5da51555f288d08f03166a5f26af01794006255c88b58986ca1ead10" - }, - { - "kid": 511, - "ctr": 43690, - "header": "1901ffaaaa", - "nonce": "42d662fbad5cd81eb3aa7d30", - "ciphertext": "1901ffaaaa990cbeb4ae2e3a76be8bb954b62591e791d0fa53c0553bc1d1e021d270b1a10688cd89195203b01978925373b04f9c08c3a4e563e2f6b9" - }, - { - "kid": 72057594037927935, - "ctr": 72057594037927935, - "header": "6effffffffffffffffffffffffffff", - "nonce": "42d662fbada327e14c552865", - "ciphertext": "6effffffffffffffffffffffffffff412c43c8077c286f7df3dd9988d1bd033f1067493e09421e5bfc363e50a3c803b4da9239514cb924dbcb5f33e33112083e99108de2ecd6" - } - ] - }, - { - "cipher_suite": 2, - "base_key": "202122232425262728292a2b2c2d2e2f", - "key": "3fce747d505e46ec9b92d9f58ee7a5d4", - "salt": "77fbf5f1d82c73f6d2b353c9", - "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e", - "encryptions": [ - { - "kid": 7, - "ctr": 0, - "header": "0700", - "nonce": "77fbf5f1d82c73f6d2b353c9", - "ciphertext": "07009d89e5753e06edf3025f1ccd70b095ebaf10c250e11da740f50f57b6ce860d7321dfa49688a2cd6c6d9a71ae9d5c14ad0978efdd719a7f18c48f07" - }, - { - "kid": 7, - "ctr": 1, - "header": "0701", - "nonce": "77fbf5f1d82c73f6d2b353c8", - "ciphertext": "0701becd2e9d10e3eed586491b3e0ecedba89407ae2151787c5117b55707d6b8a0754f4dc937e30ebdf7cafbd3769d6585d7991b1a6bd31e8bddb1adec" - }, - { - "kid": 7, - "ctr": 2, - "header": "0702", - "nonce": "77fbf5f1d82c73f6d2b353cb", - "ciphertext": "070298508be6b16d034f15b504ced45a86d1bb43ed7cd3a62bf25557d1b082b04e8e6ba6fe76160835dd8953e1be9640c988627ea447127ae4c103eabd" - }, - { - "kid": 15, - "ctr": 170, - "header": "080faa", - "nonce": "77fbf5f1d82c73f6d2b35363", - "ciphertext": "080faae7eec4b0556ddfb8068998351cd670ce95f0ce9cd4c6dca2eeee73fb14d20a0d0fd487337ed43fa7f98dad0995b8b870325aa35a105af9b1004b22" - }, - { - "kid": 511, - "ctr": 170, - "header": "0901ffaa", - "nonce": "77fbf5f1d82c73f6d2b35363", - "ciphertext": "0901ffaae7eec4b0556ddfb8068998351cd670ce95f0ce9cd4c6dca2eeee73fb14d20a0d0fd487337ed43fa7f98dad0995b8b870325aa3437cce05a6e67ee8" - }, - { - "kid": 511, - "ctr": 43690, - "header": "1901ffaaaa", - "nonce": "77fbf5f1d82c73f6d2b3f963", - "ciphertext": "1901ffaaaa8c1789aa0abcd6abc27006aae4df5cba4ba07f8113080e9726baacd16c18539974a6204a36b9dc3dcd36ed9ab48e590d95d4adfb4290f4cb1ba184" - }, - { - "kid": 72057594037927935, - "ctr": 72057594037927935, - "header": "6effffffffffffffffffffffffffff", - "nonce": "77fbf5f1d8d38c092d4cac36", - "ciphertext": "6effffffffffffffffffffffffffffa9bc6c7edde0fdfd13255a5b145c5ce84db8f8960858eb998b8ea8f3e770160150813c5806441b64251bdd2be9e8cec1386b6f8e3b1982bcd16c84" - } - ] - }, - { - "cipher_suite": 3, - "base_key": "303132333435363738393a3b3c3d3e3f", - "key": "2ea2e8163ff56c0613e6fa9f20a213da", - "salt": "a80478b3f6fba19983d540d5", - "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e", - "encryptions": [ - { - "kid": 7, - "ctr": 0, - "header": "0700", - "nonce": "a80478b3f6fba19983d540d5", - "ciphertext": "07000e426255e47ed70dd7d15d69d759bf459032ca15f5e8b2a91e7d348aa7c186d403f620801c495b1717a35097411aa97cbb1406afd9f4e5215b46e4a39dc40c27fd6bc7" - }, - { - "kid": 7, - "ctr": 1, - "header": "0701", - "nonce": "a80478b3f6fba19983d540d4", - "ciphertext": "070103bbafa34ada8a6b9f2066bc34a1959d87384c9f4b1ce34fed58e938bde143393910b1aeb55b48d91d5b0db3ea67e3d0e02b84e4cf8ecf81f8386f86cda48fcd754191" - }, - { - "kid": 7, - "ctr": 2, - "header": "0702", - "nonce": "a80478b3f6fba19983d540d7", - "ciphertext": "070258d58adebd8bf6f3cc0c1fcacf34ba4d7a763b2683fe302a57f1be7f2a274bf81b2236995fec1203cadb146cd402e1c52d5e6aceaa5252822d25acd0ce4ba14e31fa24" - }, - { - "kid": 15, - "ctr": 170, - "header": "080faa", - "nonce": "a80478b3f6fba19983d5407f", - "ciphertext": "080faad0b1743bf5248f90869c9456366d55724d16bbe08060875815565e90b114f9ccbdba192422b33848a1ae1e3bd266a001b2f5bb64c0f1216bba82ab24b1ebd677c2ca29" - }, - { - "kid": 511, - "ctr": 170, - "header": "0901ffaa", - "nonce": "a80478b3f6fba19983d5407f", - "ciphertext": "0901ffaad0b1743bf5248f90869c9456366d55724d16bbe08060875815565e90b114f9ccbdba192422b33848a1ae1e3bd266a001b2f5bb8c718170432b6f922c1f0fb307514a0e" - }, - { - "kid": 511, - "ctr": 43690, - "header": "1901ffaaaa", - "nonce": "a80478b3f6fba19983d5ea7f", - "ciphertext": "1901ffaaaa9de65e21e4f1ca2247b87943c03c5cb7b182090e93d508dcfb76e08174c6397356e682d2eaddabc0b3c1018d2c13c3570f61c185789dff3cb4469cf471ca71ceb025a5" - }, - { - "kid": 72057594037927935, - "ctr": 72057594037927935, - "header": "6effffffffffffffffffffffffffff", - "nonce": "a80478b3f6045e667c2abf2a", - "ciphertext": "6effffffffffffffffffffffffffff09981bdcdad80e380b6f74cf6afdbce946839bedadd57578bfcd809dbcea535546cc24660613d2761adea852155785011e633522450f95fd9f8ccc96fa3de9a247cfd3" - } - ] - }, - { - "cipher_suite": 4, - "base_key": "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", - "key": "436774b0b5ae45633d96547f8f3cb06c8e6628eff2e4255b5c4d77e721aa3355", - "salt": "31ed26f90a072e6aee646298", - "plaintext": "46726f6d2068656176656e6c79206861726d6f6e79202f2f205468697320756e6976657273616c206672616d6520626567616e", - "encryptions": [ - { - "kid": 7, - "ctr": 0, - "header": "0700", - "nonce": "31ed26f90a072e6aee646298", - "ciphertext": "0700f3e297c1e95207710bd31ccc4ba396fbef7b257440bde638ff0f3c8911540136df61b26220249d6c432c245ae8d55ef45bfccf3afe18dd36d64d8e341653e1a0f10be2" - }, - { - "kid": 7, - "ctr": 1, - "header": "0701", - "nonce": "31ed26f90a072e6aee646299", - "ciphertext": "070193268b0bf030071bff443bb6b4471bdfb1cc81bc9625f4697b0336ff4665d15f152f02169448d8a967fb06359a87d2145398de044ee92acfcc27b7a98f38712b60c28c" - }, - { - "kid": 7, - "ctr": 2, - "header": "0702", - "nonce": "31ed26f90a072e6aee64629a", - "ciphertext": "0702649691ba27c4c01a41280fba4657c03fa7fe21c8f5c862e9094227c3ca3ec0d9468b1a2cb060ff0978f25a24e6b106f5a6e10534b69d975605f31534caea88b33b455a" - }, - { - "kid": 15, - "ctr": 170, - "header": "080faa", - "nonce": "31ed26f90a072e6aee646232", - "ciphertext": "080faa2858c10b5ddd231c1f26819490521678603a050448d563c503b1fd890d02ead01d754f074ecb6f32da9b2f3859f380b4f47d4ed539d6103e61580a82c014b28eb48b4a" - }, - { - "kid": 511, - "ctr": 170, - "header": "0901ffaa", - "nonce": "31ed26f90a072e6aee646232", - "ciphertext": "0901ffaa2858c10b5ddd231c1f26819490521678603a050448d563c503b1fd890d02ead01d754f074ecb6f32da9b2f3859f380b4f47d4e32c565b3b3fa20fc7ecff21a1cee3eec" - }, - { - "kid": 511, - "ctr": 43690, - "header": "1901ffaaaa", - "nonce": "31ed26f90a072e6aee64c832", - "ciphertext": "1901ffaaaad9bc6a258a07d210a814d545eca70321c0e87498ada6e5c708b7ead162ffcf4fbaba1eb82650590a87122b4d95fe36bd88b278994922fe5c09f14c728521333297f84f" - }, - { - "kid": 72057594037927935, - "ctr": 72057594037927935, - "header": "6effffffffffffffffffffffffffff", - "nonce": "31ed26f90af8d195119b9d67", - "ciphertext": "6effffffffffffffffffffffffffffaf480d4779ce0c02b5137ee6a61e026c04ac999cb0c97319feceeb258d58df23bce14979e5c67a431777b34498062e72f939ca4acb471bad80259bb44f78a152487e67" - } - ] - } -] +{ + "header": [ + { + "kid": 0, + "ctr": 0, + "encoded": "0000" + }, + { + "kid": 0, + "ctr": 1, + "encoded": "0001" + }, + { + "kid": 0, + "ctr": 255, + "encoded": "00ff" + }, + { + "kid": 0, + "ctr": 256, + "encoded": "100100" + }, + { + "kid": 0, + "ctr": 65535, + "encoded": "10ffff" + }, + { + "kid": 0, + "ctr": 65536, + "encoded": "20010000" + }, + { + "kid": 0, + "ctr": 16777215, + "encoded": "20ffffff" + }, + { + "kid": 0, + "ctr": 16777216, + "encoded": "3001000000" + }, + { + "kid": 0, + "ctr": 4294967295, + "encoded": "30ffffffff" + }, + { + "kid": 0, + "ctr": 4294967296, + "encoded": "400100000000" + }, + { + "kid": 0, + "ctr": 1099511627775, + "encoded": "40ffffffffff" + }, + { + "kid": 0, + "ctr": 1099511627776, + "encoded": "50010000000000" + }, + { + "kid": 0, + "ctr": 281474976710655, + "encoded": "50ffffffffffff" + }, + { + "kid": 0, + "ctr": 281474976710656, + "encoded": "6001000000000000" + }, + { + "kid": 0, + "ctr": 72057594037927935, + "encoded": "60ffffffffffffff" + }, + { + "kid": 0, + "ctr": 72057594037927936, + "encoded": "700100000000000000" + }, + { + "kid": 0, + "ctr": 18446744073709551615, + "encoded": "70ffffffffffffffff" + }, + { + "kid": 1, + "ctr": 0, + "encoded": "0100" + }, + { + "kid": 1, + "ctr": 1, + "encoded": "0101" + }, + { + "kid": 1, + "ctr": 255, + "encoded": "01ff" + }, + { + "kid": 1, + "ctr": 256, + "encoded": "110100" + }, + { + "kid": 1, + "ctr": 65535, + "encoded": "11ffff" + }, + { + "kid": 1, + "ctr": 65536, + "encoded": "21010000" + }, + { + "kid": 1, + "ctr": 16777215, + "encoded": "21ffffff" + }, + { + "kid": 1, + "ctr": 16777216, + "encoded": "3101000000" + }, + { + "kid": 1, + "ctr": 4294967295, + "encoded": "31ffffffff" + }, + { + "kid": 1, + "ctr": 4294967296, + "encoded": "410100000000" + }, + { + "kid": 1, + "ctr": 1099511627775, + "encoded": "41ffffffffff" + }, + { + "kid": 1, + "ctr": 1099511627776, + "encoded": "51010000000000" + }, + { + "kid": 1, + "ctr": 281474976710655, + "encoded": "51ffffffffffff" + }, + { + "kid": 1, + "ctr": 281474976710656, + "encoded": "6101000000000000" + }, + { + "kid": 1, + "ctr": 72057594037927935, + "encoded": "61ffffffffffffff" + }, + { + "kid": 1, + "ctr": 72057594037927936, + "encoded": "710100000000000000" + }, + { + "kid": 1, + "ctr": 18446744073709551615, + "encoded": "71ffffffffffffffff" + }, + { + "kid": 255, + "ctr": 0, + "encoded": "08ff00" + }, + { + "kid": 255, + "ctr": 1, + "encoded": "08ff01" + }, + { + "kid": 255, + "ctr": 255, + "encoded": "08ffff" + }, + { + "kid": 255, + "ctr": 256, + "encoded": "18ff0100" + }, + { + "kid": 255, + "ctr": 65535, + "encoded": "18ffffff" + }, + { + "kid": 255, + "ctr": 65536, + "encoded": "28ff010000" + }, + { + "kid": 255, + "ctr": 16777215, + "encoded": "28ffffffff" + }, + { + "kid": 255, + "ctr": 16777216, + "encoded": "38ff01000000" + }, + { + "kid": 255, + "ctr": 4294967295, + "encoded": "38ffffffffff" + }, + { + "kid": 255, + "ctr": 4294967296, + "encoded": "48ff0100000000" + }, + { + "kid": 255, + "ctr": 1099511627775, + "encoded": "48ffffffffffff" + }, + { + "kid": 255, + "ctr": 1099511627776, + "encoded": "58ff010000000000" + }, + { + "kid": 255, + "ctr": 281474976710655, + "encoded": "58ffffffffffffff" + }, + { + "kid": 255, + "ctr": 281474976710656, + "encoded": "68ff01000000000000" + }, + { + "kid": 255, + "ctr": 72057594037927935, + "encoded": "68ffffffffffffffff" + }, + { + "kid": 255, + "ctr": 72057594037927936, + "encoded": "78ff0100000000000000" + }, + { + "kid": 255, + "ctr": 18446744073709551615, + "encoded": "78ffffffffffffffffff" + }, + { + "kid": 256, + "ctr": 0, + "encoded": "09010000" + }, + { + "kid": 256, + "ctr": 1, + "encoded": "09010001" + }, + { + "kid": 256, + "ctr": 255, + "encoded": "090100ff" + }, + { + "kid": 256, + "ctr": 256, + "encoded": "1901000100" + }, + { + "kid": 256, + "ctr": 65535, + "encoded": "190100ffff" + }, + { + "kid": 256, + "ctr": 65536, + "encoded": "290100010000" + }, + { + "kid": 256, + "ctr": 16777215, + "encoded": "290100ffffff" + }, + { + "kid": 256, + "ctr": 16777216, + "encoded": "39010001000000" + }, + { + "kid": 256, + "ctr": 4294967295, + "encoded": "390100ffffffff" + }, + { + "kid": 256, + "ctr": 4294967296, + "encoded": "4901000100000000" + }, + { + "kid": 256, + "ctr": 1099511627775, + "encoded": "490100ffffffffff" + }, + { + "kid": 256, + "ctr": 1099511627776, + "encoded": "590100010000000000" + }, + { + "kid": 256, + "ctr": 281474976710655, + "encoded": "590100ffffffffffff" + }, + { + "kid": 256, + "ctr": 281474976710656, + "encoded": "69010001000000000000" + }, + { + "kid": 256, + "ctr": 72057594037927935, + "encoded": "690100ffffffffffffff" + }, + { + "kid": 256, + "ctr": 72057594037927936, + "encoded": "7901000100000000000000" + }, + { + "kid": 256, + "ctr": 18446744073709551615, + "encoded": "790100ffffffffffffffff" + }, + { + "kid": 65535, + "ctr": 0, + "encoded": "09ffff00" + }, + { + "kid": 65535, + "ctr": 1, + "encoded": "09ffff01" + }, + { + "kid": 65535, + "ctr": 255, + "encoded": "09ffffff" + }, + { + "kid": 65535, + "ctr": 256, + "encoded": "19ffff0100" + }, + { + "kid": 65535, + "ctr": 65535, + "encoded": "19ffffffff" + }, + { + "kid": 65535, + "ctr": 65536, + "encoded": "29ffff010000" + }, + { + "kid": 65535, + "ctr": 16777215, + "encoded": "29ffffffffff" + }, + { + "kid": 65535, + "ctr": 16777216, + "encoded": "39ffff01000000" + }, + { + "kid": 65535, + "ctr": 4294967295, + "encoded": "39ffffffffffff" + }, + { + "kid": 65535, + "ctr": 4294967296, + "encoded": "49ffff0100000000" + }, + { + "kid": 65535, + "ctr": 1099511627775, + "encoded": "49ffffffffffffff" + }, + { + "kid": 65535, + "ctr": 1099511627776, + "encoded": "59ffff010000000000" + }, + { + "kid": 65535, + "ctr": 281474976710655, + "encoded": "59ffffffffffffffff" + }, + { + "kid": 65535, + "ctr": 281474976710656, + "encoded": "69ffff01000000000000" + }, + { + "kid": 65535, + "ctr": 72057594037927935, + "encoded": "69ffffffffffffffffff" + }, + { + "kid": 65535, + "ctr": 72057594037927936, + "encoded": "79ffff0100000000000000" + }, + { + "kid": 65535, + "ctr": 18446744073709551615, + "encoded": "79ffffffffffffffffffff" + }, + { + "kid": 65536, + "ctr": 0, + "encoded": "0a01000000" + }, + { + "kid": 65536, + "ctr": 1, + "encoded": "0a01000001" + }, + { + "kid": 65536, + "ctr": 255, + "encoded": "0a010000ff" + }, + { + "kid": 65536, + "ctr": 256, + "encoded": "1a0100000100" + }, + { + "kid": 65536, + "ctr": 65535, + "encoded": "1a010000ffff" + }, + { + "kid": 65536, + "ctr": 65536, + "encoded": "2a010000010000" + }, + { + "kid": 65536, + "ctr": 16777215, + "encoded": "2a010000ffffff" + }, + { + "kid": 65536, + "ctr": 16777216, + "encoded": "3a01000001000000" + }, + { + "kid": 65536, + "ctr": 4294967295, + "encoded": "3a010000ffffffff" + }, + { + "kid": 65536, + "ctr": 4294967296, + "encoded": "4a0100000100000000" + }, + { + "kid": 65536, + "ctr": 1099511627775, + "encoded": "4a010000ffffffffff" + }, + { + "kid": 65536, + "ctr": 1099511627776, + "encoded": "5a010000010000000000" + }, + { + "kid": 65536, + "ctr": 281474976710655, + "encoded": "5a010000ffffffffffff" + }, + { + "kid": 65536, + "ctr": 281474976710656, + "encoded": "6a01000001000000000000" + }, + { + "kid": 65536, + "ctr": 72057594037927935, + "encoded": "6a010000ffffffffffffff" + }, + { + "kid": 65536, + "ctr": 72057594037927936, + "encoded": "7a0100000100000000000000" + }, + { + "kid": 65536, + "ctr": 18446744073709551615, + "encoded": "7a010000ffffffffffffffff" + }, + { + "kid": 16777215, + "ctr": 0, + "encoded": "0affffff00" + }, + { + "kid": 16777215, + "ctr": 1, + "encoded": "0affffff01" + }, + { + "kid": 16777215, + "ctr": 255, + "encoded": "0affffffff" + }, + { + "kid": 16777215, + "ctr": 256, + "encoded": "1affffff0100" + }, + { + "kid": 16777215, + "ctr": 65535, + "encoded": "1affffffffff" + }, + { + "kid": 16777215, + "ctr": 65536, + "encoded": "2affffff010000" + }, + { + "kid": 16777215, + "ctr": 16777215, + "encoded": "2affffffffffff" + }, + { + "kid": 16777215, + "ctr": 16777216, + "encoded": "3affffff01000000" + }, + { + "kid": 16777215, + "ctr": 4294967295, + "encoded": "3affffffffffffff" + }, + { + "kid": 16777215, + "ctr": 4294967296, + "encoded": "4affffff0100000000" + }, + { + "kid": 16777215, + "ctr": 1099511627775, + "encoded": "4affffffffffffffff" + }, + { + "kid": 16777215, + "ctr": 1099511627776, + "encoded": "5affffff010000000000" + }, + { + "kid": 16777215, + "ctr": 281474976710655, + "encoded": "5affffffffffffffffff" + }, + { + "kid": 16777215, + "ctr": 281474976710656, + "encoded": "6affffff01000000000000" + }, + { + "kid": 16777215, + "ctr": 72057594037927935, + "encoded": "6affffffffffffffffffff" + }, + { + "kid": 16777215, + "ctr": 72057594037927936, + "encoded": "7affffff0100000000000000" + }, + { + "kid": 16777215, + "ctr": 18446744073709551615, + "encoded": "7affffffffffffffffffffff" + }, + { + "kid": 16777216, + "ctr": 0, + "encoded": "0b0100000000" + }, + { + "kid": 16777216, + "ctr": 1, + "encoded": "0b0100000001" + }, + { + "kid": 16777216, + "ctr": 255, + "encoded": "0b01000000ff" + }, + { + "kid": 16777216, + "ctr": 256, + "encoded": "1b010000000100" + }, + { + "kid": 16777216, + "ctr": 65535, + "encoded": "1b01000000ffff" + }, + { + "kid": 16777216, + "ctr": 65536, + "encoded": "2b01000000010000" + }, + { + "kid": 16777216, + "ctr": 16777215, + "encoded": "2b01000000ffffff" + }, + { + "kid": 16777216, + "ctr": 16777216, + "encoded": "3b0100000001000000" + }, + { + "kid": 16777216, + "ctr": 4294967295, + "encoded": "3b01000000ffffffff" + }, + { + "kid": 16777216, + "ctr": 4294967296, + "encoded": "4b010000000100000000" + }, + { + "kid": 16777216, + "ctr": 1099511627775, + "encoded": "4b01000000ffffffffff" + }, + { + "kid": 16777216, + "ctr": 1099511627776, + "encoded": "5b01000000010000000000" + }, + { + "kid": 16777216, + "ctr": 281474976710655, + "encoded": "5b01000000ffffffffffff" + }, + { + "kid": 16777216, + "ctr": 281474976710656, + "encoded": "6b0100000001000000000000" + }, + { + "kid": 16777216, + "ctr": 72057594037927935, + "encoded": "6b01000000ffffffffffffff" + }, + { + "kid": 16777216, + "ctr": 72057594037927936, + "encoded": "7b010000000100000000000000" + }, + { + "kid": 16777216, + "ctr": 18446744073709551615, + "encoded": "7b01000000ffffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 0, + "encoded": "0bffffffff00" + }, + { + "kid": 4294967295, + "ctr": 1, + "encoded": "0bffffffff01" + }, + { + "kid": 4294967295, + "ctr": 255, + "encoded": "0bffffffffff" + }, + { + "kid": 4294967295, + "ctr": 256, + "encoded": "1bffffffff0100" + }, + { + "kid": 4294967295, + "ctr": 65535, + "encoded": "1bffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 65536, + "encoded": "2bffffffff010000" + }, + { + "kid": 4294967295, + "ctr": 16777215, + "encoded": "2bffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 16777216, + "encoded": "3bffffffff01000000" + }, + { + "kid": 4294967295, + "ctr": 4294967295, + "encoded": "3bffffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 4294967296, + "encoded": "4bffffffff0100000000" + }, + { + "kid": 4294967295, + "ctr": 1099511627775, + "encoded": "4bffffffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 1099511627776, + "encoded": "5bffffffff010000000000" + }, + { + "kid": 4294967295, + "ctr": 281474976710655, + "encoded": "5bffffffffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 281474976710656, + "encoded": "6bffffffff01000000000000" + }, + { + "kid": 4294967295, + "ctr": 72057594037927935, + "encoded": "6bffffffffffffffffffffff" + }, + { + "kid": 4294967295, + "ctr": 72057594037927936, + "encoded": "7bffffffff0100000000000000" + }, + { + "kid": 4294967295, + "ctr": 18446744073709551615, + "encoded": "7bffffffffffffffffffffffff" + }, + { + "kid": 4294967296, + "ctr": 0, + "encoded": "0c010000000000" + }, + { + "kid": 4294967296, + "ctr": 1, + "encoded": "0c010000000001" + }, + { + "kid": 4294967296, + "ctr": 255, + "encoded": "0c0100000000ff" + }, + { + "kid": 4294967296, + "ctr": 256, + "encoded": "1c01000000000100" + }, + { + "kid": 4294967296, + "ctr": 65535, + "encoded": "1c0100000000ffff" + }, + { + "kid": 4294967296, + "ctr": 65536, + "encoded": "2c0100000000010000" + }, + { + "kid": 4294967296, + "ctr": 16777215, + "encoded": "2c0100000000ffffff" + }, + { + "kid": 4294967296, + "ctr": 16777216, + "encoded": "3c010000000001000000" + }, + { + "kid": 4294967296, + "ctr": 4294967295, + "encoded": "3c0100000000ffffffff" + }, + { + "kid": 4294967296, + "ctr": 4294967296, + "encoded": "4c01000000000100000000" + }, + { + "kid": 4294967296, + "ctr": 1099511627775, + "encoded": "4c0100000000ffffffffff" + }, + { + "kid": 4294967296, + "ctr": 1099511627776, + "encoded": "5c0100000000010000000000" + }, + { + "kid": 4294967296, + "ctr": 281474976710655, + "encoded": "5c0100000000ffffffffffff" + }, + { + "kid": 4294967296, + "ctr": 281474976710656, + "encoded": "6c010000000001000000000000" + }, + { + "kid": 4294967296, + "ctr": 72057594037927935, + "encoded": "6c0100000000ffffffffffffff" + }, + { + "kid": 4294967296, + "ctr": 72057594037927936, + "encoded": "7c01000000000100000000000000" + }, + { + "kid": 4294967296, + "ctr": 18446744073709551615, + "encoded": "7c0100000000ffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 0, + "encoded": "0cffffffffff00" + }, + { + "kid": 1099511627775, + "ctr": 1, + "encoded": "0cffffffffff01" + }, + { + "kid": 1099511627775, + "ctr": 255, + "encoded": "0cffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 256, + "encoded": "1cffffffffff0100" + }, + { + "kid": 1099511627775, + "ctr": 65535, + "encoded": "1cffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 65536, + "encoded": "2cffffffffff010000" + }, + { + "kid": 1099511627775, + "ctr": 16777215, + "encoded": "2cffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 16777216, + "encoded": "3cffffffffff01000000" + }, + { + "kid": 1099511627775, + "ctr": 4294967295, + "encoded": "3cffffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 4294967296, + "encoded": "4cffffffffff0100000000" + }, + { + "kid": 1099511627775, + "ctr": 1099511627775, + "encoded": "4cffffffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 1099511627776, + "encoded": "5cffffffffff010000000000" + }, + { + "kid": 1099511627775, + "ctr": 281474976710655, + "encoded": "5cffffffffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 281474976710656, + "encoded": "6cffffffffff01000000000000" + }, + { + "kid": 1099511627775, + "ctr": 72057594037927935, + "encoded": "6cffffffffffffffffffffffff" + }, + { + "kid": 1099511627775, + "ctr": 72057594037927936, + "encoded": "7cffffffffff0100000000000000" + }, + { + "kid": 1099511627775, + "ctr": 18446744073709551615, + "encoded": "7cffffffffffffffffffffffffff" + }, + { + "kid": 1099511627776, + "ctr": 0, + "encoded": "0d01000000000000" + }, + { + "kid": 1099511627776, + "ctr": 1, + "encoded": "0d01000000000001" + }, + { + "kid": 1099511627776, + "ctr": 255, + "encoded": "0d010000000000ff" + }, + { + "kid": 1099511627776, + "ctr": 256, + "encoded": "1d0100000000000100" + }, + { + "kid": 1099511627776, + "ctr": 65535, + "encoded": "1d010000000000ffff" + }, + { + "kid": 1099511627776, + "ctr": 65536, + "encoded": "2d010000000000010000" + }, + { + "kid": 1099511627776, + "ctr": 16777215, + "encoded": "2d010000000000ffffff" + }, + { + "kid": 1099511627776, + "ctr": 16777216, + "encoded": "3d01000000000001000000" + }, + { + "kid": 1099511627776, + "ctr": 4294967295, + "encoded": "3d010000000000ffffffff" + }, + { + "kid": 1099511627776, + "ctr": 4294967296, + "encoded": "4d0100000000000100000000" + }, + { + "kid": 1099511627776, + "ctr": 1099511627775, + "encoded": "4d010000000000ffffffffff" + }, + { + "kid": 1099511627776, + "ctr": 1099511627776, + "encoded": "5d010000000000010000000000" + }, + { + "kid": 1099511627776, + "ctr": 281474976710655, + "encoded": "5d010000000000ffffffffffff" + }, + { + "kid": 1099511627776, + "ctr": 281474976710656, + "encoded": "6d01000000000001000000000000" + }, + { + "kid": 1099511627776, + "ctr": 72057594037927935, + "encoded": "6d010000000000ffffffffffffff" + }, + { + "kid": 1099511627776, + "ctr": 72057594037927936, + "encoded": "7d0100000000000100000000000000" + }, + { + "kid": 1099511627776, + "ctr": 18446744073709551615, + "encoded": "7d010000000000ffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 0, + "encoded": "0dffffffffffff00" + }, + { + "kid": 281474976710655, + "ctr": 1, + "encoded": "0dffffffffffff01" + }, + { + "kid": 281474976710655, + "ctr": 255, + "encoded": "0dffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 256, + "encoded": "1dffffffffffff0100" + }, + { + "kid": 281474976710655, + "ctr": 65535, + "encoded": "1dffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 65536, + "encoded": "2dffffffffffff010000" + }, + { + "kid": 281474976710655, + "ctr": 16777215, + "encoded": "2dffffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 16777216, + "encoded": "3dffffffffffff01000000" + }, + { + "kid": 281474976710655, + "ctr": 4294967295, + "encoded": "3dffffffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 4294967296, + "encoded": "4dffffffffffff0100000000" + }, + { + "kid": 281474976710655, + "ctr": 1099511627775, + "encoded": "4dffffffffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 1099511627776, + "encoded": "5dffffffffffff010000000000" + }, + { + "kid": 281474976710655, + "ctr": 281474976710655, + "encoded": "5dffffffffffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 281474976710656, + "encoded": "6dffffffffffff01000000000000" + }, + { + "kid": 281474976710655, + "ctr": 72057594037927935, + "encoded": "6dffffffffffffffffffffffffff" + }, + { + "kid": 281474976710655, + "ctr": 72057594037927936, + "encoded": "7dffffffffffff0100000000000000" + }, + { + "kid": 281474976710655, + "ctr": 18446744073709551615, + "encoded": "7dffffffffffffffffffffffffffff" + }, + { + "kid": 281474976710656, + "ctr": 0, + "encoded": "0e0100000000000000" + }, + { + "kid": 281474976710656, + "ctr": 1, + "encoded": "0e0100000000000001" + }, + { + "kid": 281474976710656, + "ctr": 255, + "encoded": "0e01000000000000ff" + }, + { + "kid": 281474976710656, + "ctr": 256, + "encoded": "1e010000000000000100" + }, + { + "kid": 281474976710656, + "ctr": 65535, + "encoded": "1e01000000000000ffff" + }, + { + "kid": 281474976710656, + "ctr": 65536, + "encoded": "2e01000000000000010000" + }, + { + "kid": 281474976710656, + "ctr": 16777215, + "encoded": "2e01000000000000ffffff" + }, + { + "kid": 281474976710656, + "ctr": 16777216, + "encoded": "3e0100000000000001000000" + }, + { + "kid": 281474976710656, + "ctr": 4294967295, + "encoded": "3e01000000000000ffffffff" + }, + { + "kid": 281474976710656, + "ctr": 4294967296, + "encoded": "4e010000000000000100000000" + }, + { + "kid": 281474976710656, + "ctr": 1099511627775, + "encoded": "4e01000000000000ffffffffff" + }, + { + "kid": 281474976710656, + "ctr": 1099511627776, + "encoded": "5e01000000000000010000000000" + }, + { + "kid": 281474976710656, + "ctr": 281474976710655, + "encoded": "5e01000000000000ffffffffffff" + }, + { + "kid": 281474976710656, + "ctr": 281474976710656, + "encoded": "6e0100000000000001000000000000" + }, + { + "kid": 281474976710656, + "ctr": 72057594037927935, + "encoded": "6e01000000000000ffffffffffffff" + }, + { + "kid": 281474976710656, + "ctr": 72057594037927936, + "encoded": "7e010000000000000100000000000000" + }, + { + "kid": 281474976710656, + "ctr": 18446744073709551615, + "encoded": "7e01000000000000ffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 0, + "encoded": "0effffffffffffff00" + }, + { + "kid": 72057594037927935, + "ctr": 1, + "encoded": "0effffffffffffff01" + }, + { + "kid": 72057594037927935, + "ctr": 255, + "encoded": "0effffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 256, + "encoded": "1effffffffffffff0100" + }, + { + "kid": 72057594037927935, + "ctr": 65535, + "encoded": "1effffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 65536, + "encoded": "2effffffffffffff010000" + }, + { + "kid": 72057594037927935, + "ctr": 16777215, + "encoded": "2effffffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 16777216, + "encoded": "3effffffffffffff01000000" + }, + { + "kid": 72057594037927935, + "ctr": 4294967295, + "encoded": "3effffffffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 4294967296, + "encoded": "4effffffffffffff0100000000" + }, + { + "kid": 72057594037927935, + "ctr": 1099511627775, + "encoded": "4effffffffffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 1099511627776, + "encoded": "5effffffffffffff010000000000" + }, + { + "kid": 72057594037927935, + "ctr": 281474976710655, + "encoded": "5effffffffffffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 281474976710656, + "encoded": "6effffffffffffff01000000000000" + }, + { + "kid": 72057594037927935, + "ctr": 72057594037927935, + "encoded": "6effffffffffffffffffffffffffff" + }, + { + "kid": 72057594037927935, + "ctr": 72057594037927936, + "encoded": "7effffffffffffff0100000000000000" + }, + { + "kid": 72057594037927935, + "ctr": 18446744073709551615, + "encoded": "7effffffffffffffffffffffffffffff" + }, + { + "kid": 72057594037927936, + "ctr": 0, + "encoded": "0f010000000000000000" + }, + { + "kid": 72057594037927936, + "ctr": 1, + "encoded": "0f010000000000000001" + }, + { + "kid": 72057594037927936, + "ctr": 255, + "encoded": "0f0100000000000000ff" + }, + { + "kid": 72057594037927936, + "ctr": 256, + "encoded": "1f01000000000000000100" + }, + { + "kid": 72057594037927936, + "ctr": 65535, + "encoded": "1f0100000000000000ffff" + }, + { + "kid": 72057594037927936, + "ctr": 65536, + "encoded": "2f0100000000000000010000" + }, + { + "kid": 72057594037927936, + "ctr": 16777215, + "encoded": "2f0100000000000000ffffff" + }, + { + "kid": 72057594037927936, + "ctr": 16777216, + "encoded": "3f010000000000000001000000" + }, + { + "kid": 72057594037927936, + "ctr": 4294967295, + "encoded": "3f0100000000000000ffffffff" + }, + { + "kid": 72057594037927936, + "ctr": 4294967296, + "encoded": "4f01000000000000000100000000" + }, + { + "kid": 72057594037927936, + "ctr": 1099511627775, + "encoded": "4f0100000000000000ffffffffff" + }, + { + "kid": 72057594037927936, + "ctr": 1099511627776, + "encoded": "5f0100000000000000010000000000" + }, + { + "kid": 72057594037927936, + "ctr": 281474976710655, + "encoded": "5f0100000000000000ffffffffffff" + }, + { + "kid": 72057594037927936, + "ctr": 281474976710656, + "encoded": "6f010000000000000001000000000000" + }, + { + "kid": 72057594037927936, + "ctr": 72057594037927935, + "encoded": "6f0100000000000000ffffffffffffff" + }, + { + "kid": 72057594037927936, + "ctr": 72057594037927936, + "encoded": "7f01000000000000000100000000000000" + }, + { + "kid": 72057594037927936, + "ctr": 18446744073709551615, + "encoded": "7f0100000000000000ffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 0, + "encoded": "0fffffffffffffffff00" + }, + { + "kid": 18446744073709551615, + "ctr": 1, + "encoded": "0fffffffffffffffff01" + }, + { + "kid": 18446744073709551615, + "ctr": 255, + "encoded": "0fffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 256, + "encoded": "1fffffffffffffffff0100" + }, + { + "kid": 18446744073709551615, + "ctr": 65535, + "encoded": "1fffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 65536, + "encoded": "2fffffffffffffffff010000" + }, + { + "kid": 18446744073709551615, + "ctr": 16777215, + "encoded": "2fffffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 16777216, + "encoded": "3fffffffffffffffff01000000" + }, + { + "kid": 18446744073709551615, + "ctr": 4294967295, + "encoded": "3fffffffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 4294967296, + "encoded": "4fffffffffffffffff0100000000" + }, + { + "kid": 18446744073709551615, + "ctr": 1099511627775, + "encoded": "4fffffffffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 1099511627776, + "encoded": "5fffffffffffffffff010000000000" + }, + { + "kid": 18446744073709551615, + "ctr": 281474976710655, + "encoded": "5fffffffffffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 281474976710656, + "encoded": "6fffffffffffffffff01000000000000" + }, + { + "kid": 18446744073709551615, + "ctr": 72057594037927935, + "encoded": "6fffffffffffffffffffffffffffffff" + }, + { + "kid": 18446744073709551615, + "ctr": 72057594037927936, + "encoded": "7fffffffffffffffff0100000000000000" + }, + { + "kid": 18446744073709551615, + "ctr": 18446744073709551615, + "encoded": "7fffffffffffffffffffffffffffffffff" + } + ], + "aes_ctr_hmac": [ + { + "cipher_suite": 1, + "key": "000102030405060708090a0b0c0d0e0f", + "aead_label": "534672616d6520312e302041455320435452204145414420000000000000000a", + "aead_secret": "fda0fef7af62639ae1c6440f430395f54623f9a49db659201312ed6d9999a580", + "enc_key": "d6a61ca11fe8397b24954cda8b9543cf", + "auth_key": "0a43277c91120b7c7b6584bede06fcdfe0d07f9d1c9f15fcf0cad50aaecdd585", + "nonce": "101112131415161718191a1b", + "aad": "4945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "1075c7114e10c12f20a709450ef8a891e9f070d4fae7b01f558599c929fdfd" + }, + { + "cipher_suite": 2, + "key": "000102030405060708090a0b0c0d0e0f", + "aead_label": "534672616d6520312e3020414553204354522041454144200000000000000008", + "aead_secret": "a0d71a69b2033a5a246eefbed19d95aee712a7639a752e5ad3a2b44c9f331caa", + "enc_key": "0ef75d1dd74b81e4d2252e6daa7226da", + "auth_key": "5584d32db18ede79fe8071a334ff31eb2ca0249a7845a61965d2ec620a50c59e", + "nonce": "101112131415161718191a1b", + "aad": "4945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "f8551395579efc8dfdda575ed1a048f8b6cbf0e85653f0a514dea191e4" + }, + { + "cipher_suite": 3, + "key": "000102030405060708090a0b0c0d0e0f", + "aead_label": "534672616d6520312e3020414553204354522041454144200000000000000004", + "aead_secret": "ff69640f46d50930ce38bcf5aa5f6417a5bff98a991c79da06a0be460211dd36", + "enc_key": "96a673a94981bd85e71fcf05c79f2a01", + "auth_key": "bbf3b39da1eb8ed31fc5e0b26896a070f1a43e5ad3009b4c9d6c32e77ac68fce", + "nonce": "101112131415161718191a1b", + "aad": "4945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "d6455bdbe7b5e8cdda861a8e90835637c0f7990349ce9052e6" + } + ], + "sframe": [ + { + "cipher_suite": 1, + "kid": 291, + "ctr": 17767, + "base_key": "000102030405060708090a0b0c0d0e0f", + "sframe_label": "534672616d6520312e3020", + "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", + "sframe_key": "52cef96e29191912a6be442a9651c43a", + "sframe_salt": "9655c98fdad276683deb279c", + "metadata": "4945544620534672616d65205747", + "nonce": "9655c98fdad276683deb62fb", + "aad": "19012345674945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "1901234567b6a27b2d24f1f06d49cffe6c82af5a96e0d89443a7a93a8700f96fdda3e43c" + }, + { + "cipher_suite": 2, + "kid": 291, + "ctr": 17767, + "base_key": "000102030405060708090a0b0c0d0e0f", + "sframe_label": "534672616d6520312e3020", + "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", + "sframe_key": "52cef96e29191912a6be442a9651c43a", + "sframe_salt": "9655c98fdad276683deb279c", + "metadata": "4945544620534672616d65205747", + "nonce": "9655c98fdad276683deb62fb", + "aad": "19012345674945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "190123456728b1faac3515d5ca29f3db9c52f27789c5ec8386ff0b570853ebcf721c" + }, + { + "cipher_suite": 3, + "kid": 291, + "ctr": 17767, + "base_key": "000102030405060708090a0b0c0d0e0f", + "sframe_label": "534672616d6520312e3020", + "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", + "sframe_key": "52cef96e29191912a6be442a9651c43a", + "sframe_salt": "9655c98fdad276683deb279c", + "metadata": "4945544620534672616d65205747", + "nonce": "9655c98fdad276683deb62fb", + "aad": "19012345674945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "190123456754719dcfbe065e1606068cb6b6b5f1a9a371e633ff088485e7" + }, + { + "cipher_suite": 4, + "kid": 291, + "ctr": 17767, + "base_key": "000102030405060708090a0b0c0d0e0f", + "sframe_label": "534672616d6520312e3020", + "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", + "sframe_key": "52cef96e29191912a6be442a9651c43a", + "sframe_salt": "9655c98fdad276683deb279c", + "metadata": "4945544620534672616d65205747", + "nonce": "9655c98fdad276683deb62fb", + "aad": "19012345674945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "1901234567d4dfcd537dbd054dcf4bdab53bf451826843325838178391f63dc15b9475d6081b59c776a5" + }, + { + "cipher_suite": 5, + "kid": 291, + "ctr": 17767, + "base_key": "000102030405060708090a0b0c0d0e0f", + "sframe_label": "534672616d6520312e3020", + "sframe_secret": "0fc3ea6de6aac97a35f194cf9bed94d4b5230f1cb45a785c9fe5dce9c188938ab6ba005bc4c0a19181599e9d1bcf7b74aca48b60bf5e254e546d809313e083a3", + "sframe_key": "5f3f7c1b277d9cad86b906da39702c3fcdf720902817977ae99bd10f2e5ad56a", + "sframe_salt": "a653f558a8018877314fb8d9", + "metadata": "4945544620534672616d65205747", + "nonce": "a653f558a8018877314ffdbe", + "aad": "19012345674945544620534672616d65205747", + "pt": "64726166742d696574662d736672616d652d656e63", + "ct": "19012345672f55e5feb46d118576dc715566003f4becf5252149c839aea7dd5434bf8eceb8b4d59bbfb2" + } + ] +} From b8f7953a9fc4dfcf8c459142b17baccfb6107693 Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Fri, 1 Sep 2023 17:16:20 +0200 Subject: [PATCH 2/8] feat(crypto): update key derivation / tag computation to draft-03 With the newest draft now also the key id/auth tag length is used during the key derivation to create distinct salts. Also for AES CTR mode ciphers the tag length is also taken into account when computing the tag BREAKING CHANGE: The latest [changes in the draft](https://author-tools.ietf.org/diff?doc_1=draft-ietf-sframe-enc-01&doc_2=draft-ietf-sframe-enc-03) regarding the key derivation and tag computation, make theimplementation incompatible with previous versions --- Cargo.toml | 2 +- src/crypto/aead.rs | 5 +- src/crypto/cipher_suite.rs | 2 +- src/crypto/key_expansion.rs | 102 ++++++++++++++++++---------- src/crypto/openssl/aead.rs | 9 ++- src/crypto/openssl/key_expansion.rs | 52 +++++++++++--- src/crypto/ring/key_expansion.rs | 27 +++++--- src/header/basic_header.rs | 2 +- src/header/extended_header.rs | 2 +- src/header/mod.rs | 7 +- src/receiver.rs | 5 +- src/sender.rs | 69 ++----------------- src/test_vectors/mod.rs | 10 ++- 13 files changed, 154 insertions(+), 140 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bb408fb..2fae5b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ authors = [ "Richard Haehne ", ] -description = "pure rust implementation of SFrame draft-ietf-sframe-enc-01" +description = "pure rust implementation of SFrame draft-ietf-sframe-enc-03" repository = "https://github.com/goto-opensource/sframe-rs" documentation = "https://docs.rs/sframe/" readme = "README.md" diff --git a/src/crypto/aead.rs b/src/crypto/aead.rs index 051ecc7..abe7815 100644 --- a/src/crypto/aead.rs +++ b/src/crypto/aead.rs @@ -60,7 +60,8 @@ mod test { thread_rng().fill(data.as_mut_slice()); let header = Header::default(); let cipher_suite = CipherSuite::from(CipherSuiteVariant::AesGcm256Sha512); - let secret = Secret::expand_from(&cipher_suite, KEY_MATERIAL.as_bytes()).unwrap(); + let secret = + Secret::expand_from(&cipher_suite, KEY_MATERIAL.as_bytes(), KeyId::default()).unwrap(); let _tag = cipher_suite .encrypt( @@ -138,7 +139,7 @@ mod test { fn prepare_secret(cipher_suite: &CipherSuite, test_vec: &SframeTest) -> Secret { if cipher_suite.is_ctr_mode() { // the test vectors do not provide the auth key, so we have to expand here - Secret::expand_from(cipher_suite, &test_vec.key_material).unwrap() + Secret::expand_from(cipher_suite, &test_vec.key_material, test_vec.key_id).unwrap() } else { Secret { key: test_vec.sframe_key.clone(), diff --git a/src/crypto/cipher_suite.rs b/src/crypto/cipher_suite.rs index 70cab86..0a373a8 100644 --- a/src/crypto/cipher_suite.rs +++ b/src/crypto/cipher_suite.rs @@ -3,7 +3,7 @@ /// Depicts which AEAD algorithm is used for encryption /// and which hashing function is used for the key expansion, -/// see [sframe draft 00 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-ciphersuites) +/// see [sframe draft 03 4.4](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-cipher-suites) #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[cfg_attr(test, derive(strum_macros::Display))] pub enum CipherSuiteVariant { diff --git a/src/crypto/key_expansion.rs b/src/crypto/key_expansion.rs index ef1dab4..d0201e9 100644 --- a/src/crypto/key_expansion.rs +++ b/src/crypto/key_expansion.rs @@ -5,22 +5,58 @@ use super::{cipher_suite::CipherSuite, secret::Secret}; use crate::error::Result; pub trait KeyExpansion { - fn expand_from(cipher_suite: &CipherSuite, key_material: T) -> Result + fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where - T: AsRef<[u8]>; + M: AsRef<[u8]>, + K: Into; } -pub const SFRAME_HKDF_SALT: &[u8] = b"SFrame10"; -pub const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"key"; -pub const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"salt"; +pub fn get_hkdf_key_expand_info(key_id: u64) -> Vec { + [ + SFRAME_LABEL, + SFRAME_HKDF_KEY_EXPAND_INFO, + &key_id.to_be_bytes(), + ] + .concat() +} -#[cfg(feature = "openssl")] -pub const SFRAME_HKDF_SUB_SALT: &[u8] = b"SFrame10 AES CTR AEAD"; -#[cfg(feature = "openssl")] -pub const SFRAME_HKDF_SUB_ENC_EXPAND_INFO: &[u8] = b"enc"; -#[cfg(feature = "openssl")] -pub const SFRAME_HDKF_SUB_AUTH_EXPAND_INFO: &[u8] = b"auth"; +pub fn get_hkdf_salt_expand_info(key_id: u64) -> Vec { + [ + SFRAME_LABEL, + SFRAME_HDKF_SALT_EXPAND_INFO, + &key_id.to_be_bytes(), + ] + .concat() +} + +const SFRAME_LABEL: &[u8] = b"SFrame 1.0 "; + +// For the current test vectors different labels than specified were used +// see https://github.com/sframe-wg/sframe/issues/137 +cfg_if::cfg_if! { + if #[cfg(test)] { + const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"key "; + const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"salt "; + } else { + const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"Secret key "; + const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"Secret salt "; + } +} + +cfg_if::cfg_if! { + if #[cfg(feature = "openssl")] { + pub fn get_hkdf_aead_label(tag_len: usize) -> Vec { + // for current platforms there is no issue casting from usize to u64 + return [SFRAME_HDKF_SUB_AEAD_LABEL, &(tag_len).to_be_bytes()].concat() + } + pub const SFRAME_HDKF_SUB_AEAD_LABEL: &[u8] = b"SFrame 1.0 AES CTR AEAD "; + pub const SFRAME_HKDF_SUB_ENC_EXPAND_INFO: &[u8] = b"enc"; + pub const SFRAME_HDKF_SUB_AUTH_EXPAND_INFO: &[u8] = b"auth"; + } +} + +#[cfg(feature = "openssl")] #[cfg(test)] mod test { use super::KeyExpansion; @@ -30,16 +66,26 @@ mod test { use crate::{crypto::cipher_suite::CipherSuiteVariant, util::test::assert_bytes_eq}; mod aes_gcm { + use crate::crypto::key_expansion::SFRAME_LABEL; + use super::*; use test_case::test_case; #[test_case(CipherSuiteVariant::AesGcm128Sha256; "AesGcm128Sha256")] #[test_case(CipherSuiteVariant::AesGcm256Sha512; "AesGcm256Sha512")] + fn derive_correct_base_keys(variant: CipherSuiteVariant) { let test_vec = get_sframe_test_vector(&variant.to_string()); - let secret = - Secret::expand_from(&CipherSuite::from(variant), &test_vec.key_material).unwrap(); + + assert_bytes_eq(SFRAME_LABEL, &test_vec.sframe_label); + + let secret = Secret::expand_from( + &CipherSuite::from(variant), + &test_vec.key_material, + test_vec.key_id, + ) + .unwrap(); assert_bytes_eq(&secret.key, &test_vec.sframe_key); assert_bytes_eq(&secret.salt, &test_vec.sframe_salt); @@ -49,37 +95,23 @@ mod test { #[cfg(feature = "openssl")] mod aes_ctr { use super::*; - use crate::test_vectors::get_aes_ctr_test_vector; - use test_case::test_case; #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80")] #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64")] #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32")] fn derive_correct_sub_keys(variant: CipherSuiteVariant) { - let test_vec = get_aes_ctr_test_vector(&variant.to_string()); + let test_vec = get_sframe_test_vector(&variant.to_string()); let cipher_suite = CipherSuite::from(variant); - let secret = Secret::expand_from(&cipher_suite, &test_vec.key_material).unwrap(); - assert_bytes_eq(&secret.auth.unwrap(), &test_vec.auth_key); - assert_bytes_eq(&secret.key, &test_vec.enc_key); - } - - #[test] - fn derive_correct_keys_aes_ctr_128_hmac_sha256_64() { - derive_correct_sub_keys(CipherSuiteVariant::AesCtr128HmacSha256_64); - } - - #[test] - fn derive_correct_keys_aes_ctr_128_hmac_sha256_32() { - derive_correct_sub_keys(CipherSuiteVariant::AesCtr128HmacSha256_32); - } + let secret = + Secret::expand_from(&cipher_suite, &test_vec.key_material, test_vec.key_id) + .unwrap(); - #[test] - // AesCtr128HmacSha256_80 is not available in the test vectors - #[ignore] - fn derive_correct_keys_aes_ctr_128_hmac_sha256_80() { - derive_correct_sub_keys(CipherSuiteVariant::AesCtr128HmacSha256_80); + assert_bytes_eq(&secret.salt, &test_vec.sframe_salt); + // the subkeys stored in secret.key and secret.auth are not included in the test vectors + assert_eq!(secret.auth.unwrap().len(), cipher_suite.hash_len); + assert_eq!(secret.key.len(), cipher_suite.key_len); } } } diff --git a/src/crypto/openssl/aead.rs b/src/crypto/openssl/aead.rs index ad8d9ee..6c1e1d9 100644 --- a/src/crypto/openssl/aead.rs +++ b/src/crypto/openssl/aead.rs @@ -190,11 +190,14 @@ impl CipherSuite { let mut signer = openssl::sign::Signer::new(openssl::hash::MessageDigest::sha256(), &key)?; // for current platforms there is no issue casting from usize to u64 - let aad_len = (aad.len() as u64).to_be_bytes(); - let ct_len = (encrypted.len() as u64).to_be_bytes(); - for buf in [&aad_len, &ct_len, nonce, aad, encrypted] { + let aad_len = &(aad.len() as u64).to_be_bytes(); + let ct_len = &(encrypted.len() as u64).to_be_bytes(); + let tag_len = &(self.auth_tag_len as u64).to_be_bytes(); + + for buf in [aad_len, ct_len, tag_len, nonce, aad, encrypted] { signer.update(buf)?; } + let mut tag = signer.sign_to_vec()?; tag.resize(self.auth_tag_len, 0); diff --git a/src/crypto/openssl/key_expansion.rs b/src/crypto/openssl/key_expansion.rs index 1cf4346..f2b9dbe 100644 --- a/src/crypto/openssl/key_expansion.rs +++ b/src/crypto/openssl/key_expansion.rs @@ -5,9 +5,8 @@ use crate::{ crypto::{ cipher_suite::{CipherSuite, CipherSuiteVariant}, key_expansion::{ - KeyExpansion, SFRAME_HDKF_SALT_EXPAND_INFO, SFRAME_HDKF_SUB_AUTH_EXPAND_INFO, - SFRAME_HKDF_KEY_EXPAND_INFO, SFRAME_HKDF_SALT, SFRAME_HKDF_SUB_ENC_EXPAND_INFO, - SFRAME_HKDF_SUB_SALT, + get_hkdf_aead_label, get_hkdf_key_expand_info, get_hkdf_salt_expand_info, KeyExpansion, + SFRAME_HDKF_SUB_AUTH_EXPAND_INFO, SFRAME_HKDF_SUB_ENC_EXPAND_INFO, }, secret::Secret, }, @@ -15,12 +14,14 @@ use crate::{ }; impl KeyExpansion for Secret { - fn expand_from(cipher_suite: &CipherSuite, key_material: T) -> Result + fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where - T: AsRef<[u8]>, + M: AsRef<[u8]>, + K: Into, { let try_expand = || { - let (base_key, salt) = expand_secret(cipher_suite, key_material.as_ref())?; + let (base_key, salt) = + expand_secret(cipher_suite, key_material.as_ref(), key_id.into())?; let (key, auth) = if cipher_suite.is_ctr_mode() { let (key, auth) = expand_subsecret(cipher_suite, &base_key)?; (key, Some(auth)) @@ -38,18 +39,20 @@ impl KeyExpansion for Secret { fn expand_secret( cipher_suite: &CipherSuite, key_material: &[u8], + key_id: u64, ) -> std::result::Result<(Vec, Vec), openssl::error::ErrorStack> { - let prk = extract_prk(cipher_suite, key_material, SFRAME_HKDF_SALT)?; + // No salt used for the extraction: https://www.ietf.org/archive/id/draft-ietf-sframe-enc-03.html#name-key-derivation + let prk = extract_pseudo_random_key(cipher_suite, key_material, b"")?; let key = expand_key( cipher_suite, &prk, - SFRAME_HKDF_KEY_EXPAND_INFO, + &get_hkdf_key_expand_info(key_id), cipher_suite.key_len, )?; let salt = expand_key( cipher_suite, &prk, - SFRAME_HDKF_SALT_EXPAND_INFO, + &get_hkdf_salt_expand_info(key_id), cipher_suite.nonce_len, )?; @@ -60,7 +63,8 @@ fn expand_subsecret( cipher_suite: &CipherSuite, key: &[u8], ) -> std::result::Result<(Vec, Vec), openssl::error::ErrorStack> { - let prk = extract_prk(cipher_suite, key, SFRAME_HKDF_SUB_SALT)?; + let salt = get_hkdf_aead_label(cipher_suite.auth_tag_len); + let prk = extract_pseudo_random_key(cipher_suite, key, &salt)?; let key = expand_key( cipher_suite, &prk, @@ -77,7 +81,7 @@ fn expand_subsecret( Ok((key, auth)) } -fn extract_prk( +fn extract_pseudo_random_key( cipher_suite: &CipherSuite, key_material: &[u8], salt: &[u8], @@ -135,3 +139,29 @@ impl From for &'static openssl::md::MdRef { } } } +#[cfg(test)] +mod test { + + use super::*; + use crate::{test_vectors::get_aes_ctr_test_vector, util::test::assert_bytes_eq}; + + use test_case::test_case; + + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_80; "AesCtr128HmacSha256_80")] + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_64; "AesCtr128HmacSha256_64")] + #[test_case(CipherSuiteVariant::AesCtr128HmacSha256_32; "AesCtr128HmacSha256_32")] + fn derive_correct_sub_keys(variant: CipherSuiteVariant) { + let test_vec = get_aes_ctr_test_vector(&variant.to_string()); + let cipher_suite = CipherSuite::from(variant); + + let aead_salt = get_hkdf_aead_label(cipher_suite.auth_tag_len); + assert_bytes_eq(&aead_salt, &test_vec.aead_label); + + let prk = extract_pseudo_random_key(&cipher_suite, &test_vec.base_key, &aead_salt).unwrap(); + assert_bytes_eq(&prk, &test_vec.aead_secret); + + let (key, auth) = expand_subsecret(&cipher_suite, &test_vec.base_key).unwrap(); + assert_bytes_eq(&key, &test_vec.enc_key); + assert_bytes_eq(&auth, &test_vec.auth_key); + } +} diff --git a/src/crypto/ring/key_expansion.rs b/src/crypto/ring/key_expansion.rs index 2d904a0..04cc90a 100644 --- a/src/crypto/ring/key_expansion.rs +++ b/src/crypto/ring/key_expansion.rs @@ -4,25 +4,34 @@ use crate::{ crypto::{ cipher_suite::{CipherSuite, CipherSuiteVariant}, - key_expansion::{ - KeyExpansion, SFRAME_HDKF_SALT_EXPAND_INFO, SFRAME_HKDF_KEY_EXPAND_INFO, - SFRAME_HKDF_SALT, - }, + key_expansion::{get_hkdf_key_expand_info, get_hkdf_salt_expand_info, KeyExpansion}, secret::Secret, }, error::{Result, SframeError}, }; impl KeyExpansion for Secret { - fn expand_from(cipher_suite: &CipherSuite, key_material: T) -> Result + fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where - T: AsRef<[u8]>, + M: AsRef<[u8]>, + K: Into, { + let key_id = key_id.into(); let algorithm = cipher_suite.variant.into(); - let prk = ring::hkdf::Salt::new(algorithm, SFRAME_HKDF_SALT).extract(key_material.as_ref()); + // No salt used for the extraction: https://www.ietf.org/archive/id/draft-ietf-sframe-enc-03.html#name-key-derivation + let pseudo_random_key = + ring::hkdf::Salt::new(algorithm, b"").extract(key_material.as_ref()); - let key = expand_key(&prk, SFRAME_HKDF_KEY_EXPAND_INFO, cipher_suite.key_len)?; - let salt = expand_key(&prk, SFRAME_HDKF_SALT_EXPAND_INFO, cipher_suite.nonce_len)?; + let key = expand_key( + &pseudo_random_key, + &get_hkdf_key_expand_info(key_id), + cipher_suite.key_len, + )?; + let salt = expand_key( + &pseudo_random_key, + &get_hkdf_salt_expand_info(key_id), + cipher_suite.nonce_len, + )?; Ok(Secret { key, diff --git a/src/header/basic_header.rs b/src/header/basic_header.rs index d140b85..ddb8068 100644 --- a/src/header/basic_header.rs +++ b/src/header/basic_header.rs @@ -11,7 +11,7 @@ use super::{ }; bitfield! { - /// Modeled after [sframe draft 00 4.2](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-sframe-header) + /// Modeled after [sframe draft 03 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-sframe-header) /// ```txt /// 0 1 2 3 4 5 6 7 /// +-+-+-+-+-+-+-+-+---------------------------------+ diff --git a/src/header/extended_header.rs b/src/header/extended_header.rs index 853b842..62a6f76 100644 --- a/src/header/extended_header.rs +++ b/src/header/extended_header.rs @@ -13,7 +13,7 @@ use super::{ }; bitfield! { - /// Modeled after [sframe draft 00 4.2](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-sframe-header) + /// Modeled after [sframe draft 03 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-sframe-header) /// ```txt /// 0 1 2 3 4 5 6 7 /// +-+-+-+-+-+-+-+-+---------------------------+---------------------------+ diff --git a/src/header/mod.rs b/src/header/mod.rs index 6d8658d..13be405 100644 --- a/src/header/mod.rs +++ b/src/header/mod.rs @@ -44,7 +44,7 @@ pub trait HeaderFields { } /// Sframe header with a KID with a length of up to 3bits -/// modeled after [sframe draft 00 4.2](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-sframe-header) +/// modeled after [sframe draft 03 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-sframe-header) /// ```txt /// 0 1 2 3 4 5 6 7 /// +-+-+-+-+-+-+-+-+---------------------------------+ @@ -73,7 +73,7 @@ impl BasicHeader { } } /// Extended sframe header with a KID with a length of up to 8 bytes -/// modeled after [sframe draft 00 4.2](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-sframe-header) +/// modeled after [sframe draft 03 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-sframe-header) /// ```txt /// 0 1 2 3 4 5 6 7 /// +-+-+-+-+-+-+-+-+---------------------------+---------------------------+ @@ -102,7 +102,7 @@ impl ExtendedHeader { } #[derive(Copy, Clone, Debug)] -/// Represents an Sframe header modeled after [sframe draft 00 4.2](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-01#name-sframe-header) +/// Represents an Sframe header modeled after [sframe draft 03 4.3](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03#name-sframe-header) /// containing the key id of the sender (KID) and the current frame count (CTR). /// There are two variants, either with a KID represented by 3 bits (Basic) and an extended version with a KID of up to 8 bytes (Extended). /// The CTR field has a variable length of up to 8 bytes where the size is represented with LEN. Here LEN=0 represents a length of 1. @@ -218,7 +218,6 @@ mod test { use super::{frame_count::FrameCount, keyid::KeyId, Header}; use crate::header::{Deserialization, HeaderFields}; use crate::util::test::assert_bytes_eq; - use crate::CipherSuiteVariant::{AesGcm128Sha256, AesGcm256Sha512}; use pretty_assertions::assert_eq; diff --git a/src/receiver.rs b/src/receiver.rs index 42f430d..1654f35 100644 --- a/src/receiver.rs +++ b/src/receiver.rs @@ -107,9 +107,10 @@ impl Receiver { Id: Into, KeyMaterial: AsRef<[u8]> + ?Sized, { + let key_id = key_id.into(); self.secrets.insert( - key_id.into(), - Secret::expand_from(&self.options.cipher_suite, key_material)?, + key_id, + Secret::expand_from(&self.options.cipher_suite, key_material, key_id)?, ); Ok(()) } diff --git a/src/sender.rs b/src/sender.rs index 003b775..fc464c8 100644 --- a/src/sender.rs +++ b/src/sender.rs @@ -108,74 +108,15 @@ impl Sender { where KeyMaterial: AsRef<[u8]> + ?Sized, { - self.secret = Some(Secret::expand_from(&self.cipher_suite, key_material)?); + self.secret = Some(Secret::expand_from( + &self.cipher_suite, + key_material, + self.key_id, + )?); Ok(()) } } -#[cfg(test)] -mod test_on_wire_format { - use super::*; - use crate::receiver::Receiver; - - fn hex(hex_str: &str) -> Vec { - hex::decode(hex_str).unwrap() - } - - const KEY_ID: u8 = 0; - - #[test] - fn deadbeef_decrypt() { - let material = hex("1234567890123456789012345678901212345678901234567890123456789012"); - let mut sender = Sender::new(KEY_ID); - let mut receiver = Receiver::default(); - - sender.set_encryption_key(&material).unwrap(); - receiver.set_encryption_key(KEY_ID, &material).unwrap(); - - let encrypted = sender.encrypt(&hex("deadbeafcacadebaca00"), 4).unwrap(); - let decrypted = receiver.decrypt(encrypted, 4).unwrap(); - - assert_eq!(decrypted, hex("deadbeafcacadebaca00")); - } - - #[test] - fn deadbeef_on_wire() { - let material = hex("1234567890123456789012345678901212345678901234567890123456789012"); - let mut sender = Sender::new(KEY_ID); - let mut receiver = Receiver::default(); - - sender.set_encryption_key(&material).unwrap(); - receiver.set_encryption_key(KEY_ID, &material).unwrap(); - - let encrypted = sender.encrypt(&hex("deadbeafcacadebaca00"), 4).unwrap(); - - assert_eq!( - hex::encode(encrypted), - "deadbeaf0000a160a9176ba4ce7ca128df74907d422e5064d1c23529" - ); - } - - #[test] - fn deadbeef_on_wire_long() { - let material = hex("1234567890123456789012345678901212345678901234567890123456789012"); - let mut sender = Sender::new(KEY_ID); - let mut receiver = Receiver::default(); - - sender.set_encryption_key(&material).unwrap(); - receiver.set_encryption_key(KEY_ID, &material).unwrap(); - - let encrypted = sender - .encrypt(&hex("deadbeafcacadebacacacadebacacacadebaca00"), 4) - .unwrap(); - - assert_eq!( - hex::encode(encrypted), - "deadbeaf0000a160a9176b6ebe53f594a64faa1f48a5246b202d13416bf671b3edae7704a862" - ); - } -} - #[cfg(test)] mod test { use super::*; diff --git a/src/test_vectors/mod.rs b/src/test_vectors/mod.rs index 89596e8..29bfc12 100644 --- a/src/test_vectors/mod.rs +++ b/src/test_vectors/mod.rs @@ -86,13 +86,11 @@ pub struct AesCtrHmacTest { #[serde(deserialize_with = "vec_from_hex_str")] pub aad: Vec, - // TODO rename - #[serde(deserialize_with = "vec_from_hex_str")] - pub pt: Vec, + #[serde(rename = "pt", deserialize_with = "vec_from_hex_str")] + pub plain_text: Vec, - // TODO rename - #[serde(deserialize_with = "vec_from_hex_str")] - pub ct: Vec, + #[serde(rename = "ct", deserialize_with = "vec_from_hex_str")] + pub cipher_text: Vec, } #[derive(serde::Deserialize, Debug, Clone)] From 4014407dc333780dac83a95004b70dfea1553b5c Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Fri, 1 Sep 2023 17:19:52 +0200 Subject: [PATCH 3/8] refactor: rename KeyExpansion to KeyDerivation so the name matches the one in the spec BREAKING CHANGE: Instead of `SframeError.KeyExpansion` use `SframeError.KeyDerivation` --- src/crypto/aead.rs | 2 +- src/crypto/{key_expansion.rs => key_derivation.rs} | 6 +++--- src/crypto/mod.rs | 2 +- .../openssl/{key_expansion.rs => key_derivation.rs} | 10 +++++----- src/crypto/openssl/mod.rs | 2 +- src/crypto/ring/aead.rs | 2 +- .../ring/{key_expansion.rs => key_derivation.rs} | 6 +++--- src/crypto/ring/mod.rs | 2 +- src/error.rs | 2 +- src/receiver.rs | 2 +- src/sender.rs | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) rename src/crypto/{key_expansion.rs => key_derivation.rs} (97%) rename src/crypto/openssl/{key_expansion.rs => key_derivation.rs} (96%) rename src/crypto/ring/{key_expansion.rs => key_derivation.rs} (91%) diff --git a/src/crypto/aead.rs b/src/crypto/aead.rs index abe7815..cef8432 100644 --- a/src/crypto/aead.rs +++ b/src/crypto/aead.rs @@ -34,7 +34,7 @@ pub trait AeadDecrypt { #[cfg(test)] mod test { - use crate::crypto::key_expansion::KeyExpansion; + use crate::crypto::key_derivation::KeyDerivation; use crate::header::{FrameCount, KeyId}; use crate::test_vectors::{get_sframe_test_vector, SframeTest}; use crate::util::test::assert_bytes_eq; diff --git a/src/crypto/key_expansion.rs b/src/crypto/key_derivation.rs similarity index 97% rename from src/crypto/key_expansion.rs rename to src/crypto/key_derivation.rs index d0201e9..fb579ee 100644 --- a/src/crypto/key_expansion.rs +++ b/src/crypto/key_derivation.rs @@ -4,7 +4,7 @@ use super::{cipher_suite::CipherSuite, secret::Secret}; use crate::error::Result; -pub trait KeyExpansion { +pub trait KeyDerivation { fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where M: AsRef<[u8]>, @@ -59,14 +59,14 @@ cfg_if::cfg_if! { #[cfg(feature = "openssl")] #[cfg(test)] mod test { - use super::KeyExpansion; + use super::KeyDerivation; use crate::crypto::cipher_suite::CipherSuite; use crate::crypto::secret::Secret; use crate::test_vectors::get_sframe_test_vector; use crate::{crypto::cipher_suite::CipherSuiteVariant, util::test::assert_bytes_eq}; mod aes_gcm { - use crate::crypto::key_expansion::SFRAME_LABEL; + use crate::crypto::key_derivation::SFRAME_LABEL; use super::*; diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index c2f0cdb..a1635fa 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -3,7 +3,7 @@ pub mod aead; pub mod cipher_suite; -pub mod key_expansion; +pub mod key_derivation; pub mod secret; cfg_if::cfg_if! { diff --git a/src/crypto/openssl/key_expansion.rs b/src/crypto/openssl/key_derivation.rs similarity index 96% rename from src/crypto/openssl/key_expansion.rs rename to src/crypto/openssl/key_derivation.rs index f2b9dbe..ee68ccd 100644 --- a/src/crypto/openssl/key_expansion.rs +++ b/src/crypto/openssl/key_derivation.rs @@ -4,16 +4,16 @@ use crate::{ crypto::{ cipher_suite::{CipherSuite, CipherSuiteVariant}, - key_expansion::{ - get_hkdf_aead_label, get_hkdf_key_expand_info, get_hkdf_salt_expand_info, KeyExpansion, - SFRAME_HDKF_SUB_AUTH_EXPAND_INFO, SFRAME_HKDF_SUB_ENC_EXPAND_INFO, + key_derivation::{ + get_hkdf_aead_label, get_hkdf_key_expand_info, get_hkdf_salt_expand_info, + KeyDerivation, SFRAME_HDKF_SUB_AUTH_EXPAND_INFO, SFRAME_HKDF_SUB_ENC_EXPAND_INFO, }, secret::Secret, }, error::{Result, SframeError}, }; -impl KeyExpansion for Secret { +impl KeyDerivation for Secret { fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where M: AsRef<[u8]>, @@ -32,7 +32,7 @@ impl KeyExpansion for Secret { Ok(Secret { key, salt, auth }) }; - try_expand().map_err(|_: openssl::error::ErrorStack| SframeError::KeyExpansion) + try_expand().map_err(|_: openssl::error::ErrorStack| SframeError::KeyDerivation) } } diff --git a/src/crypto/openssl/mod.rs b/src/crypto/openssl/mod.rs index b0a2ee6..1dba826 100644 --- a/src/crypto/openssl/mod.rs +++ b/src/crypto/openssl/mod.rs @@ -2,5 +2,5 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT pub mod aead; -pub mod key_expansion; +pub mod key_derivation; pub mod tag; diff --git a/src/crypto/ring/aead.rs b/src/crypto/ring/aead.rs index 4a54e93..2b5eb25 100644 --- a/src/crypto/ring/aead.rs +++ b/src/crypto/ring/aead.rs @@ -47,7 +47,7 @@ impl From for &'static ring::aead::Algorithm { impl CipherSuite { fn unbound_encryption_key(&self, secret: &Secret) -> Result { ring::aead::UnboundKey::new(self.variant.into(), secret.key.as_slice()) - .map_err(|_| SframeError::KeyExpansion) + .map_err(|_| SframeError::KeyDerivation) } } diff --git a/src/crypto/ring/key_expansion.rs b/src/crypto/ring/key_derivation.rs similarity index 91% rename from src/crypto/ring/key_expansion.rs rename to src/crypto/ring/key_derivation.rs index 04cc90a..7965ec3 100644 --- a/src/crypto/ring/key_expansion.rs +++ b/src/crypto/ring/key_derivation.rs @@ -4,13 +4,13 @@ use crate::{ crypto::{ cipher_suite::{CipherSuite, CipherSuiteVariant}, - key_expansion::{get_hkdf_key_expand_info, get_hkdf_salt_expand_info, KeyExpansion}, + key_derivation::{get_hkdf_key_expand_info, get_hkdf_salt_expand_info, KeyDerivation}, secret::Secret, }, error::{Result, SframeError}, }; -impl KeyExpansion for Secret { +impl KeyDerivation for Secret { fn expand_from(cipher_suite: &CipherSuite, key_material: M, key_id: K) -> Result where M: AsRef<[u8]>, @@ -63,7 +63,7 @@ fn expand_key(prk: &ring::hkdf::Prk, info: &[u8], key_len: usize) -> Result Date: Sat, 2 Sep 2023 17:45:26 +0200 Subject: [PATCH 4/8] test: update test vectors upstream bug was closed --- src/crypto/key_derivation.rs | 27 +++++++-------- src/test_vectors/mod.rs | 9 +++-- src/test_vectors/test-vectors.json | 55 ++++++++++++++++-------------- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/src/crypto/key_derivation.rs b/src/crypto/key_derivation.rs index fb579ee..2103e76 100644 --- a/src/crypto/key_derivation.rs +++ b/src/crypto/key_derivation.rs @@ -31,23 +31,14 @@ pub fn get_hkdf_salt_expand_info(key_id: u64) -> Vec { const SFRAME_LABEL: &[u8] = b"SFrame 1.0 "; -// For the current test vectors different labels than specified were used -// see https://github.com/sframe-wg/sframe/issues/137 -cfg_if::cfg_if! { - if #[cfg(test)] { - const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"key "; - const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"salt "; - } else { - const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"Secret key "; - const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"Secret salt "; - } -} +const SFRAME_HKDF_KEY_EXPAND_INFO: &[u8] = b"Secret key "; +const SFRAME_HDKF_SALT_EXPAND_INFO: &[u8] = b"Secret salt "; cfg_if::cfg_if! { if #[cfg(feature = "openssl")] { pub fn get_hkdf_aead_label(tag_len: usize) -> Vec { // for current platforms there is no issue casting from usize to u64 - return [SFRAME_HDKF_SUB_AEAD_LABEL, &(tag_len).to_be_bytes()].concat() + [SFRAME_HDKF_SUB_AEAD_LABEL, &(tag_len).to_be_bytes()].concat() } pub const SFRAME_HDKF_SUB_AEAD_LABEL: &[u8] = b"SFrame 1.0 AES CTR AEAD "; @@ -56,7 +47,6 @@ cfg_if::cfg_if! { } } -#[cfg(feature = "openssl")] #[cfg(test)] mod test { use super::KeyDerivation; @@ -66,7 +56,7 @@ mod test { use crate::{crypto::cipher_suite::CipherSuiteVariant, util::test::assert_bytes_eq}; mod aes_gcm { - use crate::crypto::key_derivation::SFRAME_LABEL; + use crate::crypto::key_derivation::{get_hkdf_key_expand_info, get_hkdf_salt_expand_info}; use super::*; @@ -78,7 +68,14 @@ mod test { fn derive_correct_base_keys(variant: CipherSuiteVariant) { let test_vec = get_sframe_test_vector(&variant.to_string()); - assert_bytes_eq(SFRAME_LABEL, &test_vec.sframe_label); + assert_bytes_eq( + &get_hkdf_key_expand_info(test_vec.key_id), + &test_vec.sframe_key_label, + ); + assert_bytes_eq( + &get_hkdf_salt_expand_info(test_vec.key_id), + &test_vec.sframe_salt_label, + ); let secret = Secret::expand_from( &CipherSuite::from(variant), diff --git a/src/test_vectors/mod.rs b/src/test_vectors/mod.rs index 29bfc12..47f722b 100644 --- a/src/test_vectors/mod.rs +++ b/src/test_vectors/mod.rs @@ -17,7 +17,7 @@ pub fn get_header_test_vectors() -> &'static Vec { } pub fn get_aes_ctr_test_vector(cipher_suite_variant: &str) -> &'static AesCtrHmacTest { - &TEST_VECTORS + TEST_VECTORS .aes_ctr_hmac .iter() .find(|v| v.cipher_suite_variant == cipher_suite_variant) @@ -25,7 +25,7 @@ pub fn get_aes_ctr_test_vector(cipher_suite_variant: &str) -> &'static AesCtrHma } pub fn get_sframe_test_vector(cipher_suite_variant: &str) -> &'static SframeTest { - &TEST_VECTORS + TEST_VECTORS .sframe .iter() .find(|v| v.cipher_suite_variant == cipher_suite_variant) @@ -111,7 +111,10 @@ pub struct SframeTest { pub key_material: Vec, #[serde(deserialize_with = "vec_from_hex_str")] - pub sframe_label: Vec, + pub sframe_key_label: Vec, + + #[serde(deserialize_with = "vec_from_hex_str")] + pub sframe_salt_label: Vec, #[serde(deserialize_with = "vec_from_hex_str")] pub sframe_secret: Vec, diff --git a/src/test_vectors/test-vectors.json b/src/test_vectors/test-vectors.json index 382b9ce..98a6c15 100644 --- a/src/test_vectors/test-vectors.json +++ b/src/test_vectors/test-vectors.json @@ -1490,75 +1490,80 @@ "kid": 291, "ctr": 17767, "base_key": "000102030405060708090a0b0c0d0e0f", - "sframe_label": "534672616d6520312e3020", + "sframe_key_label": "534672616d6520312e3020536563726574206b6579200000000000000123", + "sframe_salt_label": "534672616d6520312e30205365637265742073616c74200000000000000123", "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", - "sframe_key": "52cef96e29191912a6be442a9651c43a", - "sframe_salt": "9655c98fdad276683deb279c", + "sframe_key": "73bb177a9fe6c02597132fe430ca2d99", + "sframe_salt": "55582aa5aaced36a74544d91", "metadata": "4945544620534672616d65205747", - "nonce": "9655c98fdad276683deb62fb", + "nonce": "55582aa5aaced36a745408f6", "aad": "19012345674945544620534672616d65205747", "pt": "64726166742d696574662d736672616d652d656e63", - "ct": "1901234567b6a27b2d24f1f06d49cffe6c82af5a96e0d89443a7a93a8700f96fdda3e43c" + "ct": "190123456740043f25262c0ca52e9374b070f24b02764715c2e303388c9495324037d043" }, { "cipher_suite": 2, "kid": 291, "ctr": 17767, "base_key": "000102030405060708090a0b0c0d0e0f", - "sframe_label": "534672616d6520312e3020", + "sframe_key_label": "534672616d6520312e3020536563726574206b6579200000000000000123", + "sframe_salt_label": "534672616d6520312e30205365637265742073616c74200000000000000123", "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", - "sframe_key": "52cef96e29191912a6be442a9651c43a", - "sframe_salt": "9655c98fdad276683deb279c", + "sframe_key": "73bb177a9fe6c02597132fe430ca2d99", + "sframe_salt": "55582aa5aaced36a74544d91", "metadata": "4945544620534672616d65205747", - "nonce": "9655c98fdad276683deb62fb", + "nonce": "55582aa5aaced36a745408f6", "aad": "19012345674945544620534672616d65205747", "pt": "64726166742d696574662d736672616d652d656e63", - "ct": "190123456728b1faac3515d5ca29f3db9c52f27789c5ec8386ff0b570853ebcf721c" + "ct": "1901234567729eef4910d734abfd392cdff0f67d2a8d06041eef5f895e4cecc03a6d" }, { "cipher_suite": 3, "kid": 291, "ctr": 17767, "base_key": "000102030405060708090a0b0c0d0e0f", - "sframe_label": "534672616d6520312e3020", + "sframe_key_label": "534672616d6520312e3020536563726574206b6579200000000000000123", + "sframe_salt_label": "534672616d6520312e30205365637265742073616c74200000000000000123", "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", - "sframe_key": "52cef96e29191912a6be442a9651c43a", - "sframe_salt": "9655c98fdad276683deb279c", + "sframe_key": "73bb177a9fe6c02597132fe430ca2d99", + "sframe_salt": "55582aa5aaced36a74544d91", "metadata": "4945544620534672616d65205747", - "nonce": "9655c98fdad276683deb62fb", + "nonce": "55582aa5aaced36a745408f6", "aad": "19012345674945544620534672616d65205747", "pt": "64726166742d696574662d736672616d652d656e63", - "ct": "190123456754719dcfbe065e1606068cb6b6b5f1a9a371e633ff088485e7" + "ct": "190123456717fd0a325fdcd5f0d68089ee5bd17df6296b69b6b0e70c8d73" }, { "cipher_suite": 4, "kid": 291, "ctr": 17767, "base_key": "000102030405060708090a0b0c0d0e0f", - "sframe_label": "534672616d6520312e3020", + "sframe_key_label": "534672616d6520312e3020536563726574206b6579200000000000000123", + "sframe_salt_label": "534672616d6520312e30205365637265742073616c74200000000000000123", "sframe_secret": "d926952ca8b7ec4a95941d1ada3a5203ceff8cceee34f574d23909eb314c40c0", - "sframe_key": "52cef96e29191912a6be442a9651c43a", - "sframe_salt": "9655c98fdad276683deb279c", + "sframe_key": "73bb177a9fe6c02597132fe430ca2d99", + "sframe_salt": "55582aa5aaced36a74544d91", "metadata": "4945544620534672616d65205747", - "nonce": "9655c98fdad276683deb62fb", + "nonce": "55582aa5aaced36a745408f6", "aad": "19012345674945544620534672616d65205747", "pt": "64726166742d696574662d736672616d652d656e63", - "ct": "1901234567d4dfcd537dbd054dcf4bdab53bf451826843325838178391f63dc15b9475d6081b59c776a5" + "ct": "1901234567b8bf87709717f709a35b4e91b2109e5c1ca4f76179415f8bb15d70a9be7eb89c7adb76d300" }, { "cipher_suite": 5, "kid": 291, "ctr": 17767, "base_key": "000102030405060708090a0b0c0d0e0f", - "sframe_label": "534672616d6520312e3020", + "sframe_key_label": "534672616d6520312e3020536563726574206b6579200000000000000123", + "sframe_salt_label": "534672616d6520312e30205365637265742073616c74200000000000000123", "sframe_secret": "0fc3ea6de6aac97a35f194cf9bed94d4b5230f1cb45a785c9fe5dce9c188938ab6ba005bc4c0a19181599e9d1bcf7b74aca48b60bf5e254e546d809313e083a3", - "sframe_key": "5f3f7c1b277d9cad86b906da39702c3fcdf720902817977ae99bd10f2e5ad56a", - "sframe_salt": "a653f558a8018877314fb8d9", + "sframe_key": "e9e405efb7cd325030760935bf49fd5669d7c19eb84ca74b419a1487cf835107", + "sframe_salt": "11007b537a1cf728a4c544c1", "metadata": "4945544620534672616d65205747", - "nonce": "a653f558a8018877314ffdbe", + "nonce": "11007b537a1cf728a4c501a6", "aad": "19012345674945544620534672616d65205747", "pt": "64726166742d696574662d736672616d652d656e63", - "ct": "19012345672f55e5feb46d118576dc715566003f4becf5252149c839aea7dd5434bf8eceb8b4d59bbfb2" + "ct": "19012345671e11c62748536fd55fdbc9560daea4825bfecbb05489cd41cb7a1556e001989a4485e8a02f" } ] } From a1b3c4cc5a848be45410293ede59667c2cb4e27d Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Sun, 3 Sep 2023 20:14:18 +0200 Subject: [PATCH 5/8] refactor: fix clippy warning --- src/crypto/aead.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crypto/aead.rs b/src/crypto/aead.rs index cef8432..6eec782 100644 --- a/src/crypto/aead.rs +++ b/src/crypto/aead.rs @@ -100,7 +100,7 @@ mod test { let full_frame: Vec = header_buffer .into_iter() - .chain(data_buffer.into_iter()) + .chain(data_buffer) .chain(tag.as_ref().iter().cloned()) .collect(); From 493c831ad783159606a4fd31910397eeae39b442 Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Wed, 11 Oct 2023 13:21:46 +0200 Subject: [PATCH 6/8] docs: update README --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 16dcf74..5e08875 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,18 @@ Secure Frame (SFrame) ![maintenance](https://img.shields.io/maintenance/yes/2023) -This library is an implementation of [draft-ietf-sframe-enc-latest](https://sframe-wg.github.io/sframe/draft-ietf-sframe-enc.html) and provides and end-to-end encryption mechanism for media frames that is suited for WebRTC conferences. +This library is an implementation of [draft-ietf-sframe-enc-03](https://datatracker.ietf.org/doc/html/draft-ietf-sframe-enc-03) and provides and end-to-end encryption mechanism for media frames that is suited for WebRTC conferences. It is in it's current form a subset of the specification. There is an alternative implementation under [goto-opensource/secure-frame-ts](https://github.com/goto-opensource/secure-frame-ts) ## Differences from the sframe draft * ratcheting is not implemented * keyIds are used as senderIds -* no metadata authentication +* no metadata authentication ## Supported crypto libraries Currently two crypto libraries are supported: -- [ring](https://crates.io/crates/ring) +- [ring](https://crates.io/crates/ring) - is enabled per default with the feature `ring` - supports compilation to Wasm32 - Aes-CTR mode ciphers are not supported @@ -27,10 +27,10 @@ Currently two crypto libraries are supported: - is enabled with the feature `openssl` - To build e.g. use `cargo build --features openssl --no-default-features` - uses rust bindings to OpenSSL. - - Per default the OpenSSL library is locally compiled and then statically linked. The build process requires a C compiler, `perl` (and `perl-core`), and `make`. For further options see the [openssl crate documentation](https://docs.rs/openssl/0.10.55/openssl/). + - Per default the OpenSSL library is locally compiled and then statically linked. The build process requires a C compiler, `perl` (and `perl-core`), and `make`. For further options see the [openssl crate documentation](https://docs.rs/openssl/0.10.55/openssl/). - Compilation to Wasm32 is [not yet supported](https://github.com/sfackler/rust-openssl/issues/1016) -Both cannot be enabled at the same time, thus on conflict `sframe` issues a compiler error. +Both cannot be enabled at the same time, thus on conflict `sframe` issues a compiler error. ## License Licensed under either of Apache License, Version 2.0 or MIT license at your option. @@ -39,4 +39,4 @@ Unless you explicitly state otherwise, any contribution intentionally submitted ## Contribution Any help in form of descriptive and friendly issues or comprehensive pull requests are welcome! -The Changelog of this library is generated from its commit log, there any commit message must conform with https://www.conventionalcommits.org/en/v1.0.0/. For simplicity you could make your commits with convco. \ No newline at end of file +The Changelog of this library is generated from its commit log, there any commit message must conform with https://www.conventionalcommits.org/en/v1.0.0/. For simplicity you could make your commits with convco. From e4c8a6e31edaeb7d3ac4fe32d9d486f80f42641b Mon Sep 17 00:00:00 2001 From: Tobias Waurick Date: Sat, 21 Oct 2023 19:02:07 +0200 Subject: [PATCH 7/8] test: add aes-ctr benches --- benches/crypto.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/benches/crypto.rs b/benches/crypto.rs index 05e65f9..803c5cd 100644 --- a/benches/crypto.rs +++ b/benches/crypto.rs @@ -108,6 +108,12 @@ fn crypto_benches(c: &mut Criterion) { for variant in [ CipherSuiteVariant::AesGcm128Sha256, CipherSuiteVariant::AesGcm256Sha512, + #[cfg(feature = "openssl")] + CipherSuiteVariant::AesCtr128HmacSha256_80, + #[cfg(feature = "openssl")] + CipherSuiteVariant::AesCtr128HmacSha256_64, + #[cfg(feature = "openssl")] + CipherSuiteVariant::AesCtr128HmacSha256_32, ] { let mut ctx = CryptoBenches::from(variant); ctx.run_benches(c); From 987db3b943ce584eb318f3ffba764f5047aeddd8 Mon Sep 17 00:00:00 2001 From: Hendrik Sollich Date: Sat, 28 Oct 2023 11:42:55 +0200 Subject: [PATCH 8/8] refactor: manually unroll loop --- src/crypto/openssl/aead.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/crypto/openssl/aead.rs b/src/crypto/openssl/aead.rs index 6c1e1d9..4102711 100644 --- a/src/crypto/openssl/aead.rs +++ b/src/crypto/openssl/aead.rs @@ -190,13 +190,12 @@ impl CipherSuite { let mut signer = openssl::sign::Signer::new(openssl::hash::MessageDigest::sha256(), &key)?; // for current platforms there is no issue casting from usize to u64 - let aad_len = &(aad.len() as u64).to_be_bytes(); - let ct_len = &(encrypted.len() as u64).to_be_bytes(); - let tag_len = &(self.auth_tag_len as u64).to_be_bytes(); - - for buf in [aad_len, ct_len, tag_len, nonce, aad, encrypted] { - signer.update(buf)?; - } + signer.update(&(aad.len() as u64).to_be_bytes())?; + signer.update(&(encrypted.len() as u64).to_be_bytes())?; + signer.update(&(self.auth_tag_len as u64).to_be_bytes())?; + signer.update(nonce)?; + signer.update(aad)?; + signer.update(encrypted)?; let mut tag = signer.sign_to_vec()?; tag.resize(self.auth_tag_len, 0);