Add interface to change LUKS iteration time (#3634)

* Added User Interface to change iteration time for LUKS encryption

* removing unneessary try catch and imports

* used the same constant in luks.py file

* fixed issue with error firing in default value

* fixed ruf preview warnings

* preview even if its default value. (iter_time)

* check encryption type is not non before showing iter_time

* using _real_input with input_vp instead of _current_text

* proper check for enc_type

* added Interation time to outer menu preview

* removed (ms) from title. so that we don't need to translate "Iteration time" and "iteration time (ms)".

* a comment slipped in. this was not supposed to be in this pull

* fixed comparison str with EncryptionType
This commit is contained in:
Haouari haitam Kouider 2025-06-30 01:11:24 +00:00 committed by GitHub
parent 19459731ad
commit b3b00aa00f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 118 additions and 9 deletions

View File

@ -14,6 +14,7 @@ from ..exceptions import DiskError, SysCallError, UnknownFilesystemFormat
from ..general import SysCommand, SysCommandWorker
from ..luks import Luks2
from ..models.device_model import (
DEFAULT_ITER_TIME,
BDevice,
BtrfsMountOption,
DeviceModification,
@ -308,6 +309,7 @@ class DeviceHandler:
mapper_name: str | None,
enc_password: Password | None,
lock_after_create: bool = True,
iter_time: int = DEFAULT_ITER_TIME,
) -> Luks2:
luks_handler = Luks2(
dev_path,
@ -315,7 +317,7 @@ class DeviceHandler:
password=enc_password,
)
key_file = luks_handler.encrypt()
key_file = luks_handler.encrypt(iter_time=iter_time)
self.udev_sync()
@ -346,7 +348,7 @@ class DeviceHandler:
password=enc_conf.encryption_password,
)
key_file = luks_handler.encrypt()
key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time)
self.udev_sync()

View File

@ -3,6 +3,7 @@ from typing import override
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
from archinstall.lib.models.device_model import (
DEFAULT_ITER_TIME,
BtrfsOptions,
DiskEncryption,
DiskLayoutConfiguration,
@ -255,12 +256,15 @@ class DiskLayoutConfigurationMenu(AbstractSubMenu[DiskLayoutConfiguration]):
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
if enc_config:
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
output = tr('Encryption type') + f': {enc_type}\n'
enc_type = enc_config.encryption_type
output = tr('Encryption type') + f': {EncryptionType.type_to_text(enc_type)}\n'
if enc_config.encryption_password:
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'
if enc_type != EncryptionType.NoEncryption:
output += tr('Iteration time') + f': {enc_config.iter_time or DEFAULT_ITER_TIME}ms\n'
if enc_config.partitions:
output += f'Partitions: {len(enc_config.partitions)} selected\n'
elif enc_config.lvm_volumes:

View File

@ -11,13 +11,13 @@ from archinstall.lib.models.device_model import (
PartitionModification,
)
from archinstall.lib.translationhandler import tr
from archinstall.tui.curses_menu import SelectMenu
from archinstall.tui.curses_menu import EditMenu, SelectMenu
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
from archinstall.tui.result import ResultType
from archinstall.tui.types import Alignment, FrameProperties
from ..menu.abstract_menu import AbstractSubMenu
from ..models.device_model import Fido2Device
from ..models.device_model import DEFAULT_ITER_TIME, Fido2Device
from ..models.users import Password
from ..output import FormattedOutput
from ..utils.util import get_password
@ -65,6 +65,14 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
preview_action=self._preview,
key='encryption_password',
),
MenuItem(
text=tr('Iteration time'),
action=select_iteration_time,
value=self._enc_config.iter_time,
dependencies=[self._check_dep_enc_type],
preview_action=self._preview,
key='iter_time',
),
MenuItem(
text=tr('Partitions'),
action=lambda x: select_partitions_to_encrypt(self._device_modifications, x),
@ -120,6 +128,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
enc_type: EncryptionType | None = self._item_group.find_by_key('encryption_type').value
enc_password: Password | None = self._item_group.find_by_key('encryption_password').value
iter_time: int | None = self._item_group.find_by_key('iter_time').value
enc_partitions = self._item_group.find_by_key('partitions').value
enc_lvm_vols = self._item_group.find_by_key('lvm_volumes').value
@ -140,6 +149,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
partitions=enc_partitions,
lvm_volumes=enc_lvm_vols,
hsm_device=self._enc_config.hsm_device,
iter_time=iter_time or DEFAULT_ITER_TIME,
)
return None
@ -153,6 +163,9 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
if (enc_pwd := self._prev_password()) is not None:
output += f'\n{enc_pwd}'
if (iter_time := self._prev_iter_time()) is not None:
output += f'\n{iter_time}'
if (fido_device := self._prev_hsm()) is not None:
output += f'\n{fido_device}'
@ -214,6 +227,15 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
output += f' ({fido_device.manufacturer}, {fido_device.product})'
return f'{tr("HSM device")}: {output}'
def _prev_iter_time(self) -> str | None:
iter_time = self._item_group.find_by_key('iter_time').value
enc_type = self._item_group.find_by_key('encryption_type').value
if iter_time and enc_type != EncryptionType.NoEncryption:
return f'{tr("Iteration time")}: {iter_time}ms'
return None
def select_encryption_type(
device_modifications: list[DeviceModification],
@ -354,3 +376,42 @@ def select_lvm_vols_to_encrypt(
return volumes
return []
def select_iteration_time(preset: int | None = None) -> int | None:
header = tr('Enter iteration time for LUKS encryption (in milliseconds)') + '\n'
header += tr('Higher values increase security but slow down boot time') + '\n'
header += tr(f'Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000') + '\n'
def validate_iter_time(value: str | None) -> str | None:
if not value:
return None
try:
iter_time = int(value)
if iter_time < 100:
return tr('Iteration time must be at least 100ms')
if iter_time > 120000:
return tr('Iteration time must be at most 120000ms')
return None
except ValueError:
return tr('Please enter a valid number')
result = EditMenu(
tr('Iteration time'),
header=header,
alignment=Alignment.CENTER,
allow_skip=True,
default_text=str(preset) if preset else str(DEFAULT_ITER_TIME),
validator=validate_iter_time,
).input()
match result.type_:
case ResultType.Skip:
return preset
case ResultType.Selection:
if not result.text():
return preset
return int(result.text())
case ResultType.Reset:
return None

View File

@ -287,6 +287,7 @@ class FilesystemHandler:
vol.mapper_name,
enc_config.encryption_password,
lock_after_create,
iter_time=enc_config.iter_time,
)
enc_vols[vol] = luks_handler
@ -317,6 +318,7 @@ class FilesystemHandler:
part_mod.mapper_name,
enc_config.encryption_password,
lock_after_create=lock_after_create,
iter_time=enc_config.iter_time,
)
enc_mods[part_mod] = luks_handler

