From f1660e212ef63077c37377622ecf8916e248be7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodolphe=20Br=C3=A9ard?= Date: Sat, 20 Apr 2024 19:02:55 +0200 Subject: [PATCH] Add the key length to the key context --- src/coffio.rs | 14 +++++++------- src/kdf.rs | 21 +++++++++++---------- src/scheme.rs | 9 +++++++++ src/scheme/aes.rs | 1 + src/scheme/xchacha20poly1305.rs | 1 + 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/coffio.rs b/src/coffio.rs index c511fb5..d10f98c 100644 --- a/src/coffio.rs +++ b/src/coffio.rs @@ -98,7 +98,7 @@ mod tests { use super::*; use crate::{DataContext, KeyContext}; - const TEST_CIPHERTEXT: &str = "AQAAAA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:NgAAAAAAAAA"; + const TEST_CIPHERTEXT: &str = "AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA"; const TEST_DATA: &[u8] = b"Lorem ipsum dolor sit amet."; const TEST_KEY_CTX: &[&str] = &["db_name", "table_name", "column_name"]; const TEST_DATA_CTX: &[&str] = &["018db876-3d9d-79af-9460-55d17da991d8"]; @@ -268,12 +268,12 @@ mod tests { fn decrypt_invalid_ciphertext() { let tests = &[ ("", "empty data"), - ("AQAATA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:NgAAAAAAAAA", "unknown ikm id"), - ("AQAAAA:MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:NgAAAAAAAAA", "invalid nonce"), - ("AQAAAA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:8e_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:NgAAAAAAAAA", "invalid ciphertext"), - ("AQAAAA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:NaAAAAAAAAA", "invalid time period"), - ("AQAAAA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg:", "empty time period"), - ("AQAAAA:W-nzcGkPU6eWj_JjjqLpQk6WSe_CIUPF:we_HR8yD3XnQ9aaJlZFvqPitnDlQHexw4QPaYaOTzpHSWNW86QQrLRRZOg", "missing time period"), + ("AQAATA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "unknown ikm id"), + ("AQAAAA:8pVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid nonce"), + ("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:8TkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NgAAAAAAAAA", "invalid ciphertext"), + ("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:NaAAAAAAAAA", "invalid time period"), + ("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg:", "empty time period"), + ("AQAAAA:qpVDbGvu0wl2tQgfF5jngCWCoCq5d9gj:eTkOSKz9YyvJE8PyT1lAFn4hyeK_0l6tWU4yyHA-7WRCJ9G-HWNpqoKBxg", "missing time period"), ]; let lst = get_ikm_lst_chacha20poly1305_blake3(); diff --git a/src/kdf.rs b/src/kdf.rs index e2dc8db..cb6a991 100644 --- a/src/kdf.rs +++ b/src/kdf.rs @@ -9,7 +9,8 @@ pub(crate) fn derive_key( ctx: &KeyContext, time_period: Option, ) -> Vec { - let elems = ctx.get_ctx_elems(time_period); + let mut elems = ctx.get_ctx_elems(time_period); + elems.push(ikm.scheme.get_key_len().to_le_bytes().to_vec()); let key_context = canonicalize(&elems); let kdf = ikm.scheme.get_kdf(); kdf(&key_context, &ikm.content) @@ -36,9 +37,9 @@ mod tests { assert_eq!( super::derive_key(&ikm, &ctx, None), vec![ - 0xc1, 0xd2, 0xf0, 0xa7, 0x4d, 0xc5, 0x32, 0x6e, 0x89, 0x86, 0x85, 0xae, 0x3f, 0xdf, - 0x16, 0x0b, 0xec, 0xe6, 0x63, 0x46, 0x41, 0x8a, 0x28, 0x2b, 0x04, 0xa1, 0x23, 0x20, - 0x36, 0xe3, 0x2f, 0x0a + 0xf9, 0x90, 0x22, 0x8, 0x9a, 0x63, 0x2, 0xc9, 0xd0, 0x7c, 0x71, 0x56, 0xa4, 0xc3, + 0x8c, 0x4b, 0x1d, 0xe8, 0x56, 0xf2, 0xc3, 0xf6, 0xba, 0xc3, 0x4b, 0x8d, 0x85, 0x29, + 0x4b, 0x5, 0x13, 0xc3 ] ); } @@ -51,9 +52,9 @@ mod tests { assert_eq!( super::derive_key(&ikm, &ctx, Some(0)), vec![ - 0xdc, 0x6c, 0x4b, 0xed, 0xef, 0x31, 0x2a, 0x83, 0x40, 0xc0, 0xee, 0xf4, 0xd7, 0xe5, - 0xec, 0x2e, 0xcf, 0xda, 0x64, 0x0a, 0xb8, 0xb6, 0x89, 0xe4, 0x3c, 0x6e, 0xc2, 0x53, - 0x0e, 0xaa, 0x38, 0x12 + 0xfe, 0x70, 0x65, 0x84, 0x79, 0x9a, 0xc0, 0xf1, 0x50, 0xb5, 0x72, 0x73, 0x16, 0xf4, + 0x5b, 0x49, 0xb4, 0x46, 0xfa, 0x58, 0xa6, 0xb9, 0xf0, 0xc7, 0xec, 0x49, 0x87, 0x7e, + 0x46, 0xd0, 0x9, 0xe8 ] ); } @@ -66,9 +67,9 @@ mod tests { assert_eq!( super::derive_key(&ikm, &ctx, Some(42)), vec![ - 0xc7, 0xfb, 0x96, 0x6a, 0x15, 0xde, 0x5f, 0xfc, 0x66, 0xa6, 0xac, 0xda, 0x6b, 0x8e, - 0xa3, 0x66, 0xd8, 0x70, 0x5b, 0x2f, 0xf9, 0x7f, 0xfb, 0x47, 0xb1, 0xa9, 0x93, 0xfc, - 0xf5, 0x0b, 0x6d, 0x3c + 0x5c, 0x9b, 0x1c, 0xfa, 0x21, 0xac, 0xdb, 0x37, 0x4d, 0xee, 0x60, 0xf7, 0x6, 0x18, + 0x85, 0xb5, 0x95, 0x2a, 0x6c, 0xd3, 0x43, 0x9, 0xcb, 0x1b, 0x7f, 0x9d, 0xdf, 0x58, + 0xf9, 0x3e, 0x6e, 0x14 ] ); } diff --git a/src/scheme.rs b/src/scheme.rs index 4d95aba..c4e51a4 100644 --- a/src/scheme.rs +++ b/src/scheme.rs @@ -88,6 +88,15 @@ impl Scheme { } } + pub(crate) fn get_key_len(&self) -> usize { + match self { + #[cfg(feature = "chacha")] + Scheme::XChaCha20Poly1305WithBlake3 => xchacha20poly1305::KEY_SIZE, + #[cfg(feature = "aes")] + Scheme::Aes128GcmWithSha256 => aes::AES128_KEY_SIZE, + } + } + pub(crate) fn get_decryption(&self) -> Box { match self { #[cfg(feature = "chacha")] diff --git a/src/scheme/aes.rs b/src/scheme/aes.rs index 2b0ac26..b224124 100644 --- a/src/scheme/aes.rs +++ b/src/scheme/aes.rs @@ -3,6 +3,7 @@ use crate::error::{Error, Result}; use aes_gcm::aead::{Aead, KeyInit, Payload}; use aes_gcm::{Aes128Gcm, Key, Nonce}; +pub(crate) const AES128_KEY_SIZE: usize = 128; // 96 bits (12 bytes) // Reason: NIST Special Publication 800-38D // https://doi.org/10.6028/NIST.SP.800-38D diff --git a/src/scheme/xchacha20poly1305.rs b/src/scheme/xchacha20poly1305.rs index daa38a3..d041eda 100644 --- a/src/scheme/xchacha20poly1305.rs +++ b/src/scheme/xchacha20poly1305.rs @@ -3,6 +3,7 @@ use crate::error::{Error, Result}; use chacha20poly1305::aead::{Aead, KeyInit, Payload}; use chacha20poly1305::{Key, XChaCha20Poly1305, XNonce}; +pub(crate) const KEY_SIZE: usize = 256; // X-variant: the nonce's size is 192 bits (24 bytes) const NONCE_SIZE: usize = 24;