swap: extend randomEncryption to plainOpen and ability to select cipher

Changed files
+32 -12
nixos
modules
config
system
+31 -11
nixos/modules/config/swap.nix
···
'';
};
-
randomEncryption = mkOption {
default = false;
type = types.bool;
description = ''
···
'';
};
deviceName = mkOption {
type = types.str;
internal = true;
···
device = mkIf options.label.isDefined
"/dev/disk/by-label/${config.label}";
deviceName = lib.replaceChars ["\\"] [""] (escapeSystemdPath config.device);
-
realDevice = if config.randomEncryption then "/dev/mapper/${deviceName}" else config.device;
};
};
···
createSwapDevice = sw:
assert sw.device != "";
-
assert !(sw.randomEncryption && lib.hasPrefix "/dev/disk/by-uuid" sw.device);
-
assert !(sw.randomEncryption && lib.hasPrefix "/dev/disk/by-label" sw.device);
let realDevice' = escapeSystemdPath sw.realDevice;
in nameValuePair "mkswap-${sw.deviceName}"
{ description = "Initialisation of swap device ${sw.device}";
wantedBy = [ "${realDevice'}.swap" ];
before = [ "${realDevice'}.swap" ];
-
path = [ pkgs.utillinux ] ++ optional sw.randomEncryption pkgs.cryptsetup;
script =
''
···
truncate --size "${toString sw.size}M" "${sw.device}"
fi
chmod 0600 ${sw.device}
-
${optionalString (!sw.randomEncryption) "mkswap ${sw.realDevice}"}
fi
''}
-
${optionalString sw.randomEncryption ''
-
cryptsetup open ${sw.device} ${sw.deviceName} --type plain --key-file /dev/urandom
mkswap ${sw.realDevice}
''}
'';
···
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
serviceConfig.Type = "oneshot";
-
serviceConfig.RemainAfterExit = sw.randomEncryption;
-
serviceConfig.ExecStop = optionalString sw.randomEncryption "${pkgs.cryptsetup}/bin/cryptsetup luksClose ${sw.deviceName}";
restartIfChanged = false;
};
-
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption) config.swapDevices));
};
···
'';
};
+
randomEncryption.enable = mkOption {
default = false;
type = types.bool;
description = ''
···
'';
};
+
randomEncryption.cipher = mkOption {
+
default = "aes-xts-plain64";
+
example = "serpent-xts-plain64";
+
type = types.str;
+
description = ''
+
Use specified cipher for randomEncryption.
+
+
Hint: Run "cryptsetup benchmark" to see which one is fastest on your machine.
+
'';
+
};
+
+
randomEncryption.source = mkOption {
+
default = "/dev/urandom";
+
example = "/dev/random";
+
type = types.str;
+
description = ''
+
Define the source of randomness to obtain a random key for encryption.
+
'';
+
};
+
deviceName = mkOption {
type = types.str;
internal = true;
···
device = mkIf options.label.isDefined
"/dev/disk/by-label/${config.label}";
deviceName = lib.replaceChars ["\\"] [""] (escapeSystemdPath config.device);
+
realDevice = if config.randomEncryption.enable then "/dev/mapper/${deviceName}" else config.device;
};
};
···
createSwapDevice = sw:
assert sw.device != "";
+
assert !(sw.randomEncryption.enable && lib.hasPrefix "/dev/disk/by-uuid" sw.device);
+
assert !(sw.randomEncryption.enable && lib.hasPrefix "/dev/disk/by-label" sw.device);
let realDevice' = escapeSystemdPath sw.realDevice;
in nameValuePair "mkswap-${sw.deviceName}"
{ description = "Initialisation of swap device ${sw.device}";
wantedBy = [ "${realDevice'}.swap" ];
before = [ "${realDevice'}.swap" ];
+
path = [ pkgs.utillinux ] ++ optional sw.randomEncryption.enable pkgs.cryptsetup;
script =
''
···
truncate --size "${toString sw.size}M" "${sw.device}"
fi
chmod 0600 ${sw.device}
+
${optionalString (!sw.randomEncryption.enable) "mkswap ${sw.realDevice}"}
fi
''}
+
${optionalString sw.randomEncryption.enable ''
+
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} ${sw.device} ${sw.deviceName}
mkswap ${sw.realDevice}
''}
'';
···
unitConfig.RequiresMountsFor = [ "${dirOf sw.device}" ];
unitConfig.DefaultDependencies = false; # needed to prevent a cycle
serviceConfig.Type = "oneshot";
+
serviceConfig.RemainAfterExit = sw.randomEncryption.enable;
+
serviceConfig.ExecStop = optionalString sw.randomEncryption.enable "${pkgs.cryptsetup}/bin/cryptsetup luksClose ${sw.deviceName}";
restartIfChanged = false;
};
+
in listToAttrs (map createSwapDevice (filter (sw: sw.size != null || sw.randomEncryption.enable) config.swapDevices));
};
+1 -1
nixos/modules/system/boot/stage-1.nix
···
preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
-
(filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption
# Don't include zram devices
&& !(hasPrefix "/dev/zram" sd.device)
) config.swapDevices);
···
preLVMCommands preDeviceCommands postDeviceCommands postMountCommands preFailCommands kernelModules;
resumeDevices = map (sd: if sd ? device then sd.device else "/dev/disk/by-label/${sd.label}")
+
(filter (sd: hasPrefix "/dev/" sd.device && !sd.randomEncryption.enable
# Don't include zram devices
&& !(hasPrefix "/dev/zram" sd.device)
) config.swapDevices);