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