main
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<!-- Sep 03, 2024 -->
5<meta charset="utf-8" />
6<meta name="viewport" content="width=device-width, initial-scale=1" />
7<title>Automatically unlock a luks encrypted partiiton with an SDCard</title>
8<meta name="author" content="Vincent Demeester" />
9<meta name="keywords" content="post" />
10<meta name="generator" content="Org Mode" />
11<link rel="stylesheet" type="text/css" href="/css/2022.css" />
12<link rel="stylesheet" type="text/css" href="/css/syntax.css" />
13<link rel='icon' type='image/x-icon' href='/images/favicon.ico'/>
14<meta name='viewport' content='width=device-width, initial-scale=1'>
15</head>
16<body>
17<main id="content" class="content">
18<header>
19<h1 class="title">Automatically unlock a luks encrypted partiiton with an SDCard</h1>
20<p class="subtitle" role="doc-subtitle">… or a USB card.</p>
21</header><p>
22I am booting my work laptop (NixOS on a Thinkpad) from a LUKS-encrypted volume. I also do
23have another “laptop” (used as a build/server) that is LUKS-encrypted. So far, I’ve been
24using a passphrase I type on boot. It’s more than fine for my laptop, but it means it’s a
25bit trickier for my other machine. I need to remove from its slot below my desk, type it
26and re-put it in the slot. This mean it’s a bit harder to do upgrade and reboot without
27any input from me.
28</p>
29
30<p>
31For convenience, I want an SD card’s LUKS volume to unlock and mount when the machine
32boots, rather than me needing to unlock and mount it each time.
33</p>
34
35<p>
36There is a bunch of articles about this, like <a href="https://possiblelossofprecision.net/?p=300">this one</a>. Or slightly related <a href="https://kyau.net/wiki/ArchLinux:LUKS">these</a> <a href="https://neilzone.co.uk/2021/07/auto-unlocking-a-luks-volume-on-an-sd-card-on-boot-with-debian-11-bullseye">ones</a>. I
37am using NixOS however, and it is actually making things relatively straightforward. The
38closer article to what I was looking for is <a href="https://medium.com/@geis/using-a-raw-usb-device-to-unlock-a-luks-volume-on-nixos-193406ee7474">this one</a> as well as the <a href="https://nixos.wiki/wiki/Full_Disk_Encryption">NixOS wiki entry</a> on
39full disk encryption.
40</p>
41
42<p>
43The idea is relatively simple : we are going to use a key file (hidden or not in a
44partition) to unlock a luks encrypted — with a fallback on passphrase (in case the medium
45is not there). There is 3 main steps :
46</p>
47<ul class="org-ul">
48<li>creating the key file and storing it somewhere</li>
49<li>add the key to a slot in the luks encrypted partition</li>
50<li>configuring NixOS to use it</li>
51</ul>
52<section id="outline-container-Creating%20a%20keyfile%20and%20storing%20it" class="outline-2">
53<h2 id="Creating%20a%20keyfile%20and%20storing%20it">Creating a keyfile and storing it</h2>
54<div class="outline-text-2" id="text-Creating%20a%20keyfile%20and%20storing%20it">
55<p>
56Creating a key file is very simple. If we are to use a file, we can just do the following:
57</p>
58
59<div class="org-src-container">
60<pre class="src src-bash">$ dd <span class="org-variable-name">if</span>=/dev/urandom <span class="org-variable-name">of</span>=hdd.key <span class="org-variable-name">bs</span>=4096 <span class="org-variable-name">count</span>=1
61</pre>
62</div>
63
64<p>
65I have two key to generate, one for <code>aomi</code> and one for <code>naruhodo</code>
66</p>
67
68<div class="org-src-container">
69<pre class="src src-bash">$ dd <span class="org-variable-name">if</span>=/dev/random <span class="org-variable-name">of</span>=naruhodo.key.bin <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
704096+0 records<span class="org-keyword"> in</span>
714096+0 records out
724096 bytes (4.1 kB, 4.0 KiB) copied, 0.00947718 s, 432 kB/s
73
74$ dd <span class="org-variable-name">if</span>=/dev/random <span class="org-variable-name">of</span>=aomi.key.bin <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
754096+0 records<span class="org-keyword"> in</span>
764096+0 records out
774096 bytes (4.1 kB, 4.0 KiB) copied, 0.00985101 s, 416 kB/s
78</pre>
79</div>
80
81<p>
82What we are going to do here is, to hide the key inside a sdcard or a usb stick. The idea
83is to use the first or the last few blocks to hide the key.
84</p>
85
86<div class="org-src-container">
87<pre class="src src-bash"><span class="org-comment-delimiter"># </span><span class="org-comment">This writes the aomi key to the "head" of sda (a sdcard)</span>
88$ sudo dd <span class="org-variable-name">if</span>=sync/aomi.key.bin <span class="org-variable-name">of</span>=/dev/sda <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096
89<span class="org-comment-delimiter"># </span><span class="org-comment">This writes the naruhodo key to the "tail" of sdb (a usb card)</span>
90<span class="org-comment-delimiter"># </span><span class="org-comment">The offset has to be computed from the usb key size</span>
91$ sudo dd <span class="org-variable-name">if</span>=sync/naruhodo.key.bin <span class="org-variable-name">of</span>=/dev/sdb <span class="org-variable-name">bs</span>=1 <span class="org-variable-name">count</span>=4096 <span class="org-variable-name">seek</span>=30992883712
92</pre>
93</div>
94</div>
95</section>
96<section id="outline-container-Add%20the%20key%20to%20a%20slot" class="outline-2">
97<h2 id="Add%20the%20key%20to%20a%20slot">Add the key to a slot</h2>
98<div class="outline-text-2" id="text-Add%20the%20key%20to%20a%20slot">
99<p>
100This is probably the easiest step of all, this is just about running the following.
101</p>
102
103<div class="org-src-container">
104<pre class="src src-bash">$ cryptsetup luksAddKey $<span class="org-variable-name">LUKS_DEVICE</span> $<span class="org-variable-name">KEY</span>
105</pre>
106</div>
107
108<p>
109The only <i>trick</i> to it is : you have to do this “offline”, a.k.a. when the partition in
110locked (and thus not mounted, …). Either you do this when you are installing the operating
111system (and it’s straightforward), or you need to boot your laptop/desktop with a livecd
112(that also then has access to the key).
113</p>
114</div>
115</section>
116<section id="outline-container-NixOS%20configuration" class="outline-2">
117<h2 id="NixOS%20configuration">NixOS configuration</h2>
118<div class="outline-text-2" id="text-NixOS%20configuration">
119<p>
120This is where NixOS helps greatly, we have just a few things to write, and NixOS will make
121sure all is correctly setup (the initramfs, …).
122</p>
123
124<div class="org-src-container">
125<pre class="src src-nix"><span class="org-comment-delimiter"># </span><span class="org-comment">For aomi, without offset</span>
126<span class="org-nix-attribute">boot.initrd.luks.devices</span> = {
127 <span class="org-nix-attribute">root</span> = {
128 <span class="org-nix-attribute">device</span> = <span class="org-string">"/dev/disk/by-uuid/{UUID}"</span>;
129 <span class="org-nix-attribute">preLVM</span> = <span class="org-nix-builtin">true</span>;
130 <span class="org-nix-attribute">allowDiscards</span> = <span class="org-nix-builtin">true</span>;
131 <span class="org-nix-attribute">keyFile</span> = <span class="org-string">"/dev/disk/by-id/{DISKID}"</span>;
132 <span class="org-nix-attribute">keyFileSize</span> = 4096;
133 <span class="org-nix-attribute">fallbackToPassword</span> = <span class="org-nix-builtin">true</span>;
134 };
135};
136<span class="org-comment-delimiter"># </span><span class="org-comment">For narudoho, with offset</span>
137<span class="org-nix-attribute">boot.initrd.luks.devices</span> = {
138 <span class="org-nix-attribute">root</span> = {
139 <span class="org-nix-attribute">device</span> = <span class="org-string">"/dev/disk/by-uuid/{UUID}"</span>;
140 <span class="org-nix-attribute">preLVM</span> = <span class="org-nix-builtin">true</span>;
141 <span class="org-nix-attribute">allowDiscards</span> = <span class="org-nix-builtin">true</span>;
142 <span class="org-nix-attribute">keyFile</span> = <span class="org-string">"/dev/disk/by-id/{DISKID}"</span>;
143 <span class="org-nix-attribute">keyFileOffset</span> = 30992883712;
144 <span class="org-nix-attribute">keyFileSize</span> = 4096;
145 <span class="org-nix-attribute">fallbackToPassword</span> = <span class="org-nix-builtin">true</span>;
146 };
147};
148</pre>
149</div>
150
151<p>
152Now, we are a <code>nixos-rebuild</code> away from being able to boot a NixOS on a encrypted file
153system, without having to type the password <b>if we have the correct medium</b> inserted in
154the machine.
155</p>
156
157<p>
158<i>Of course, this means that the “unlock” medium becomes precious and important <b>not to</b>
159loose. If you go on vacation for example, you should definitely remove any of those medium
160and hide them (or bring them with you).</i>
161</p>
162</div>
163</section>
164</main>
165<footer id="postamble" class="status">
166<footer>
167 <small><a href="/" rel="history">Index</a> • <a href="/sitemap.html">Sitemap</a> • <a href="https://dl.sbr.pm/">Files</a></small><br/>
168 <small class='questions'>Questions, comments ? Please use my <a href="https://lists.sr.ht/~vdemeester/public-inbox">public inbox</a> by sending a plain-text email to <a href="mailto:~vdemeester/public-inbox@lists.sr.ht">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/>
169 <small class='copyright'>
170 Content and design by Vincent Demeester
171 (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>)
172 </small><br />
173</footer>
174</footer>
175</body>
176</html>