blob: b5f930e35d273867933c080640a65031956b2061 [file] [log] [blame]
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use crypto_provider::aes::BLOCK_SIZE;
use crypto_provider::{CryptoProvider, CryptoRng};
use crypto_provider_default::CryptoProviderImpl;
use ldt::*;
use ldt_tbc::TweakableBlockCipher;
use rand::rngs::StdRng;
use rand::{self, distributions, Rng as _, SeedableRng as _};
use rand_ext::{random_bytes, random_vec};
use xts_aes::{XtsAes128, XtsAes256};
#[test]
fn roundtrip_normal_padder() {
let mut rng = <CryptoProviderImpl as CryptoProvider>::CryptoRng::new();
let mut rc_rng = rand::rngs::StdRng::from_entropy();
let plaintext_len_range = distributions::Uniform::new_inclusive(BLOCK_SIZE, BLOCK_SIZE * 2 - 1);
for _ in 0..100_000 {
if rc_rng.gen() {
let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
&DefaultPadder,
&mut rng,
&plaintext_len_range,
)
} else {
let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
LdtEncryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
LdtDecryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
&DefaultPadder,
&mut rng,
&plaintext_len_range,
)
};
}
}
#[test]
fn roundtrip_xor_padder() {
let mut rng = <CryptoProviderImpl as CryptoProvider>::CryptoRng::new();
let mut rc_rng = rand::rngs::StdRng::from_entropy();
// 2 bytes smaller because we're using a 2 byte salt
let plaintext_len_range =
distributions::Uniform::new_inclusive(BLOCK_SIZE, BLOCK_SIZE * 2 - 1 - 2);
for _ in 0..100_000 {
let padder: XorPadder<BLOCK_SIZE> =
random_bytes::<BLOCK_SIZE, CryptoProviderImpl>(&mut rng).into();
if rc_rng.gen() {
let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
LdtEncryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
LdtDecryptCipher::<16, XtsAes128<CryptoProviderImpl>, Swap>::new(&ldt_key),
&padder,
&mut rng,
&plaintext_len_range,
)
} else {
let ldt_key = LdtKey::from_random::<CryptoProviderImpl>(&mut rng);
do_roundtrip::<16, _, _, _, CryptoProviderImpl>(
LdtEncryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
LdtDecryptCipher::<16, XtsAes256<CryptoProviderImpl>, Swap>::new(&ldt_key),
&padder,
&mut rng,
&plaintext_len_range,
)
};
}
}
fn 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>,
) {
let mut rng_rc = StdRng::from_entropy();
let len = rng_rc.sample(plaintext_len_range);
let plaintext = random_vec::<C>(rng, len);
let mut ciphertext = plaintext.clone();
ldt_enc.encrypt(&mut ciphertext, padder).unwrap();
assert_eq!(plaintext.len(), ciphertext.len());
assert_ne!(plaintext, ciphertext);
ldt_dec.decrypt(&mut ciphertext, padder).unwrap();
assert_eq!(plaintext, ciphertext);
}