From 228a86c474bc019307ecaa95a135fa4d7ac4ef2a Mon Sep 17 00:00:00 2001 From: Alperen42v <243298691+Alperen42v@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:23:54 +0300 Subject: [PATCH] fix the problems for filesystems --- archinstall/lib/disk/device_handler.py | 5 ++-- archinstall/lib/disk/encryption_menu.py | 30 +++------------------ archinstall/lib/disk/luks.py | 33 +++++++---------------- archinstall/lib/models/device.py | 35 +++++-------------------- 4 files changed, 21 insertions(+), 82 deletions(-) diff --git a/archinstall/lib/disk/device_handler.py b/archinstall/lib/disk/device_handler.py index d86ab062..f2f79088 100644 --- a/archinstall/lib/disk/device_handler.py +++ b/archinstall/lib/disk/device_handler.py @@ -282,7 +282,6 @@ class DeviceHandler: lock_after_create: bool = True, iter_time: int = DEFAULT_ITER_TIME, cipher: str = DEFAULT_CIPHER, - integrity: str | None = None, ) -> Luks2: luks_handler = Luks2( dev_path, @@ -290,7 +289,7 @@ class DeviceHandler: password=enc_password, ) - key_file = luks_handler.encrypt(iter_time=iter_time, cipher=cipher, integrity=integrity) + key_file = luks_handler.encrypt(iter_time=iter_time, cipher=cipher) udev_sync() @@ -321,7 +320,7 @@ class DeviceHandler: password=enc_conf.encryption_password, ) - key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time, cipher=enc_conf.cipher, integrity=enc_conf.integrity) + key_file = luks_handler.encrypt(iter_time=enc_conf.iter_time, cipher=enc_conf.cipher) udev_sync() diff --git a/archinstall/lib/disk/encryption_menu.py b/archinstall/lib/disk/encryption_menu.py index 3c0cd059..30ae1a7f 100644 --- a/archinstall/lib/disk/encryption_menu.py +++ b/archinstall/lib/disk/encryption_menu.py @@ -7,7 +7,6 @@ from archinstall.lib.menu.helpers import Input, Selection, Table from archinstall.lib.menu.menu_helper import MenuHelper from archinstall.lib.menu.util import get_password from archinstall.lib.models.device import ( - AEAD_CIPHERS, DEFAULT_CIPHER, DEFAULT_ITER_TIME, DeviceModification, @@ -114,17 +113,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]): return [] async def _select_cipher(self, preset: str | None) -> str | None: - cipher = await select_encryption_cipher(preset) - - # AEAD ciphers (e.g. chacha20-random) require LUKS2 + --integrity; - # keep the underlying DiskEncryption.integrity in sync automatically - # so the user never has to set it manually or risk an invalid combo. - if cipher in AEAD_CIPHERS: - self._enc_config.integrity = AEAD_CIPHERS[cipher] - else: - self._enc_config.integrity = None - - return cipher + return await select_encryption_cipher(preset) def _check_dep_enc_type(self) -> bool: enc_type: EncryptionType | None = self._item_group.find_by_key('encryption_type').value @@ -168,9 +157,6 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]): enc_partitions = [] if enc_type != EncryptionType.NO_ENCRYPTION and enc_password and (enc_partitions or enc_lvm_vols): - cipher = cipher or DEFAULT_CIPHER - integrity = AEAD_CIPHERS.get(cipher) - return DiskEncryption( encryption_password=enc_password, encryption_type=enc_type, @@ -178,8 +164,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]): lvm_volumes=enc_lvm_vols, hsm_device=enc_config.hsm_device, iter_time=iter_time or DEFAULT_ITER_TIME, - cipher=cipher, - integrity=integrity, + cipher=cipher or DEFAULT_CIPHER, ) return None @@ -231,13 +216,7 @@ class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]): def _prev_cipher(self, item: MenuItem) -> str | None: cipher = self._item_group.find_by_key('cipher').value if cipher: - output = f'{tr("Encryption cipher")}: {cipher}' - - if cipher in AEAD_CIPHERS: - integrity = AEAD_CIPHERS[cipher] - output += f'\n{tr("Integrity")}: {integrity} ({tr("requires LUKS2")})' - - return output + return f'{tr("Encryption cipher")}: {cipher}' return None def _prev_partitions(self, item: MenuItem) -> str | None: @@ -452,9 +431,6 @@ async def select_iteration_time(preset: int | None = None) -> int | None: async def select_encryption_cipher(preset: str | None = None) -> str | None: # Regular block-cipher modes: accepted directly by `cryptsetup --cipher`. - # AEAD modes (see AEAD_CIPHERS in models/device.py) need LUKS2 and a - # separate --integrity value, which DiskEncryption.__post_init__ and - # DiskEncryptionMenu._select_cipher fill in automatically. options = [ 'aes-xts-plain64', 'aes-cbc-essiv:sha256', diff --git a/archinstall/lib/disk/luks.py b/archinstall/lib/disk/luks.py index 8788262e..ff2e529b 100644 --- a/archinstall/lib/disk/luks.py +++ b/archinstall/lib/disk/luks.py @@ -3,13 +3,12 @@ from dataclasses import dataclass from pathlib import Path from subprocess import CalledProcessError from types import TracebackType -from typing import cast from archinstall.lib.command import SysCommand, SysCommandWorker, run from archinstall.lib.disk.utils import get_lsblk_info, umount from archinstall.lib.exceptions import DiskError, SysCallError from archinstall.lib.log import debug, info -from archinstall.lib.models.device import AEAD_CIPHERS, DEFAULT_CIPHER, DEFAULT_ITER_TIME +from archinstall.lib.models.device import CIPHER_KEY_SIZES, DEFAULT_CIPHER, DEFAULT_ITER_TIME from archinstall.lib.models.users import Password from archinstall.lib.utils.util import generate_password @@ -75,19 +74,15 @@ class Luks2: iter_time: int = DEFAULT_ITER_TIME, key_file: Path | None = None, cipher: str = DEFAULT_CIPHER, - integrity: str | None = None, ) -> Path | None: debug(f'Luks2 encrypting: {self.luks_dev_path}') key_file_arg, passphrase = self._get_passphrase_args(key_file) - is_aead = cipher in AEAD_CIPHERS - - if is_aead and not integrity: - integrity = AEAD_CIPHERS[cipher] - - if integrity and not is_aead: - raise DiskError(f'Integrity option "{integrity}" is only valid for AEAD ciphers, not "{cipher}"') + # Resolve the correct key size for this cipher. + # XTS mode uses two keys (e.g. 256+256 = 512 bits for aes-xts-plain64), + # CBC mode uses a single key (max 256 bits for aes-cbc-essiv:sha256). + resolved_key_size = CIPHER_KEY_SIZES.get(cipher, key_size) cmd = [ 'cryptsetup', @@ -99,22 +94,12 @@ class Luks2: 'argon2id', '--cipher', cipher, + '--hash', + hash_type, + '--key-size', + str(resolved_key_size), ] - if is_aead: - # AEAD ciphers (e.g. chacha20-random) authenticate each sector via - # --integrity and do not take --hash or a fixed --key-size the same - # way length-preserving modes (aes-xts-plain64 etc.) do; key size is - # derived from the cipher/integrity combination by cryptsetup itself. - cmd += ['--integrity', cast(str, integrity)] - else: - cmd += [ - '--hash', - hash_type, - '--key-size', - str(key_size), - ] - cmd += [ '--iter-time', str(iter_time), diff --git a/archinstall/lib/models/device.py b/archinstall/lib/models/device.py index 50d82068..b492762f 100644 --- a/archinstall/lib/models/device.py +++ b/archinstall/lib/models/device.py @@ -1464,15 +1464,15 @@ class EncryptionType(StrEnum): DEFAULT_CIPHER = 'aes-xts-plain64' -# AEAD (Authenticated Encryption with Associated Data) ciphers require LUKS2 -# and a separate --integrity parameter; they cannot be used like normal -# block-cipher + chainmode + ivmode strings (e.g. aes-xts-plain64). -# Mapping: cipher value used in --cipher -> required --integrity value -AEAD_CIPHERS: dict[str, str] = { - 'aes-gcm-random': 'aead', +# XTS mode splits the key in two halves so needs double the bits. +# CBC/ECB use the key directly — max 256 bit. +CIPHER_KEY_SIZES: dict[str, int] = { + 'aes-xts-plain64': 512, # XTS: 256+256 + 'aes-cbc-essiv:sha256': 256, # CBC: single 256-bit key + 'serpent-xts-plain64': 512, # XTS: 256+256 + 'twofish-xts-plain64': 512, # XTS: 256+256 } - class _DiskEncryptionSerialization(TypedDict): encryption_type: str partitions: list[str] @@ -1480,7 +1480,6 @@ class _DiskEncryptionSerialization(TypedDict): hsm_device: NotRequired[_Fido2DeviceSerialization] iter_time: NotRequired[int] cipher: NotRequired[str] - integrity: NotRequired[str] @dataclass @@ -1492,7 +1491,6 @@ class DiskEncryption: hsm_device: Fido2Device | None = None iter_time: int = DEFAULT_ITER_TIME cipher: str = DEFAULT_CIPHER - integrity: str | None = None def __post_init__(self) -> None: if self.encryption_type in [EncryptionType.LUKS, EncryptionType.LVM_ON_LUKS] and not self.partitions: @@ -1501,20 +1499,6 @@ class DiskEncryption: if self.encryption_type == EncryptionType.LUKS_ON_LVM and not self.lvm_volumes: raise ValueError('LuksOnLvm encryption require LMV volumes to be defined') - # AEAD ciphers (chacha20-random, aes-gcm-random) are only valid on LUKS2 - # and require --integrity to be set; auto-fill it if missing so the - # cryptsetup call downstream doesn't end up with an invalid combination. - if self.cipher in AEAD_CIPHERS: - required_integrity = AEAD_CIPHERS[self.cipher] - if not self.integrity: - self.integrity = required_integrity - elif self.integrity != required_integrity: - raise ValueError( - f'Cipher {self.cipher!r} requires integrity {required_integrity!r}, got {self.integrity!r}' - ) - elif self.integrity: - raise ValueError(f'Integrity option is only valid for AEAD ciphers, not {self.cipher!r}') - def should_generate_encryption_file(self, dev: PartitionModification | LvmVolume) -> bool: if isinstance(dev, PartitionModification): return dev in self.partitions and dev.mountpoint != Path('/') @@ -1537,9 +1521,6 @@ class DiskEncryption: if self.cipher != DEFAULT_CIPHER: # Only include if not default obj['cipher'] = self.cipher - if self.integrity: - obj['integrity'] = self.integrity - return obj @staticmethod @@ -1585,7 +1566,6 @@ class DiskEncryption: volumes.append(vol) cipher = disk_encryption.get('cipher', None) or DEFAULT_CIPHER - integrity = disk_encryption.get('integrity', None) enc = cls( EncryptionType(disk_encryption['encryption_type']), @@ -1593,7 +1573,6 @@ class DiskEncryption: enc_partitions, volumes, cipher=cipher, - integrity=integrity, ) if hsm := disk_encryption.get('hsm_device', None):