Skip to content

Commit b3b00aa

Browse files
authored
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
1 parent 1945973 commit b3b00aa

8 files changed

Lines changed: 118 additions & 9 deletions

File tree

archinstall/lib/disk/device_handler.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from ..general import SysCommand, SysCommandWorker
1515
from ..luks import Luks2
1616
from ..models.device_model import (
17+
DEFAULT_ITER_TIME,
1718
BDevice,
1819
BtrfsMountOption,
1920
DeviceModification,
@@ -308,14 +309,15 @@ def encrypt(
308309
mapper_name: str | None,
309310
enc_password: Password | None,
310311
lock_after_create: bool = True,
312+
iter_time: int = DEFAULT_ITER_TIME,
311313
) -> Luks2:
312314
luks_handler = Luks2(
313315
dev_path,
314316
mapper_name=mapper_name,
315317
password=enc_password,
316318
)
317319

318-
key_file = luks_handler.encrypt()
320+
key_file = luks_handler.encrypt(iter_time=iter_time)
319321

320322
self.udev_sync()
321323

@@ -346,7 +348,7 @@ def format_encrypted(
346348
password=enc_conf.encryption_password,
347349
)
348350

349-
key_file = luks_handler.encrypt()
351+
key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time)
350352

351353
self.udev_sync()
352354

archinstall/lib/disk/disk_menu.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from archinstall.lib.disk.encryption_menu import DiskEncryptionMenu
55
from archinstall.lib.models.device_model import (
6+
DEFAULT_ITER_TIME,
67
BtrfsOptions,
78
DiskEncryption,
89
DiskLayoutConfiguration,
@@ -255,12 +256,15 @@ def _prev_disk_encryption(self, item: MenuItem) -> str | None:
255256
return tr('LVM disk encryption with more than 2 partitions is currently not supported')
256257

257258
if enc_config:
258-
enc_type = EncryptionType.type_to_text(enc_config.encryption_type)
259-
output = tr('Encryption type') + f': {enc_type}\n'
259+
enc_type = enc_config.encryption_type
260+
output = tr('Encryption type') + f': {EncryptionType.type_to_text(enc_type)}\n'
260261

261262
if enc_config.encryption_password:
262263
output += tr('Password') + f': {enc_config.encryption_password.hidden()}\n'
263264

265+
if enc_type != EncryptionType.NoEncryption:
266+
output += tr('Iteration time') + f': {enc_config.iter_time or DEFAULT_ITER_TIME}ms\n'
267+
264268
if enc_config.partitions:
265269
output += f'Partitions: {len(enc_config.partitions)} selected\n'
266270
elif enc_config.lvm_volumes:

archinstall/lib/disk/encryption_menu.py

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
PartitionModification,
1212
)
1313
from archinstall.lib.translationhandler import tr
14-
from archinstall.tui.curses_menu import SelectMenu
14+
from archinstall.tui.curses_menu import EditMenu, SelectMenu
1515
from archinstall.tui.menu_item import MenuItem, MenuItemGroup
1616
from archinstall.tui.result import ResultType
1717
from archinstall.tui.types import Alignment, FrameProperties
1818

1919
from ..menu.abstract_menu import AbstractSubMenu
20-
from ..models.device_model import Fido2Device
20+
from ..models.device_model import DEFAULT_ITER_TIME, Fido2Device
2121
from ..models.users import Password
2222
from ..output import FormattedOutput
2323
from ..utils.util import get_password
@@ -65,6 +65,14 @@ def _define_menu_options(self) -> list[MenuItem]:
6565
preview_action=self._preview,
6666
key='encryption_password',
6767
),
68+
MenuItem(
69+
text=tr('Iteration time'),
70+
action=select_iteration_time,
71+
value=self._enc_config.iter_time,
72+
dependencies=[self._check_dep_enc_type],
73+
preview_action=self._preview,
74+
key='iter_time',
75+
),
6876
MenuItem(
6977
text=tr('Partitions'),
7078
action=lambda x: select_partitions_to_encrypt(self._device_modifications, x),
@@ -120,6 +128,7 @@ def run(self, additional_title: str | None = None) -> DiskEncryption | None:
120128

121129
enc_type: EncryptionType | None = self._item_group.find_by_key('encryption_type').value
122130
enc_password: Password | None = self._item_group.find_by_key('encryption_password').value
131+
iter_time: int | None = self._item_group.find_by_key('iter_time').value
123132
enc_partitions = self._item_group.find_by_key('partitions').value
124133
enc_lvm_vols = self._item_group.find_by_key('lvm_volumes').value
125134

@@ -140,6 +149,7 @@ def run(self, additional_title: str | None = None) -> DiskEncryption | None:
140149
partitions=enc_partitions,
141150
lvm_volumes=enc_lvm_vols,
142151
hsm_device=self._enc_config.hsm_device,
152+
iter_time=iter_time or DEFAULT_ITER_TIME,
143153
)
144154

