def test_format(self): """Verify that formating device as LUKS works""" # no passphrase nor keyfile with self.assertRaises(GLib.GError): BlockDev.crypto_luks_format(self.loop_dev, None, 0, None, None, 0) # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, PASSWD, None, 0) self.assertTrue(succ) # create with a keyfile succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0) self.assertTrue(succ)
def test_luks_open_rw(self): """Verify that a LUKS device can be activated as RW as well as RO""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) # tests that we can write something to the raw LUKS device succ = BlockDev.utils_exec_and_report_error(["dd", "if=/dev/zero", "of=/dev/mapper/libblockdevTestLUKS", "bs=1M", "count=1"]) self.assertTrue(succ) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ) # now try the same with LUKS device opened as RO succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, True) self.assertTrue(succ) # tests that we can write something to the raw LUKS device with self.assertRaises(GLib.GError): BlockDev.utils_exec_and_report_error(["dd", "if=/dev/zero", "of=/dev/mapper/libblockdevTestLUKS", "bs=1M", "count=1"]) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_luks_open_close(self): """Verify that opening/closing LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, self.keyfile, 0) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open("/non/existing/device", "libblockdevTestLUKS", PASSWD, None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", "wrong-passhprase", None, False) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, "wrong-keyfile", False) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) # use the full /dev/mapper/ path succ = BlockDev.crypto_luks_close("/dev/mapper/libblockdevTestLUKS") self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", None, self.keyfile, False) self.assertTrue(succ) # use just the LUKS device name succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_backup_passphrase(self): """Verify that a backup passphrase can be created for a device""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) escrow_dir = tempfile.mkdtemp(prefix='libblockdev_test_escrow') self.addCleanup(shutil.rmtree, escrow_dir) backup_passphrase = BlockDev.crypto_generate_backup_passphrase() with open(self.public_cert, 'rb') as cert_file: succ = BlockDev.crypto_escrow_device(self.loop_dev, PASSWD, cert_file.read(), escrow_dir, backup_passphrase) self.assertTrue(succ) # Find the backup passphrase escrow_backup_passphrase = "%s/%s-escrow-backup-passphrase" % (escrow_dir, BlockDev.crypto_luks_uuid(self.loop_dev)) self.assertTrue(os.path.isfile(escrow_backup_passphrase)) # Check that the encrypted file contains what we put in env = os.environ env.update({"LC_ALL": "C"}) passphrase = subprocess.check_output( ['volume_key', '--secrets', '-d', self.nss_dir, escrow_backup_passphrase], env=env) passphrase = passphrase.strip().split()[1].decode('ascii') self.assertEqual(passphrase, backup_passphrase) # Check that the backup passphrase works succ = BlockDev.crypto_luks_open(self.loop_dev, 'libblockdevTestLUKS', backup_passphrase, None) self.assertTrue(succ)
def test_luks_status(self): """Verify that LUKS device status reporting works""" with self.assertRaises(GLib.GError): BlockDev.crypto_luks_status("/non/existing/device") succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) # use the full /dev/mapper path status = BlockDev.crypto_luks_status("/dev/mapper/libblockdevTestLUKS") self.assertEqual(status, "active") # use just the LUKS device name status = BlockDev.crypto_luks_status("libblockdevTestLUKS") self.assertEqual(status, "active") succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_status("libblockdevTestLUKS")
def test_luks2_integrity(self): """Verify that we can get create a LUKS 2 device with integrity""" if not BlockDev.utils_have_kernel_module("dm-integrity"): self.skipTest('dm-integrity kernel module not available, skipping.') extra = BlockDev.CryptoLUKSExtra() extra.integrity = "hmac(sha256)" succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 512, PASSWD, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) info = BlockDev.crypto_integrity_info("libblockdevTestLUKS") self.assertIsNotNone(info) self.assertEqual(info.algorithm, "hmac(sha256)") # get integrity device dm name _ret, int_name, _err = run_command('ls /sys/block/%s/holders/' % self.loop_dev.split("/")[-1]) self.assertTrue(int_name) # true == not empty tag_size = read_file("/sys/block/%s/integrity/tag_size" % int_name) self.assertEqual(info.tag_size, int(tag_size)) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_luks2_format(self): """Verify that we can get information about a LUKS 2 device""" extra = BlockDev.CryptoLUKSExtra() extra.sector_size = 4096 succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 256, PASSWD, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) info = BlockDev.crypto_luks_info("libblockdevTestLUKS") self.assertIsNotNone(info) self.assertEqual(info.version, BlockDev.CryptoLUKSVersion.LUKS2) self.assertEqual(info.cipher, "aes") self.assertEqual(info.mode, "cbc-essiv:sha256") self.assertEqual(info.backing_device, self.loop_dev) self.assertEqual(info.sector_size, 4096) _ret, uuid, _err = run_command("blkid -p -ovalue -sUUID %s" % self.loop_dev) self.assertEqual(info.uuid, uuid) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_change_key(self): """Verify that changing key in LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_change_key(self.loop_dev, PASSWD, PASSWD2) self.assertTrue(succ)
def test_luks_format(self): """Verify that formating device as LUKS works""" # no passphrase nor keyfile with self.assertRaises(GLib.GError): BlockDev.crypto_luks_format(self.loop_dev, None, 0, None, None, 0) # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, PASSWD, None, 0) self.assertTrue(succ) # create with a keyfile succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0) self.assertTrue(succ) # the simple case with password blob succ = BlockDev.crypto_luks_format_blob(self.loop_dev, "aes-xts-plain64", 0, [ord(c) for c in PASSWD], 0) self.assertTrue(succ)
def test_error_locale_key(self): """Verify that the error msg is locale agnostic""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) locale.setlocale(locale.LC_ALL, "cs_CZ.UTF-8") try: BlockDev.crypto_luks_remove_key(self.loop_dev, "wrong-passphrase", None) except GLib.GError as e: self.assertIn("Operation not permitted", str(e))
def test_add_key(self): """Verify that adding key to LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_add_key(self.loop_dev, "wrong-passphrase", None, PASSWD2, None) succ = BlockDev.crypto_luks_add_key(self.loop_dev, PASSWD, None, PASSWD2, None) self.assertTrue(succ)
def test_get_uuid(self): """Verify that getting LUKS device UUID works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) uuid = BlockDev.crypto_luks_uuid(self.loop_dev) self.assertTrue(uuid) with self.assertRaises(GLib.GError): uuid = BlockDev.crypto_luks_uuid(self.loop_dev2)
def test_is_luks(self): """Verify that LUKS device recognition works""" with self.assertRaises(GLib.GError): BlockDev.crypto_device_is_luks("/non/existing/device") succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) is_luks = BlockDev.crypto_device_is_luks(self.loop_dev) self.assertTrue(is_luks) is_luks = BlockDev.crypto_device_is_luks(self.loop_dev2) self.assertFalse(is_luks)
def test_luks_open_rw(self): """Verify that opened LUKS device is usable (activated as RW)""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None) self.assertTrue(succ) # tests that we can write something to the raw LUKS device succ = BlockDev.utils_exec_and_report_error(["dd", "if=/dev/zero", "of=/dev/mapper/libblockdevTestLUKS", "bs=1M", "count=1"]) self.assertTrue(succ) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_format(self): """Verify that formating device as LUKS works""" # no passphrase nor keyfile with self.assertRaises(GLib.GError): BlockDev.crypto_luks_format(self.loop_dev, None, 0, None, None, 0) # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, PASSWD, None, 0) self.assertTrue(succ) # create with a keyfile succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0) self.assertTrue(succ) # the simple case with password blob succ = BlockDev.crypto_luks_format_blob(self.loop_dev, "aes-cbc-essiv:sha256", 0, [ord(c) for c in PASSWD], 0) self.assertTrue(succ)
def test_remove_key(self): """Verify that removing key from LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_add_key(self.loop_dev, PASSWD, None, PASSWD2, None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_remove_key(self.loop_dev, "wrong-passphrase", None) succ = BlockDev.crypto_luks_remove_key(self.loop_dev, PASSWD, None) self.assertTrue(succ)
def test_add_key(self): """Verify that adding key to LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_add_key(self.loop_dev, "wrong-passphrase", None, PASSWD2, None) succ = BlockDev.crypto_luks_add_key(self.loop_dev, PASSWD, None, PASSWD2, None) self.assertTrue(succ) succ = BlockDev.crypto_luks_add_key_blob(self.loop_dev, [ord(c) for c in PASSWD2], [ord(c) for c in PASSWD3]) self.assertTrue(succ)
def test_luks_open_rw(self): """Verify that opened LUKS device is usable (activated as RW)""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None) self.assertTrue(succ) # tests that we can write something to the raw LUKS device succ = BlockDev.utils_exec_and_report_error([ "dd", "if=/dev/zero", "of=/dev/mapper/libblockdevTestLUKS", "bs=1M", "count=1" ]) self.assertTrue(succ) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_remove_key(self): """Verify that removing key from LUKS device works""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_add_key(self.loop_dev, PASSWD, None, PASSWD2, None) self.assertTrue(succ) succ = BlockDev.crypto_luks_add_key(self.loop_dev, PASSWD, None, PASSWD3, None) self.assertTrue(succ) with self.assertRaises(GLib.GError): BlockDev.crypto_luks_remove_key(self.loop_dev, "wrong-passphrase", None) succ = BlockDev.crypto_luks_remove_key(self.loop_dev, PASSWD, None) self.assertTrue(succ) succ = BlockDev.crypto_luks_remove_key_blob(self.loop_dev, [ord(c) for c in PASSWD2]) self.assertTrue(succ)
def test_resize(self): """Verify that resizing LUKS device works""" # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, PASSWD, None, 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) # resize to 512 KiB (1024 * 512B sectors) succ = BlockDev.crypto_luks_resize("libblockdevTestLUKS", 1024) self.assertTrue(succ) # resize back to full size succ = BlockDev.crypto_luks_resize("libblockdevTestLUKS", 0) self.assertTrue(succ) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def test_escrow_packet(self): """Verify that an escrow packet can be created for a device""" succ = BlockDev.crypto_luks_format(self.loop_dev, None, 0, PASSWD, None, 0) self.assertTrue(succ) escrow_dir = tempfile.mkdtemp(prefix='libblockdev_test_escrow') self.addCleanup(shutil.rmtree, escrow_dir) with open(self.public_cert, 'rb') as cert_file: succ = BlockDev.crypto_escrow_device(self.loop_dev, PASSWD, cert_file.read(), escrow_dir, None) self.assertTrue(succ) # Find the escrow packet escrow_packet_file = '%s/%s-escrow' % (escrow_dir, BlockDev.crypto_luks_uuid(self.loop_dev)) self.assertTrue(os.path.isfile(escrow_packet_file)) # Use the volume_key utility (see note in setUp about why not python) # to decrypt the escrow packet and restore access to the volume under # a new passphrase # Just use the existing temp directory to output the re-encrypted packet # PASSWD2 is the passphrase of the new escrow packet p = subprocess.Popen(['volume_key', '--reencrypt', '-b', '-d', self.nss_dir, escrow_packet_file, '-o', '%s/escrow-out' % escrow_dir], stdin=subprocess.PIPE) p.communicate(input=('%s\0%s\0' % (PASSWD2, PASSWD2)).encode('utf-8')) if p.returncode != 0: raise subprocess.CalledProcessError(p.returncode, 'volume_key') # Restore access to the volume # PASSWD3 is the new passphrase for the LUKS device p = subprocess.Popen(['volume_key', '--restore', '-b', self.loop_dev, '%s/escrow-out' % escrow_dir], stdin=subprocess.PIPE) p.communicate(input=('%s\0%s\0%s\0' % (PASSWD2, PASSWD3, PASSWD3)).encode('utf-8')) if p.returncode != 0: raise subprocess.CalledProcessError(p.returncode, 'volume_key') # Open the volume with the new passphrase succ = BlockDev.crypto_luks_open(self.loop_dev, 'libblockdevTestLUKS', PASSWD3, None) self.assertTrue(succ)
def test_luks2_integrity(self): """Verify that we can get create a LUKS 2 device with integrity""" if not BlockDev.utils_have_kernel_module("dm-integrity"): self.skipTest( 'dm-integrity kernel module not available, skipping.') extra = BlockDev.CryptoLUKSExtra() extra.integrity = "hmac(sha256)" succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 512, PASSWD, None, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) succ = BlockDev.crypto_luks_open(self.loop_dev, "libblockdevTestLUKS", PASSWD, None, False) self.assertTrue(succ) info = BlockDev.crypto_integrity_info("libblockdevTestLUKS") self.assertIsNotNone(info) self.assertEqual(info.algorithm, "hmac(sha256)") # get integrity device dm name _ret, int_name, _err = run_command('ls /sys/block/%s/holders/' % self.loop_dev.split("/")[-1]) self.assertTrue(int_name) # true == not empty tag_size = read_file("/sys/block/%s/integrity/tag_size" % int_name) self.assertEqual(info.tag_size, int(tag_size)) succ = BlockDev.crypto_luks_close("libblockdevTestLUKS") self.assertTrue(succ)
def _luks2_format(self, device, passphrase, keyfile): return BlockDev.crypto_luks_format(device, None, 0, passphrase, keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, None)
def _luks_format(self, device, passphrase, keyfile): return BlockDev.crypto_luks_format(device, None, 0, passphrase, keyfile, 0)
def test_luks2_format(self): """Verify that formating device as LUKS 2 works""" # no passphrase nor keyfile with self.assertRaises(GLib.GError): BlockDev.crypto_luks_format(self.loop_dev, None, 0, None, None, 0) # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, PASSWD, None, 0) self.assertTrue(succ) # create with a keyfile succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0) self.assertTrue(succ) # the simple case with password blob succ = BlockDev.crypto_luks_format_blob(self.loop_dev, "aes-cbc-essiv:sha256", 0, [ord(c) for c in PASSWD], 0) self.assertTrue(succ) # simple case with extra options extra = BlockDev.CryptoLUKSExtra(label="blockdevLUKS") succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, label, _err = run_command("lsblk -oLABEL -n %s" % self.loop_dev) self.assertEqual(label, "blockdevLUKS") # different key derivation function pbkdf = BlockDev.CryptoLUKSPBKDF(type="pbkdf2") extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"PBKDF:\s*(\S+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(m.group(1), "pbkdf2") # different options for argon2 -- all parameters set pbkdf = BlockDev.CryptoLUKSPBKDF(type="argon2id", max_memory_kb=100 * 1024, iterations=10, parallel_threads=1) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"PBKDF:\s*(\S+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(m.group(1), "argon2id") m = re.search(r"Memory:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) # both iterations and memory is set --> cryptsetup will use exactly max_memory_kb self.assertEqual(int(m.group(1)), 100 * 1024) m = re.search(r"Threads:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 1) m = re.search(r"Time cost:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 10) # different options for argon2 -- only memory set pbkdf = BlockDev.CryptoLUKSPBKDF(max_memory_kb=100 * 1024) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"Memory:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) # only memory is set -> cryptsetup will run a benchmark and use # at most max_memory_kb self.assertLessEqual(int(m.group(1)), 100 * 1024) # different options for argon2 -- only miterations set pbkdf = BlockDev.CryptoLUKSPBKDF(iterations=5) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-cbc-essiv:sha256", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"Time cost:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 5)
def test_luks2_format(self): """Verify that formating device as LUKS 2 works""" # no passphrase nor keyfile with self.assertRaises(GLib.GError): BlockDev.crypto_luks_format(self.loop_dev, None, 0, None, None, 0) # the simple case with password succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, PASSWD, None, 0) self.assertTrue(succ) # create with a keyfile succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0) self.assertTrue(succ) # the simple case with password blob succ = BlockDev.crypto_luks_format_blob(self.loop_dev, "aes-xts-plain64", 0, [ord(c) for c in PASSWD], 0) self.assertTrue(succ) # simple case with extra options extra = BlockDev.CryptoLUKSExtra(label="blockdevLUKS") succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"Label:\s*(\S+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get label information from:\n%s %s" % (out, err)) self.assertEqual(m.group(1), "blockdevLUKS") # different key derivation function pbkdf = BlockDev.CryptoLUKSPBKDF(type="pbkdf2") extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"PBKDF:\s*(\S+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(m.group(1), "pbkdf2") # different options for argon2 -- all parameters set pbkdf = BlockDev.CryptoLUKSPBKDF(type="argon2id", max_memory_kb=100*1024, iterations=10, parallel_threads=1) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"PBKDF:\s*(\S+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(m.group(1), "argon2id") m = re.search(r"Memory:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) # both iterations and memory is set --> cryptsetup will use exactly max_memory_kb self.assertEqual(int(m.group(1)), 100*1024) m = re.search(r"Threads:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 1) m = re.search(r"Time cost:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 10) # different options for argon2 -- only memory set pbkdf = BlockDev.CryptoLUKSPBKDF(max_memory_kb=100*1024) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"Memory:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) # only memory is set -> cryptsetup will run a benchmark and use # at most max_memory_kb self.assertLessEqual(int(m.group(1)), 100*1024) # different options for argon2 -- only miterations set pbkdf = BlockDev.CryptoLUKSPBKDF(iterations=5) extra = BlockDev.CryptoLUKSExtra(pbkdf=pbkdf) succ = BlockDev.crypto_luks_format(self.loop_dev, "aes-xts-plain64", 0, None, self.keyfile, 0, BlockDev.CryptoLUKSVersion.LUKS2, extra) self.assertTrue(succ) _ret, out, err = run_command("cryptsetup luksDump %s" % self.loop_dev) m = re.search(r"Time cost:\s*(\d+)\s*", out) if not m or len(m.groups()) != 1: self.fail("Failed to get pbkdf information from:\n%s %s" % (out, err)) self.assertEqual(int(m.group(1)), 5)