From 989f6d00568de9489f06f2b2aa6fc99416551201 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Mon, 12 Aug 2024 18:32:03 +0200 Subject: [PATCH] Add support for creating LUKS HW-OPAL devices This adds support for creating encrypted devices using the OPAL self-encrypting drives. Anaconda only needs to make sure to pass the OPAL administrator passphrase to Blivet when creating the LUKS device, everything else will be taken care by either Blivet or pykickstart -- whether a "normal" or OPAL LUKS device will be created is controlled by the "--luks-version" kickstart option specified by the user which is passed "as is" to Blivet. --- .../modules/common/structures/partitioning.py | 19 +++++++++++++++++-- .../automatic/automatic_module.py | 5 +++++ .../automatic/automatic_partitioning.py | 1 + .../custom/custom_partitioning.py | 6 ++++-- .../test_module_part_automatic.py | 4 ++++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/pyanaconda/modules/common/structures/partitioning.py b/pyanaconda/modules/common/structures/partitioning.py index ddcb290b151..0ffef6bce41 100644 --- a/pyanaconda/modules/common/structures/partitioning.py +++ b/pyanaconda/modules/common/structures/partitioning.py @@ -47,6 +47,8 @@ def __init__(self): self._escrow_certificate = "" self._backup_passphrase_enabled = False + self._opal_admin_passphrase = "" + @property def partitioning_scheme(self) -> Int: """The partitioning scheme. @@ -255,12 +257,25 @@ def backup_passphrase_enabled(self) -> Bool: def backup_passphrase_enabled(self, enabled: Bool): self._backup_passphrase_enabled = enabled + @property + def opal_admin_passphrase(self) -> Str: + """OPAL admin passphrase to be used when configuring hardware encryption + + :return: a string with the OPAL admin passphrase + """ + return self._opal_admin_passphrase + + @opal_admin_passphrase.setter + def opal_admin_passphrase(self, value: Str): + self._opal_admin_passphrase = value + def __repr__(self): """Generate a string representation.""" return generate_string_from_data( self, - skip=["passphrase"], - add={"passphrase_set": bool(self.passphrase)} + skip=["passphrase", "opal_admin_passphrase"], + add={"passphrase_set": bool(self.passphrase), + "opal_admin_passphrase_set": bool(self.opal_admin_passphrase)} ) diff --git a/pyanaconda/modules/storage/partitioning/automatic/automatic_module.py b/pyanaconda/modules/storage/partitioning/automatic/automatic_module.py index e7ac5bff47a..4e3c7363851 100644 --- a/pyanaconda/modules/storage/partitioning/automatic/automatic_module.py +++ b/pyanaconda/modules/storage/partitioning/automatic/automatic_module.py @@ -92,6 +92,8 @@ def process_kickstart(self, data): request.escrow_certificate = data.autopart.escrowcert request.backup_passphrase_enabled = data.autopart.backuppassphrase + request.opal_admin_passphrase = data.autopart.hw_passphrase + self.set_request(request) def setup_kickstart(self, data): @@ -123,6 +125,9 @@ def setup_kickstart(self, data): data.autopart.escrowcert = self.request.escrow_certificate data.autopart.backuppassphrase = self.request.backup_passphrase_enabled + # Don't generate sensitive information. + data.autopart.hw_passphrase = "" + @property def request(self): """The partitioning request.""" diff --git a/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py b/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py index 5d8c4da3896..507e96c96bc 100644 --- a/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py +++ b/pyanaconda/modules/storage/partitioning/automatic/automatic_partitioning.py @@ -119,6 +119,7 @@ def _get_luks_format_args(storage, request): "pbkdf_args": pbkdf_args, "escrow_cert": escrow_cert, "add_backup_passphrase": request.backup_passphrase_enabled, + "opal_admin_passphrase": request.opal_admin_passphrase, } @staticmethod diff --git a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py index e59509975f1..4cf899c8ca9 100644 --- a/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py +++ b/pyanaconda/modules/storage/partitioning/custom/custom_partitioning.py @@ -410,7 +410,8 @@ def _execute_partition_data(self, storage, data, partition_data): escrow_cert=cert, add_backup_passphrase=partition_data.backuppassphrase, luks_version=partition_data.luks_version, - pbkdf_args=pbkdf_args + pbkdf_args=pbkdf_args, + opal_admin_passphrase=partition_data.hw_passphrase, ) luksdev = LUKSDevice( "luks%d" % storage.next_id, @@ -426,7 +427,8 @@ def _execute_partition_data(self, storage, data, partition_data): escrow_cert=cert, add_backup_passphrase=partition_data.backuppassphrase, luks_version=partition_data.luks_version, - pbkdf_args=pbkdf_args + pbkdf_args=pbkdf_args, + opal_admin_passphrase=partition_data.hw_passphrase, ) luksdev = LUKSDevice("luks%d" % storage.next_id, fmt=luksformat, diff --git a/tests/unit_tests/pyanaconda_tests/modules/storage/partitioning/test_module_part_automatic.py b/tests/unit_tests/pyanaconda_tests/modules/storage/partitioning/test_module_part_automatic.py index 384dd8e39ce..79aa2b16bc3 100644 --- a/tests/unit_tests/pyanaconda_tests/modules/storage/partitioning/test_module_part_automatic.py +++ b/tests/unit_tests/pyanaconda_tests/modules/storage/partitioning/test_module_part_automatic.py @@ -102,6 +102,7 @@ def test_request_property(self): 'pbkdf-iterations': get_variant(Int, 1000), 'escrow-certificate': get_variant(Str, 'file:///tmp/escrow.crt'), 'backup-passphrase-enabled': get_variant(Bool, True), + 'opal-admin-passphrase': get_variant(Str, '123456'), } self._check_dbus_property( "Request", @@ -200,6 +201,7 @@ def test_luks1_format_args(self): request.cipher = "aes-xts-plain64" request.escrow_certificate = "file:///tmp/escrow.crt" request.backup_passphrase_enabled = True + request.opal_admin_passphrase = "passphrase" args = AutomaticPartitioningTask._get_luks_format_args(storage, request) assert args == { @@ -209,6 +211,7 @@ def test_luks1_format_args(self): "pbkdf_args": None, "escrow_cert": "CERTIFICATE", "add_backup_passphrase": True, + "opal_admin_passphrase": "passphrase", } def test_luks2_format_args(self): @@ -231,6 +234,7 @@ def test_luks2_format_args(self): "luks_version": "luks2", "escrow_cert": None, "add_backup_passphrase": False, + "opal_admin_passphrase": "", } assert isinstance(pbkdf_args, LUKS2PBKDFArgs)