View File

@ -7,6 +7,7 @@ from subprocess import CalledProcessError
from types import TracebackType
from archinstall.lib.disk.utils import get_lsblk_info, umount
from archinstall.lib.models.device_model import DEFAULT_ITER_TIME
from .exceptions import DiskError, SysCallError
from .general import SysCommand, SysCommandWorker, generate_password, run
@ -76,7 +77,7 @@ class Luks2:
self,
key_size: int = 512,
hash_type: str = 'sha512',
iter_time: int = 10000,
iter_time: int = DEFAULT_ITER_TIME,
key_file: Path | None = None,
) -> Path | None:
debug(f'Luks2 encrypting: {self.luks_dev_path}')

View File

@ -19,6 +19,7 @@ from ..models.users import Password
from ..output import debug
ENC_IDENTIFIER = 'ainst'
DEFAULT_ITER_TIME = 10000
class DiskLayoutType(Enum):
@ -1471,6 +1472,7 @@ class _DiskEncryptionSerialization(TypedDict):
partitions: list[str]
lvm_volumes: list[str]
hsm_device: NotRequired[_Fido2DeviceSerialization]
iter_time: NotRequired[int]
@dataclass
@ -1480,6 +1482,7 @@ class DiskEncryption:
partitions: list[PartitionModification] = field(default_factory=list)
lvm_volumes: list[LvmVolume] = field(default_factory=list)
hsm_device: Fido2Device | None = None
iter_time: int = DEFAULT_ITER_TIME
def __post_init__(self) -> None:
if self.encryption_type in [EncryptionType.Luks, EncryptionType.LvmOnLuks] and not self.partitions:
@ -1504,6 +1507,9 @@ class DiskEncryption:
if self.hsm_device:
obj['hsm_device'] = self.hsm_device.json()
if self.iter_time != DEFAULT_ITER_TIME: # Only include if not default
obj['iter_time'] = self.iter_time
return obj
@classmethod
@ -1559,6 +1565,9 @@ class DiskEncryption:
if hsm := disk_encryption.get('hsm_device', None):
enc.hsm_device = Fido2Device.parse_arg(hsm)
if iter_time := disk_encryption.get('iter_time', None):
enc.iter_time = iter_time
return enc

View File

@ -959,6 +959,33 @@ msgstr ""
msgid "Encryption type"
msgstr ""
msgid "Iteration time"
msgstr ""
msgid "Enter iteration time for LUKS encryption (in milliseconds)"
msgstr ""
msgid "Higher values increase security but slow down boot time"
msgstr ""
msgid "Default: 10000ms, Recommended range: 1000-60000"
msgstr ""
msgid "Iteration time"
msgstr ""
msgid "Iteration time cannot be empty"
msgstr ""
msgid "Iteration time must be at least 100ms"
msgstr ""
msgid "Iteration time must be at most 120000ms"
msgstr ""
msgid "Please enter a valid number"
msgstr ""
msgid "Partitions"
msgstr ""

View File

@ -566,7 +566,10 @@ class EditMenu(AbstractCurses[str]):
entry = ViewportEntry(err, 0, 0, STYLE.ERROR)
self._info_vp.update([entry], 0)
self._set_default_info = False
self._real_input = ''
if self._hide_input:
self._real_input = ''
return None
return text
@ -586,7 +589,7 @@ class EditMenu(AbstractCurses[str]):
if self._set_default_info and self._info_vp:
self._info_vp.update([self._only_ascii_text], 0)
self._input_vp.edit(default_text=self._current_text)
self._input_vp.edit(default_text=self._real_input)
@override
def kickoff(self, win: curses.window) -> Result[str]: