Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,7 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
name = "crypto"
version = "0.0.0"
dependencies = [
"hex",
"openssl",
"thiserror 2.0.16",
"wchar",
Expand Down
3 changes: 3 additions & 0 deletions support/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ windows = { workspace = true, features = ["Win32_Foundation","Win32_Security_Cry
windows-result.workspace = true
zerocopy.workspace = true

[dev-dependencies]
hex.workspace = true

[lints]
workspace = true
35 changes: 35 additions & 0 deletions support/crypto/src/aes_256_gcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,38 @@ impl Aes256GcmDecCtx<'_> {
self.0.cipher(iv, data, tag)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_aes_256_gcm() {
// Test Case 14 from the NIST GCM specification (gcm-spec.pdf).
let key = hex::decode("feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308")
.unwrap();
let iv = hex::decode("cafebabefacedbaddecaf888").unwrap();
let plain = hex::decode(
"d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72\
1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
)
.unwrap();
let cipher = hex::decode(
"522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa\
8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad",
)
.unwrap();
let tag = hex::decode("b094dac5d93471bdec1a502270e3cc6c").unwrap();

let aes = Aes256Gcm::new(&key.try_into().unwrap()).unwrap();
let mut enc_ctx = aes.encrypt().unwrap();
let mut enc_tag = vec![0u8; tag.len()];
let enc_cipher = enc_ctx.cipher(&iv, &plain, &mut enc_tag).unwrap();
assert_eq!(enc_cipher, cipher);
assert_eq!(enc_tag, tag);

let mut dec_ctx = aes.decrypt().unwrap();
let dec_plain = dec_ctx.cipher(&iv, &cipher, &tag).unwrap();
assert_eq!(dec_plain, plain);
}
}
43 changes: 43 additions & 0 deletions support/crypto/src/xts_aes_256/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,46 @@ impl XtsAes256DecCtx<'_> {
self.0.cipher(tweak, data)
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_xts_aes_256() {
// Key and plaintext from IEEE Std 1619-2007 XTS-AES-256 test vectors
// (vectors 10–14 use this key derived from the digits of e and pi).
let key = hex::decode(
"2718281828459045235360287471352662497757247093699959574966967627\
3141592653589793238462643383279502884197169399375105820974944592",
)
.unwrap();
let tweak: u128 = 0;
let plain = hex::decode("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")
.unwrap();
let expected_ciphertext =
hex::decode("3a060a8cad115a6f44572e3759e43c8fcad8bfcb233ff6ad71b7c1e7ca651508")
.unwrap();

let data_unit_size = plain.len() as u32;
let xts = XtsAes256::new(&key.try_into().unwrap(), data_unit_size).unwrap();

// Encrypt and verify against known test vector.
let mut enc_data = plain.clone();
let mut enc_ctx = xts.encrypt().unwrap();
enc_ctx.cipher(tweak, &mut enc_data).unwrap();
assert_eq!(enc_data, expected_ciphertext);

// Decrypt and verify we recover the original plaintext.
let mut dec_data = enc_data.clone();
let mut dec_ctx = xts.decrypt().unwrap();
dec_ctx.cipher(tweak, &mut dec_data).unwrap();
assert_eq!(dec_data, plain);

// Verify a different tweak produces different ciphertext.
let mut enc_data2 = plain.clone();
let mut enc_ctx2 = xts.encrypt().unwrap();
enc_ctx2.cipher(1, &mut enc_data2).unwrap();
assert_ne!(enc_data2, enc_data);
}
}
Loading