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)]
16
17 use crypto_provider::aes::BLOCK_SIZE;
18 use crypto_provider::{CryptoProvider, CryptoRng};
19 use crypto_provider_default::CryptoProviderImpl;
20 use ldt::*;
21 use ldt_tbc::TweakableBlockCipher;
22 use rand::rngs::StdRng;
23 use rand::{distributions, Rng as _, SeedableRng as _};
24 use rand_ext::{random_bytes, random_vec};
25 use xts_aes::{XtsAes128, XtsAes256};
26
27 #[test]
roundtrip_normal_padder()28 fn roundtrip_normal_padder() {
29 let mut rng = <CryptoProviderImpl as CryptoProvider>::CryptoRng::new();
30 let mut rc_rng = rand::rngs::StdRng::from_entropy();
31 let plaintext_len_range = distributions::Uniform::new_inclusive(BLOCK_SIZE, BLOCK_SIZE * 2 - 1);
32
33 for _ in 0..100_000 {
34 if rc_rng.gen() {
35 let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
36 do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
37 LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
38 LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
39 &DefaultPadder,
40 &mut rng,
41 &plaintext_len_range,
42 )
43 } else {
44 let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
45 do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
46 LdtEncryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
47 LdtDecryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
48 &DefaultPadder,
49 &mut rng,
50 &plaintext_len_range,
51 )
52 };
53 }
54 }
55
56 #[test]
roundtrip_xor_padder()57 fn roundtrip_xor_padder() {
58 let mut rng = <CryptoProviderImpl as CryptoProvider>::CryptoRng::new();
59 let mut rc_rng = rand::rngs::StdRng::from_entropy();
60 let plaintext_len_range = distributions::Uniform::new_inclusive(BLOCK_SIZE, BLOCK_SIZE * 2 - 1);
61
62 for _ in 0..100_000 {
63 let padder: XorPadder<BLOCK_SIZE> =
64 random_bytes::<BLOCK_SIZE, CryptoProviderImpl>(&mut rng).into();
65
66 if rc_rng.gen() {
67 let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
68 do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
69 LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
70 LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
71 &padder,
72 &mut rng,
73 &plaintext_len_range,
74 )
75 } else {
76 let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
77 do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
78 LdtEncryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
79 LdtDecryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
80 &padder,
81 &mut rng,
82 &plaintext_len_range,
83 )
84 };
85 }
86 }
87
do_roundtrip< const B: usize, T: TweakableBlockCipher<B>, P: Padder<B, T>, M: Mix, C: CryptoProvider, >( ldt_enc: LdtEncryptCipher<B, T, M>, ldt_dec: LdtDecryptCipher<B, T, M>, padder: &P, rng: &mut C::CryptoRng, plaintext_len_range: &distributions::Uniform<usize>, )88 fn do_roundtrip<
89 const B: usize,
90 T: TweakableBlockCipher<B>,
91 P: Padder<B, T>,
92 M: Mix,
93 C: CryptoProvider,
94 >(
95 ldt_enc: LdtEncryptCipher<B, T, M>,
96 ldt_dec: LdtDecryptCipher<B, T, M>,
97 padder: &P,
98 rng: &mut C::CryptoRng,
99 plaintext_len_range: &distributions::Uniform<usize>,
100 ) {
101 let mut rng_rc = StdRng::from_entropy();
102 let len = rng_rc.sample(plaintext_len_range);
103 let plaintext = random_vec::<C>(rng, len);
104
105 let mut ciphertext = plaintext.clone();
106 ldt_enc.encrypt(&mut ciphertext, padder).unwrap();
107
108 assert_eq!(plaintext.len(), ciphertext.len());
109 assert_ne!(plaintext, ciphertext);
110
111 ldt_dec.decrypt(&mut ciphertext, padder).unwrap();
112 assert_eq!(plaintext, ciphertext);
113 }
114