Aller au contenu
Sylvain Joffraud l4w
Retour

Argon2 : le KDF par défaut piège les cibles à 1 GB de RAM

J’initialise un disque externe en LUKS2 sur mon PC (16 GB de RAM) avec cryptsetup luksFormat --pbkdf argon2id --pbkdf-memory 1048576 --pbkdf-parallel 4. Tout va vite, je copie le keyfile sur mon NAS (1 GB de RAM), je teste le pipeline luksOpen → mount → rsync : OK en quelques minutes.

Le lendemain, vrai backup nightly sur le NAS. luksOpen lance Argon2id. Puis… plus rien. systemctl is-active retourne activating pendant 5 min, 10, 20, 28. Aucun crash, aucun OOM dans dmesg. Le service est juste assis là, à mouliner.

free -h me donne la vérité :

Mem:    958Mi   935Mi   59Mi   ...   25Mi avail
Swap:   2.0Gi   1.0Gi   1.0Gi

1 GB de swap utilisé, 25 MB de RAM dispo. luksOpen a alloué 1 GB pour Argon2 → la moitié en swap → chaque accès aléatoire = page fault → 28 min d’I/O brut juste pour dériver le master key d’un keyslot.

Cause

Argon2id est memory-hard : son coût est proportionnel à la RAM consommée, ce qui casse les attaques GPU/ASIC. cryptsetup choisit par défaut la moitié de la RAM dispo au luksFormat (8 GB sur un PC 16 GB, ou plafond 1 GB). Solide pour la machine qui chiffre, catastrophique pour celle qui déchiffre si elle est plus petite. Le coût KDF doit être calibré sur le hardware le plus faible de la chaîne.

Fix

sudo cryptsetup luksFormat --pbkdf argon2id \
    --pbkdf-memory 131072 --pbkdf-parallel 2 \
    --type luks2 ... /dev/sdX1

128 MB, 2 threads. Sur le NAS 1 GB : ~12% de RAM pendant l’unlock, zero swap, unlock sub-seconde. Sécurité : à 128 MB + Argon2id, le brute-force reste prohibitif (~1 sec/essai, des milliards d’années).

Slot déjà créé avec un cost trop élevé

Pas besoin de reformater. luksChangeKey ré-écrit juste la zone du keyslot, le master key reste identique → données préservées 100% :

# Slot 1 (keyfile), même fichier = même clé, nouveau KDF cost
sudo cryptsetup luksChangeKey --pbkdf argon2id \
    --pbkdf-memory 131072 --pbkdf-parallel 2 \
    --key-slot 1 --key-file /tmp/backups.key \
    /dev/sdX1 /tmp/backups.key

Pour le slot 0 (passphrase) : même commande sans --key-file, taper la MÊME passphrase 3 fois. Vérifier : cryptsetup luksDump /dev/sdX1 | grep Memory.

Lessons learned

Questions fréquentes

Pourquoi mon luksOpen reste bloqué en activating pendant 20 minutes sur mon NAS sans crash ni OOM ?
Argon2id est memory-hard : au déverrouillage, cryptsetup alloue toute la mémoire fixée à la création du volume. Si la cible a peu de RAM (NAS 1 GB), la moitié part en swap et chaque accès aléatoire devient un page fault, soit des dizaines de minutes d’I/O. Lancez free -h pendant le blocage : un swap saturé avec quelques MB de RAM dispo confirme le swap thrash.
Comment cryptsetup choisit-il la mémoire Argon2 par défaut au luksFormat ?
Par défaut cryptsetup calibre le coût KDF sur la moitié de la RAM disponible de la machine qui chiffre, avec un plafond de 1 GB. Sur un PC 16 GB cela donne jusqu’à 1 GB. Ce coût est ensuite figé dans le keyslot, donc il est rejoué tel quel sur la machine qui déchiffre, même si elle est bien plus petite.
Quelle valeur de pbkdf-memory choisir pour LUKS sur un NAS ou un Raspberry Pi à faible RAM ?
Calibrez le coût sur le hardware le plus faible de la chaîne, pas sur celui qui chiffre. Pour un NAS 1 GB utilisez --pbkdf-memory 131072 (128 MB) avec --pbkdf-parallel 2 ; pour un RPi 512 MB descendez à 64 MB. À 128 MB en Argon2id l’unlock est sub-seconde sans swap et le brute-force reste prohibitif (environ 1 sec par essai).
Comment réduire le coût KDF d’un volume LUKS existant sans reformater ni perdre les données ?
Utilisez luksChangeKey : il ré-écrit uniquement la zone du keyslot, le master key reste identique, donc les données sont préservées à 100 %. Exemple : cryptsetup luksChangeKey --pbkdf argon2id --pbkdf-memory 131072 --pbkdf-parallel 2 --key-slot 1 --key-file /tmp/backups.key /dev/sdX1 /tmp/backups.key. Vérifiez avec cryptsetup luksDump /dev/sdX1 | grep Memory.

Partager cet article :

Article précédent
Argon2 dans LUKS : moins de mémoire ≠ moins sûr
Article suivant
Migrer Plausible vers Coolify v4 : 5 pièges en 30 min