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 &ldquo;laptop&rdquo; (used as a build/server) that is LUKS-encrypted. So far, I&rsquo;ve been
 24using a passphrase I type on boot. It&rsquo;s more than fine for my laptop, but it means it&rsquo;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&rsquo;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&rsquo;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 &ldquo;offline&rdquo;, 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&rsquo;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 &ldquo;unlock&rdquo; 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>