145155
return None
@@ -153,6 +163,9 @@ def _preview(self, item: MenuItem) -> str | None:
153163
if (enc_pwd := self._prev_password()) is not None:
154164
output += f'\n{enc_pwd}'
155165

166+
if (iter_time := self._prev_iter_time()) is not None:
167+
output += f'\n{iter_time}'
168+
156169
if (fido_device := self._prev_hsm()) is not None:
157170
output += f'\n{fido_device}'
158171

@@ -214,6 +227,15 @@ def _prev_hsm(self) -> str | None:
214227
output += f' ({fido_device.manufacturer}, {fido_device.product})'
215228
return f'{tr("HSM device")}: {output}'
216229

230+
def _prev_iter_time(self) -> str | None:
231+
iter_time = self._item_group.find_by_key('iter_time').value
232+
enc_type = self._item_group.find_by_key('encryption_type').value
233+
234+
if iter_time and enc_type != EncryptionType.NoEncryption:
235+
return f'{tr("Iteration time")}: {iter_time}ms'
236+
237+
return None
238+
217239

218240
def select_encryption_type(
219241
device_modifications: list[DeviceModification],
@@ -354,3 +376,42 @@ def select_lvm_vols_to_encrypt(
354376
return volumes
355377

356378
return []
379+
380+
381+
def select_iteration_time(preset: int | None = None) -> int | None:
382+
header = tr('Enter iteration time for LUKS encryption (in milliseconds)') + '\n'
383+
header += tr('Higher values increase security but slow down boot time') + '\n'
384+
header += tr(f'Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000') + '\n'
385+
386+
def validate_iter_time(value: str | None) -> str | None:
387+
if not value:
388+
return None
389+
390+
try:
391+
iter_time = int(value)
392+
if iter_time < 100:
393+
return tr('Iteration time must be at least 100ms')
394+
if iter_time > 120000:
395+
return tr('Iteration time must be at most 120000ms')
396+
return None
397+
except ValueError:
398+
return tr('Please enter a valid number')
399+
400+
result = EditMenu(
401+
tr('Iteration time'),
402+
header=header,
403+
alignment=Alignment.CENTER,
404+
allow_skip=True,
405+
default_text=str(preset) if preset else str(DEFAULT_ITER_TIME),
406+
validator=validate_iter_time,
407+
).input()
408+
409+
match result.type_:
410+
case ResultType.Skip:
411+
return preset
412+
case ResultType.Selection:
413+
if not result.text():
414+
return preset
415+
return int(result.text())
416+
case ResultType.Reset:
417+
return None

archinstall/lib/disk/filesystem.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ def _encrypt_lvm_vols(
287287
vol.mapper_name,
288288
enc_config.encryption_password,
289289
lock_after_create,
290+
iter_time=enc_config.iter_time,
290291
)
291292

292293
enc_vols[vol] = luks_handler
@@ -317,6 +318,7 @@ def _encrypt_partitions(
317318
part_mod.mapper_name,
318319
enc_config.encryption_password,
319320
lock_after_create=lock_after_create,
321+
iter_time=enc_config.iter_time,
320322
)
321323

322324
enc_mods[part_mod] = luks_handler

archinstall/lib/luks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from types import TracebackType
88

99
from archinstall.lib.disk.utils import get_lsblk_info, umount
10+
from archinstall.lib.models.device_model import DEFAULT_ITER_TIME
1011

1112
from .exceptions import DiskError, SysCallError
1213
from .general import SysCommand, SysCommandWorker, generate_password, run
@@ -76,7 +77,7 @@ def encrypt(
7677
self,
7778
key_size: int = 512,
7879
hash_type: str = 'sha512',
79-
iter_time: int = 10000,
80+
iter_time: int = DEFAULT_ITER_TIME,
8081
key_file: Path | None = None,
8182
) -> Path | None:
8283
debug(f'Luks2 encrypting: {self.luks_dev_path}')

archinstall/lib/models/device_model.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from ..output import debug
2020

2121
ENC_IDENTIFIER = 'ainst'
22+
DEFAULT_ITER_TIME = 10000
2223

2324

2425
class DiskLayoutType(Enum):
@@ -1471,6 +1472,7 @@ class _DiskEncryptionSerialization(TypedDict):
14711472
partitions: list[str]
14721473
lvm_volumes: list[str]
14731474
hsm_device: NotRequired[_Fido2DeviceSerialization]
1475+
iter_time: NotRequired[int]
14741476

14751477

14761478
@dataclass
@@ -1480,6 +1482,7 @@ class DiskEncryption:
14801482
partitions: list[PartitionModification] = field(default_factory=list)
14811483
lvm_volumes: list[LvmVolume] = field(default_factory=list)
14821484
hsm_device: Fido2Device | None = None
1485+
iter_time: int = DEFAULT_ITER_TIME
14831486

14841487
def __post_init__(self) -> None:
14851488
if self.encryption_type in [EncryptionType.Luks, EncryptionType.LvmOnLuks] and not self.partitions:
@@ -1504,6 +1507,9 @@ def json(self) -> _DiskEncryptionSerialization:
15041507
if self.hsm_device:
15051508
obj['hsm_device'] = self.hsm_device.json()
15061509

1510+
if self.iter_time != DEFAULT_ITER_TIME: # Only include if not default
1511+
obj['iter_time'] = self.iter_time
1512+
15071513
return obj
15081514

15091515
@classmethod
@@ -1559,6 +1565,9 @@ def parse_arg(
15591565
if hsm := disk_encryption.get('hsm_device', None):
15601566
enc.hsm_device = Fido2Device.parse_arg(hsm)
15611567

1568+
if iter_time := disk_encryption.get('iter_time', None):
1569+
enc.iter_time = iter_time
1570+
15621571
return enc
15631572

15641573

archinstall/locales/base.pot

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,33 @@ msgstr ""
959959
msgid "Encryption type"
960960
msgstr ""
961961

962+
msgid "Iteration time"
963+
msgstr ""
964+
965+
msgid "Enter iteration time for LUKS encryption (in milliseconds)"
966+
msgstr ""
967+
968+
msgid "Higher values increase security but slow down boot time"
969+
msgstr ""
970+
971+
msgid "Default: 10000ms, Recommended range: 1000-60000"
972+
msgstr ""
973+
974+
msgid "Iteration time"
975+
msgstr ""
976+
977+
msgid "Iteration time cannot be empty"
978+
msgstr ""
979+
980+
msgid "Iteration time must be at least 100ms"
981+
msgstr ""
982+
983+
msgid "Iteration time must be at most 120000ms"
984+
msgstr ""
985+
986+
msgid "Please enter a valid number"
987+
msgstr ""
988+
962989
msgid "Partitions"
963990
msgstr ""
964991

archinstall/tui/curses_menu.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,10 @@ def _get_input_text(self) -> str | None:
566566
entry = ViewportEntry(err, 0, 0, STYLE.ERROR)
567567
self._info_vp.update([entry], 0)
568568
self._set_default_info = False
569-
self._real_input = ''
569+
570+
if self._hide_input:
571+
self._real_input = ''
572+
570573
return None
571574

572575
return text
@@ -586,7 +589,7 @@ def _draw(self) -> None:
586589
if self._set_default_info and self._info_vp:
587590
self._info_vp.update([self._only_ascii_text], 0)
588591

589-
self._input_vp.edit(default_text=self._current_text)
592+
self._input_vp.edit(default_text=self._real_input)
590593

591594
@override
592595
def kickoff(self, win: curses.window) -> Result[str]:

0 commit comments

Comments
 (0)