dm_crypt: Extend unit tests to cover both ciphers
The current tests (that maps crypt device & checks if data is accessible
or not) only covered for the default cipher. Extend the tests for both
the ciphers (and correct key size).
This patch also add logic to validate_key_size depending on chosen
cipher in dm_rust lib.
Test: atest libdm_rust.test
Bug: 259253336
Change-Id: Ie32c0882db364ac296f0ed55991ce079bee0fbb8
diff --git a/libs/devicemapper/src/lib.rs b/libs/devicemapper/src/lib.rs
index ebe71e4..9069eb2 100644
--- a/libs/devicemapper/src/lib.rs
+++ b/libs/devicemapper/src/lib.rs
@@ -234,12 +234,28 @@
#[cfg(test)]
mod tests {
use super::*;
- use crypt::DmCryptTargetBuilder;
+ use crypt::{CipherType, DmCryptTargetBuilder};
+ use rustutils::system_properties;
use std::fs::{read, File, OpenOptions};
use std::io::Write;
- const KEY: &[u8; 32] = b"thirtytwobyteslongreallylongword";
- const DIFFERENT_KEY: &[u8; 32] = b"drowgnolyllaergnolsetybowtytriht";
+ // Just a logical set of keys to make testing easy. This has no real meaning.
+ struct KeySet<'a> {
+ cipher: CipherType,
+ key: &'a [u8],
+ different_key: &'a [u8],
+ }
+
+ const KEY_SET_XTS: KeySet = KeySet {
+ cipher: CipherType::AES256XTS,
+ key: b"sixtyfourbyteslongsentencearerarebutletsgiveitatrycantbethathard",
+ different_key: b"drahtahtebtnacyrtatievigsteltuberareraecnetnesgnolsetybruofytxis",
+ };
+ const KEY_SET_HCTR2: KeySet = KeySet {
+ cipher: CipherType::AES256HCTR2,
+ key: b"thirtytwobyteslongreallylongword",
+ different_key: b"drowgnolyllaergnolsetybowtytriht",
+ };
// Create a file in given temp directory with given size
fn prepare_tmpfile(test_dir: &Path, filename: &str, sz: u64) -> PathBuf {
@@ -254,14 +270,54 @@
f.write_all(data).unwrap();
}
+ // TODO(b/250880499): delete_device() doesn't really delete it even without DM_DEFERRED_REMOVE.
+ // Hence, we have to create a new device with a different name for each test. Retrying
+ // the test on same machine without reboot will also fail.
fn delete_device(dm: &DeviceMapper, name: &str) -> Result<()> {
dm.delete_device_deferred(name)?;
wait_for_path_disappears(Path::new(MAPPER_DEV_ROOT).join(name))?;
Ok(())
}
+ // TODO(b/260692911): Find a better way to skip a test instead of silently passing it.
+ fn is_hctr2_supported() -> bool {
+ // hctr2 is NOT enabled in kernel 5.10 or lower. We run Microdroid tests on kernel versions
+ // 5.10 or above & therefore, we don't really care to skip test on other versions.
+ if let Some(version) = system_properties::read("ro.kernel.version")
+ .expect("Unable to read system property ro.kernel.version")
+ {
+ version != "5.10"
+ } else {
+ panic!("Could not read property: kernel.version!!");
+ }
+ }
+
#[test]
- fn mapping_again_keeps_data() {
+ fn mapping_again_keeps_data_xts() {
+ mapping_again_keeps_data(&KEY_SET_XTS, "name1");
+ }
+
+ #[test]
+ fn mapping_again_keeps_data_hctr2() {
+ if !is_hctr2_supported() {
+ return;
+ }
+ mapping_again_keeps_data(&KEY_SET_HCTR2, "name2");
+ }
+ #[test]
+ fn data_inaccessible_with_diff_key_xts() {
+ data_inaccessible_with_diff_key(&KEY_SET_XTS, "name3");
+ }
+
+ #[test]
+ fn data_inaccessible_with_diff_key_hctr2() {
+ if !is_hctr2_supported() {
+ return;
+ }
+ data_inaccessible_with_diff_key(&KEY_SET_HCTR2, "name4");
+ }
+
+ fn mapping_again_keeps_data(keyset: &KeySet, device: &str) {
// This test creates 2 different crypt devices using same key backed by same data_device
// -> Write data on dev1 -> Check the data is visible & same on dev2
let dm = DeviceMapper::new().unwrap();
@@ -278,28 +334,33 @@
/*writable*/ true,
)
.unwrap();
+ let device_diff = device.to_owned() + "_diff";
+
scopeguard::defer! {
loopdevice::detach(&data_device).unwrap();
- _ = delete_device(&dm, "crypt1");
- _ = delete_device(&dm, "crypt2");
+ _ = delete_device(&dm, device);
+ _ = delete_device(&dm, &device_diff);
}
- let target =
- DmCryptTargetBuilder::default().data_device(&data_device, sz).key(KEY).build().unwrap();
+ let target = DmCryptTargetBuilder::default()
+ .data_device(&data_device, sz)
+ .cipher(keyset.cipher)
+ .key(keyset.key)
+ .build()
+ .unwrap();
- let mut crypt_device = dm.create_crypt_device("crypt1", &target).unwrap();
+ let mut crypt_device = dm.create_crypt_device(device, &target).unwrap();
write_to_dev(&crypt_device, inputimg);
// Recreate another device using same target spec & check if the content is the same
- crypt_device = dm.create_crypt_device("crypt2", &target).unwrap();
+ crypt_device = dm.create_crypt_device(&device_diff, &target).unwrap();
let crypt = read(crypt_device).unwrap();
assert_eq!(inputimg.len(), crypt.len()); // fail early if the size doesn't match
assert_eq!(inputimg, crypt.as_slice());
}
- #[test]
- fn data_inaccessible_with_diff_key() {
+ fn data_inaccessible_with_diff_key(keyset: &KeySet, device: &str) {
// This test creates 2 different crypt devices using different keys backed
// by same data_device -> Write data on dev1 -> Check the data is visible but not the same on dev2
let dm = DeviceMapper::new().unwrap();
@@ -316,26 +377,32 @@
/*writable*/ true,
)
.unwrap();
+ let device_diff = device.to_owned() + "_diff";
scopeguard::defer! {
loopdevice::detach(&data_device).unwrap();
- _ = delete_device(&dm, "crypt3");
- _ = delete_device(&dm, "crypt4");
+ _ = delete_device(&dm, device);
+ _ = delete_device(&dm, &device_diff);
}
- let target =
- DmCryptTargetBuilder::default().data_device(&data_device, sz).key(KEY).build().unwrap();
+ let target = DmCryptTargetBuilder::default()
+ .data_device(&data_device, sz)
+ .cipher(keyset.cipher)
+ .key(keyset.key)
+ .build()
+ .unwrap();
let target2 = DmCryptTargetBuilder::default()
.data_device(&data_device, sz)
- .key(DIFFERENT_KEY)
+ .cipher(keyset.cipher)
+ .key(keyset.different_key)
.build()
.unwrap();
- let mut crypt_device = dm.create_crypt_device("crypt3", &target).unwrap();
+ let mut crypt_device = dm.create_crypt_device(device, &target).unwrap();
write_to_dev(&crypt_device, inputimg);
// Recreate the crypt device again diff key & check if the content is changed
- crypt_device = dm.create_crypt_device("crypt4", &target2).unwrap();
+ crypt_device = dm.create_crypt_device(&device_diff, &target2).unwrap();
let crypt = read(crypt_device).unwrap();
assert_ne!(inputimg, crypt.as_slice());
}