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:
parent
19459731ad
commit
b3b00aa00f
|
|
@ -14,6 +14,7 @@ from ..exceptions import DiskError, SysCallError, UnknownFilesystemFormat
|
||||||
from ..general import SysCommand, SysCommandWorker
|
from ..general import SysCommand, SysCommandWorker
|
||||||
from ..luks import Luks2
|
from ..luks import Luks2
|
||||||
from ..models.device_model import (
|
from ..models.device_model import (
|
||||||
|
DEFAULT_ITER_TIME,
|
||||||
BDevice,
|
BDevice,
|
||||||
BtrfsMountOption,
|
BtrfsMountOption,
|
||||||
DeviceModification,
|
DeviceModification,
|
||||||
|
|
@ -308,6 +309,7 @@ class DeviceHandler:
|
||||||
mapper_name: str | None,
|
mapper_name: str | None,
|
||||||
enc_password: Password | None,
|
enc_password: Password | None,
|
||||||
lock_after_create: bool = True,
|
lock_after_create: bool = True,
|
||||||
|
iter_time: int = DEFAULT_ITER_TIME,
|
||||||
) -> Luks2:
|
) -> Luks2:
|
||||||
luks_handler = Luks2(
|
luks_handler = Luks2(
|
||||||
dev_path,
|
dev_path,
|
||||||
|
|
@ -315,7 +317,7 @@ class DeviceHandler:
|
||||||
password=enc_password,
|
password=enc_password,
|
||||||
)
|
)
|
||||||
|
|
||||||
key_file = luks_handler.encrypt()
|
key_file = luks_handler.encrypt(iter_time=iter_time)
|
||||||
|
|
||||||
self.udev_sync()
|
self.udev_sync()
|
||||||
|
|
||||||
|
|
@ -346,7 +348,7 @@ class DeviceHandler:
|
||||||
password=enc_conf.encryption_password,
|
password=enc_conf.encryption_password,
|
||||||
)
|
)
|
||||||
|
|
||||||
key_file = luks_handler.encrypt()
|
key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time)
|
||||||
|
|
||||||
self.udev_sync()
|
self.udev_sync()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from typing import override
|
||||||
|
|
||||||
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
|
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
|
||||||
from archinstall.lib.models.device_model import (
|
from archinstall.lib.models.device_model import (
|
||||||
|
DEFAULT_ITER_TIME,
|
||||||
BtrfsOptions,
|
BtrfsOptions,
|
||||||
DiskEncryption,
|
DiskEncryption,
|
||||||
DiskLayoutConfiguration,
|
DiskLayoutConfiguration,
|
||||||
|
|
@ -255,12 +256,15 @@ class DiskLayoutConfigurationMenu(AbstractSubMenu[DiskLayoutConfiguration]):
|
||||||
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
|
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
|
||||||
|
|
||||||
if enc_config:
|
if enc_config:
|
||||||
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
|
enc_type = enc_config.encryption_type
|
||||||
output = tr('Encryption type') + f': {enc_type}\n'
|
output = tr('Encryption type') + f': {EncryptionType.type_to_text(enc_type)}\n'
|
||||||
|
|
||||||
if enc_config.encryption_password:
|
if enc_config.encryption_password:
|
||||||
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'
|
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:
|
if enc_config.partitions:
|
||||||
output += f'Partitions: {len(enc_config.partitions)} selected\n'
|
output += f'Partitions: {len(enc_config.partitions)} selected\n'
|
||||||
elif enc_config.lvm_volumes:
|
elif enc_config.lvm_volumes:
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ from archinstall.lib.models.device_model import (
|
||||||
PartitionModification,
|
PartitionModification,
|
||||||
)
|
)
|
||||||
from archinstall.lib.translationhandler import tr
|
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.menu_item import MenuItem, MenuItemGroup
|
||||||
from archinstall.tui.result import ResultType
|
from archinstall.tui.result import ResultType
|
||||||
from archinstall.tui.types import Alignment, FrameProperties
|
from archinstall.tui.types import Alignment, FrameProperties
|
||||||
|
|
||||||
from ..menu.abstract_menu import AbstractSubMenu
|
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 ..models.users import Password
|
||||||
from ..output import FormattedOutput
|
from ..output import FormattedOutput
|
||||||
from ..utils.util import get_password
|
from ..utils.util import get_password
|
||||||
|
|
@ -65,6 +65,14 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
|
||||||
preview_action=self._preview,
|
preview_action=self._preview,
|
||||||
key='encryption_password',
|
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(
|
MenuItem(
|
||||||
text=tr('Partitions'),
|
text=tr('Partitions'),
|
||||||
action=lambda x: select_partitions_to_encrypt(self._device_modifications, x),
|
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_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
|
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_partitions = self._item_group.find_by_key('partitions').value
|
||||||
enc_lvm_vols = self._item_group.find_by_key('lvm_volumes').value
|
enc_lvm_vols = self._item_group.find_by_key('lvm_volumes').value
|
||||||
|
|
||||||
|
|
@ -140,6 +149,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
|
||||||
partitions=enc_partitions,
|
partitions=enc_partitions,
|
||||||
lvm_volumes=enc_lvm_vols,
|
lvm_volumes=enc_lvm_vols,
|
||||||
hsm_device=self._enc_config.hsm_device,
|
hsm_device=self._enc_config.hsm_device,
|
||||||
|
iter_time=iter_time or DEFAULT_ITER_TIME,
|
||||||
)
|
)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
@ -153,6 +163,9 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
|
||||||
if (enc_pwd := self._prev_password()) is not None:
|
if (enc_pwd := self._prev_password()) is not None:
|
||||||
output += f'\n{enc_pwd}'
|
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:
|
if (fido_device := self._prev_hsm()) is not None:
|
||||||
output += f'\n{fido_device}'
|
output += f'\n{fido_device}'
|
||||||
|
|
||||||
|
|
@ -214,6 +227,15 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]):
|
||||||
output += f' ({fido_device.manufacturer}, {fido_device.product})'
|
output += f' ({fido_device.manufacturer}, {fido_device.product})'
|
||||||
return f'{tr("HSM device")}: {output}'
|
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(
|
def select_encryption_type(
|
||||||
device_modifications: list[DeviceModification],
|
device_modifications: list[DeviceModification],
|
||||||
|
|
@ -354,3 +376,42 @@ def select_lvm_vols_to_encrypt(
|
||||||
return volumes
|
return volumes
|
||||||
|
|
||||||
return []
|
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
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,7 @@ class FilesystemHandler:
|
||||||
vol.mapper_name,
|
vol.mapper_name,
|
||||||
enc_config.encryption_password,
|
enc_config.encryption_password,
|
||||||
lock_after_create,
|
lock_after_create,
|
||||||
|
iter_time=enc_config.iter_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
enc_vols[vol] = luks_handler
|
enc_vols[vol] = luks_handler
|
||||||
|
|
@ -317,6 +318,7 @@ class FilesystemHandler:
|
||||||
part_mod.mapper_name,
|
part_mod.mapper_name,
|
||||||
enc_config.encryption_password,
|
enc_config.encryption_password,
|
||||||
lock_after_create=lock_after_create,
|
lock_after_create=lock_after_create,
|
||||||
|
iter_time=enc_config.iter_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
enc_mods[part_mod] = luks_handler
|
enc_mods[part_mod] = luks_handler
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from subprocess import CalledProcessError
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
|
|
||||||
from archinstall.lib.disk.utils import get_lsblk_info, umount
|
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 .exceptions import DiskError, SysCallError
|
||||||
from .general import SysCommand, SysCommandWorker, generate_password, run
|
from .general import SysCommand, SysCommandWorker, generate_password, run
|
||||||
|
|
@ -76,7 +77,7 @@ class Luks2:
|
||||||
self,
|
self,
|
||||||
key_size: int = 512,
|
key_size: int = 512,
|
||||||
hash_type: str = 'sha512',
|
hash_type: str = 'sha512',
|
||||||
iter_time: int = 10000,
|
iter_time: int = DEFAULT_ITER_TIME,
|
||||||
key_file: Path | None = None,
|
key_file: Path | None = None,
|
||||||
) -> Path | None:
|
) -> Path | None:
|
||||||
debug(f'Luks2 encrypting: {self.luks_dev_path}')
|
debug(f'Luks2 encrypting: {self.luks_dev_path}')
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ from ..models.users import Password
|
||||||
from ..output import debug
|
from ..output import debug
|
||||||
|
|
||||||
ENC_IDENTIFIER = 'ainst'
|
ENC_IDENTIFIER = 'ainst'
|
||||||
|
DEFAULT_ITER_TIME = 10000
|
||||||
|
|
||||||
|
|
||||||
class DiskLayoutType(Enum):
|
class DiskLayoutType(Enum):
|
||||||
|
|
@ -1471,6 +1472,7 @@ class _DiskEncryptionSerialization(TypedDict):
|
||||||
partitions: list[str]
|
partitions: list[str]
|
||||||
lvm_volumes: list[str]
|
lvm_volumes: list[str]
|
||||||
hsm_device: NotRequired[_Fido2DeviceSerialization]
|
hsm_device: NotRequired[_Fido2DeviceSerialization]
|
||||||
|
iter_time: NotRequired[int]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|
@ -1480,6 +1482,7 @@ class DiskEncryption:
|
||||||
partitions: list[PartitionModification] = field(default_factory=list)
|
partitions: list[PartitionModification] = field(default_factory=list)
|
||||||
lvm_volumes: list[LvmVolume] = field(default_factory=list)
|
lvm_volumes: list[LvmVolume] = field(default_factory=list)
|
||||||
hsm_device: Fido2Device | None = None
|
hsm_device: Fido2Device | None = None
|
||||||
|
iter_time: int = DEFAULT_ITER_TIME
|
||||||
|
|
||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
if self.encryption_type in [EncryptionType.Luks, EncryptionType.LvmOnLuks] and not self.partitions:
|
if self.encryption_type in [EncryptionType.Luks, EncryptionType.LvmOnLuks] and not self.partitions:
|
||||||
|
|
@ -1504,6 +1507,9 @@ class DiskEncryption:
|
||||||
if self.hsm_device:
|
if self.hsm_device:
|
||||||
obj['hsm_device'] = self.hsm_device.json()
|
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
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
@ -1559,6 +1565,9 @@ class DiskEncryption:
|
||||||
if hsm := disk_encryption.get('hsm_device', None):
|
if hsm := disk_encryption.get('hsm_device', None):
|
||||||
enc.hsm_device = Fido2Device.parse_arg(hsm)
|
enc.hsm_device = Fido2Device.parse_arg(hsm)
|
||||||
|
|
||||||
|
if iter_time := disk_encryption.get('iter_time', None):
|
||||||
|
enc.iter_time = iter_time
|
||||||
|
|
||||||
return enc
|
return enc
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -959,6 +959,33 @@ msgstr ""
|
||||||
msgid "Encryption type"
|
msgid "Encryption type"
|
||||||
msgstr ""
|
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"
|
msgid "Partitions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -566,7 +566,10 @@ class EditMenu(AbstractCurses[str]):
|
||||||
entry = ViewportEntry(err, 0, 0, STYLE.ERROR)
|
entry = ViewportEntry(err, 0, 0, STYLE.ERROR)
|
||||||
self._info_vp.update([entry], 0)
|
self._info_vp.update([entry], 0)
|
||||||
self._set_default_info = False
|
self._set_default_info = False
|
||||||
self._real_input = ''
|
|
||||||
|
if self._hide_input:
|
||||||
|
self._real_input = ''
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
@ -586,7 +589,7 @@ class EditMenu(AbstractCurses[str]):
|
||||||
if self._set_default_info and self._info_vp:
|
if self._set_default_info and self._info_vp:
|
||||||
self._info_vp.update([self._only_ascii_text], 0)
|
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
|
@override
|
||||||
def kickoff(self, win: curses.window) -> Result[str]:
|
def kickoff(self, win: curses.window) -> Result[str]:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue