1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #![allow(clippy::unwrap_used, clippy::indexing_slicing)]
16
17 use anyhow::anyhow;
18 use crypto_provider_default::CryptoProviderImpl;
19 use ldt::{DefaultPadder, LdtCipher, LdtDecryptCipher, LdtEncryptCipher, LdtKey, Swap, XorPadder};
20 use std::{fs, io::Read as _};
21 use test_helper::{extract_key_array, extract_key_vec};
22 use xts_aes::XtsAes128;
23
24 #[test]
aluykx_test_vectors() -> Result<(), anyhow::Error>25 fn aluykx_test_vectors() -> Result<(), anyhow::Error> {
26 let full_path = test_helper::get_data_file(
27 "presence/ldt/resources/test/aluykx-test-vectors/ldt_testvectors.json",
28 );
29 let mut file = fs::File::open(full_path)?;
30 let mut data = String::new();
31 let _ = file.read_to_string(&mut data)?;
32 let test_cases = match serde_json::de::from_str(&data)? {
33 serde_json::Value::Array(a) => a,
34 _ => return Err(anyhow!("bad json")),
35 };
36
37 assert_eq!(320, test_cases.len());
38
39 for tc in test_cases {
40 let expected_ciphertext = extract_key_vec(&tc, "ciphertext");
41 let expected_plaintext = extract_key_vec(&tc, "plaintext");
42 let key: [u8; 64] = extract_key_array(&tc, "key");
43 // ignoring the type -- we confirm both encryption and decryption for each test
44 // case
45
46 assert_eq!(expected_plaintext.len(), expected_ciphertext.len());
47 let len = expected_plaintext.len();
48 assert!(len >= crypto_provider::aes::BLOCK_SIZE);
49 assert!(len < crypto_provider::aes::BLOCK_SIZE * 2);
50
51 let ldt_enc = LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(
52 &LdtKey::from_concatenated(&key),
53 );
54 let ldt_dec = LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(
55 &LdtKey::from_concatenated(&key),
56 );
57
58 let mut plaintext = [0; 31];
59 plaintext[..len].copy_from_slice(&expected_ciphertext);
60 ldt_dec.decrypt(&mut plaintext[..len], &DefaultPadder).unwrap();
61 assert_eq!(&expected_plaintext, &plaintext[..len]);
62
63 let mut ciphertext = [0; 31];
64 ciphertext[..len].copy_from_slice(&expected_plaintext);
65 ldt_enc.encrypt(&mut ciphertext[..len], &DefaultPadder).unwrap();
66 assert_eq!(&expected_ciphertext, &ciphertext[..len]);
67 }
68
69 Ok(())
70 }
71
72 #[test]
xor_pad_test_vectors() -> Result<(), anyhow::Error>73 fn xor_pad_test_vectors() -> Result<(), anyhow::Error> {
74 let full_path =
75 test_helper::get_data_file("presence/ldt/resources/test/ldt-xor-pad-testvectors.json");
76 let mut file = fs::File::open(full_path)?;
77 let mut data = String::new();
78 let _ = file.read_to_string(&mut data)?;
79 let test_cases = match serde_json::de::from_str(&data)? {
80 serde_json::Value::Array(a) => a,
81 _ => return Err(anyhow!("bad json")),
82 };
83
84 assert_eq!(1000, test_cases.len());
85
86 for tc in test_cases {
87 let expected_ciphertext = extract_key_vec(&tc, "ciphertext");
88 let expected_plaintext = extract_key_vec(&tc, "plaintext");
89 let key: [u8; 64] = extract_key_array(&tc, "key");
90 let xor_pad: [u8; crypto_provider::aes::BLOCK_SIZE] =
91 extract_key_vec(&tc, "xor_pad").try_into().unwrap();
92 // ignoring the type -- we confirm both encryption and decryption for each test
93 // case
94
95 assert_eq!(expected_plaintext.len(), expected_ciphertext.len());
96 let len = expected_plaintext.len();
97 assert!(len >= crypto_provider::aes::BLOCK_SIZE);
98 assert!(len < crypto_provider::aes::BLOCK_SIZE * 2);
99
100 let ldt_enc = LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(
101 &LdtKey::from_concatenated(&key),
102 );
103 let ldt_dec = LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(
104 &LdtKey::from_concatenated(&key),
105 );
106
107 let mut plaintext = [0; 31];
108 plaintext[..len].copy_from_slice(&expected_ciphertext);
109 ldt_dec.decrypt(&mut plaintext[..len], &XorPadder::from(xor_pad)).unwrap();
110 assert_eq!(&expected_plaintext, &plaintext[..len]);
111
112 let mut ciphertext = [0; 31];
113 ciphertext[..len].copy_from_slice(&expected_plaintext);
114 ldt_enc.encrypt(&mut ciphertext[..len], &XorPadder::from(xor_pad)).unwrap();
115 assert_eq!(&expected_ciphertext, &ciphertext[..len]);
116 }
117
118 Ok(())
119 }
120