Skip to content

Commit 332bc2c

Browse files
authored
Merge pull request #123 from desultory/dev
Detect aes kmods from the LUKS header
2 parents 123c9ae + 5b07496 commit 332bc2c

File tree

1 file changed

+27
-11
lines changed

1 file changed

+27
-11
lines changed

src/ugrd/crypto/cryptsetup.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__author__ = "desultory"
2-
__version__ = "3.5.0"
2+
__version__ = "3.6.1"
33

44
from pathlib import Path
55

@@ -195,14 +195,31 @@ def _read_cryptsetup_header(self, mapped_name: str, slave_device: str = None) ->
195195
self.logger.warning("Cannot read detached LUKS header for validation: %s" % e)
196196
return {}
197197

198-
def _check_luks_header_aes(self, luks_info: dict) -> dict:
199-
"""Checks for aes requirements in the LUKS header"""
198+
def _detect_luks_aes_module(self, luks_cipher_name: str) -> None:
199+
"""Using the cipher name from the LUKS header, detects the corresponding kernel module."""
200+
if luks_cipher_name.startswith("aes"):
201+
self["_kmod_auto"] = "aes" # Try to enable the aesni module for any aes type
202+
203+
aes_type = luks_cipher_name.split("-")[1] # Get the cipher type from the name
204+
self["_kmod_auto"] = aes_type # Add the aes type to the kernel modules
205+
206+
crypto_name = f"{aes_type}(aes)" # Format the name like the /proc/crypto entry
207+
crypto_config = self["_crypto_ciphers"][crypto_name]
208+
if crypto_config["module"] == "kernel":
209+
self.logger.debug("Cipher kernel modules are builtin: %s" % crypto_name)
210+
else:
211+
self.logger.info("[%s] Adding kernel module for LUKS cipher: %s" % (crypto_name, crypto_config["module"]))
212+
self["_kmod_auto"] = crypto_config["module"]
213+
214+
def _detect_luks_header_aes(self, luks_info: dict) -> dict:
215+
"""Checks the cipher type in the LUKS header, reads /proc/crypto to find the
216+
corresponding driver. If it's not builtin, adds the module to the kernel modules."""
200217
for keyslot in luks_info.get("keyslots", {}).values():
201-
if keyslot.get("area", {}).get("encryption") == "aes-xts-plain64":
202-
return True
218+
if keyslot.get("area", {}).get("encryption").startswith("aes"):
219+
_detect_luks_aes_module(self, keyslot["area"]["encryption"])
203220
for segment in luks_info.get("segments", {}).values():
204-
if segment.get("encryption") == "aes-xts-plain64":
205-
return True
221+
if segment.get("encryption").startswith("aes"):
222+
_detect_luks_aes_module(self, segment["encryption"])
206223

207224
def _detect_luks_header_sha(self, luks_info: dict) -> dict:
208225
"""Reads the hash algorithm from the LUKS header,
@@ -229,10 +246,7 @@ def _validate_cryptsetup_header(self, mapped_name: str) -> None:
229246
if luks_info.get("uuid") != uuid:
230247
raise ValueError("[%s] LUKS UUID mismatch, found '%s', expected: %s" % (mapped_name, luks_info["uuid"], uuid))
231248

232-
if _check_luks_header_aes(self, luks_info):
233-
self.logger.debug("[%s] LUKS uses aes-xts-plain64" % mapped_name)
234-
self["kernel_modules"] = self._crypto_ciphers["xts(aes)"]["driver"] # Placeholder, this driver is wrong!
235-
249+
_detect_luks_header_aes(self, luks_info)
236250
_detect_luks_header_sha(self, luks_info)
237251

238252
if not self["argon2"]: # if argon support was not detected, check if the header wants it
@@ -302,6 +316,8 @@ def get_value(line):
302316
continue # Skip lines until a name is found
303317
elif line.startswith("driver"):
304318
self._crypto_ciphers[current_name]["driver"] = get_value(line)
319+
elif line.startswith("module"):
320+
self._crypto_ciphers[current_name]["module"] = get_value(line)
305321

306322

307323
@contains("validate", "Skipping cryptsetup configuration validation.", log_level=30)

0 commit comments

Comments
 (0)