| import os |
| import subprocess |
| |
| import infra.basetest |
| |
| |
| class TestCryptSetup(infra.basetest.BRTest): |
| # A specific configuration is needed for using cryptsetup: |
| # - A kernel config fragment enables all the parts needed for |
| # mounting a LUKS2 volume, |
| # - Enable OpenSSL for cryptsetup crypto backend library, |
| # - Enable e2fsprog for formatting a ext4 filesystem. |
| kern_frag = \ |
| infra.filepath("tests/package/test_cryptsetup/linux-cryptsetup.fragment") |
| config = \ |
| f""" |
| BR2_aarch64=y |
| BR2_TOOLCHAIN_EXTERNAL=y |
| BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" |
| BR2_LINUX_KERNEL=y |
| BR2_LINUX_KERNEL_CUSTOM_VERSION=y |
| BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.1.75" |
| BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y |
| BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" |
| BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}" |
| BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y |
| BR2_PACKAGE_CRYPTSETUP=y |
| BR2_PACKAGE_E2FSPROGS=y |
| BR2_PACKAGE_OPENSSL=y |
| BR2_TARGET_ROOTFS_CPIO=y |
| BR2_TARGET_ROOTFS_CPIO_GZIP=y |
| # BR2_TARGET_ROOTFS_TAR is not set |
| """ |
| |
| def test_run(self): |
| disk_file = os.path.join(self.builddir, "images", "disk.img") |
| self.emulator.logfile.write(f"Creating disk image: {disk_file}") |
| subprocess.check_call( |
| ["dd", "if=/dev/urandom", f"of={disk_file}", "bs=1M", "count=20"], |
| stdout=self.emulator.logfile, |
| stderr=self.emulator.logfile) |
| |
| img = os.path.join(self.builddir, "images", "rootfs.cpio.gz") |
| kern = os.path.join(self.builddir, "images", "Image") |
| |
| bootargs = ["console=ttyAMA0"] |
| qemu_opts = ["-M", "virt", "-cpu", "cortex-a57", "-m", "256M", |
| "-initrd", img, |
| "-drive", f"file={disk_file},if=virtio,format=raw"] |
| self.emulator.boot(arch="aarch64", |
| kernel=kern, |
| kernel_cmdline=bootargs, |
| options=qemu_opts) |
| self.emulator.login() |
| |
| # Check the program can execute. |
| self.assertRunOk("cryptsetup --version") |
| |
| passkey = "ThisIsAPassKey." |
| dev = "/dev/vda" |
| dm_name = "luks-vol" |
| dm_dev = f"/dev/mapper/{dm_name}" |
| mnt_pt = "/mnt/secure-volume" |
| |
| # Check the device is NOT detected as a LUKS volume, because |
| # it is not formatted yet. |
| is_luks_cmd = f"cryptsetup isLuks {dev}" |
| _, ret = self.emulator.run(is_luks_cmd) |
| self.assertNotEqual(ret, 0) |
| |
| # Format the LUKS volume. |
| cmd = f"echo {passkey} | cryptsetup luksFormat {dev}" |
| self.assertRunOk(cmd, timeout=30) |
| |
| # Check the device is now detected as a LUKS device. |
| self.assertRunOk(is_luks_cmd) |
| |
| # Dump LUKS device header information. |
| self.assertRunOk(f"cryptsetup luksDump {dev}") |
| |
| # Open the LUKS device |
| luks_open_cmd = f"echo {passkey} | " |
| luks_open_cmd += f"cryptsetup open --type luks {dev} {dm_name}" |
| self.assertRunOk(luks_open_cmd, timeout=10) |
| |
| # Create an ext4 filesystem. |
| self.assertRunOk(f"mke2fs -T ext4 {dm_dev}", timeout=10) |
| |
| # Create the mount point directory. |
| self.assertRunOk(f"mkdir {mnt_pt}") |
| |
| # Mount the LUKS device. |
| mount_cmd = f"mount {dm_dev} {mnt_pt}" |
| self.assertRunOk(mount_cmd) |
| |
| # Create a plain text file in the mounted filesystem. |
| msg = "This is a plain text message" |
| plain_file = f"{mnt_pt}/file.txt" |
| self.assertRunOk(f"echo '{msg}' > {plain_file}") |
| |
| # Unmount. |
| self.assertRunOk(f"umount {mnt_pt}") |
| |
| # We are supposed to see our plain text message on the |
| # dm-crypt device. |
| self.assertRunOk(f"grep -Fq '{msg}' {dm_dev}", timeout=10) |
| |
| # Close the LUKS device |
| self.assertRunOk(f"cryptsetup close {dm_name}") |
| |
| # We are NOT supposed to find our plain text message on the |
| # encrypted storage device. |
| _, ret = self.emulator.run(f"grep -Fq '{msg}' {dev}", timeout=10) |
| self.assertNotEqual(ret, 0) |
| |
| # Try to open LUKS volume with a wrong password. This is |
| # expected to fail. |
| cmd = f"echo 'Wrong{passkey}' | " |
| cmd += f"cryptsetup open --type luks {dev} {dm_name}" |
| _, ret = self.emulator.run(cmd, timeout=10) |
| self.assertNotEqual(ret, 0) |
| |
| # Check the device-mapper device was NOT created (since we |
| # tried to open it with a wrong password). |
| self.assertRunOk(f"test ! -e {dm_dev}") |
| |
| # Reopen the LUKS device, with the good passkey this time... |
| self.assertRunOk(luks_open_cmd, timeout=10) |
| |
| # ...remount... |
| self.assertRunOk(mount_cmd) |
| |
| # ...and read back our plain text file. We check we get back |
| # our original message. |
| out, ret = self.emulator.run(f"cat {plain_file}") |
| self.assertEqual(ret, 0) |
| self.assertEqual(out[0], msg) |