1{ config, lib, ... }:
2
3with lib;
4
5let
6 fileSystems = attrValues config.fileSystems ++ config.swapDevices;
7 encDevs = filter (dev: dev.encrypted.enable) fileSystems;
8 keyedEncDevs = filter (dev: dev.encrypted.keyFile != null) encDevs;
9 isIn = needle: haystack: filter (p: p == needle) haystack != [];
10 anyEncrypted =
11 fold (j: v: v || j.encrypted.enable) false encDevs;
12
13 encryptedFSOptions = {
14
15 encrypted = {
16 enable = mkOption {
17 default = false;
18 type = types.bool;
19 description = "The block device is backed by an encrypted one, adds this device as a initrd luks entry.";
20 };
21
22 blkDev = mkOption {
23 default = null;
24 example = "/dev/sda1";
25 type = types.uniq (types.nullOr types.string);
26 description = "Location of the backing encrypted device.";
27 };
28
29 label = mkOption {
30 default = null;
31 example = "rootfs";
32 type = types.uniq (types.nullOr types.string);
33 description = "Label of the backing encrypted device.";
34 };
35
36 keyFile = mkOption {
37 default = null;
38 example = "/root/.swapkey";
39 type = types.uniq (types.nullOr types.string);
40 description = "File system location of keyfile.";
41 };
42 };
43 };
44in
45
46{
47
48 options = {
49 fileSystems = mkOption {
50 options = [encryptedFSOptions];
51 };
52 swapDevices = mkOption {
53 options = [encryptedFSOptions];
54 };
55 };
56
57 config = mkIf anyEncrypted {
58 boot.initrd = {
59 luks = {
60 devices =
61 map (dev: { name = dev.encrypted.label; device = dev.encrypted.blkDev; } ) encDevs;
62 cryptoModules = [ "aes" "sha256" "sha1" "xts" ];
63 };
64 postMountCommands =
65 concatMapStrings (dev: "cryptsetup luksOpen --key-file ${dev.encrypted.keyFile} ${dev.encrypted.label};\n") keyedEncDevs;
66 };
67 };
68}
69