xref: /freebsd/stand/libsa/geli/geliboot.c (revision b3e76948)
1 /*-
2  * Copyright (c) 2015 Allan Jude <allanjude@FreeBSD.org>
3  * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <stand.h>
29 #include <stdarg.h>
30 #include "geliboot.h"
31 #include "geliboot_internal.h"
32 
33 struct known_dev {
34 	char			name[GELIDEV_NAMELEN];
35 	struct geli_dev 	*gdev;
36 	SLIST_ENTRY(known_dev)	entries;
37 };
38 
39 SLIST_HEAD(known_dev_list, known_dev) known_devs_head =
40     SLIST_HEAD_INITIALIZER(known_devs_head);
41 
42 static geli_ukey saved_keys[GELI_MAX_KEYS];
43 static unsigned int nsaved_keys = 0;
44 
45 /*
46  * Copy keys from local storage to the keybuf struct.
47  * Destroy the local storage when finished.
48  */
49 void
geli_export_key_buffer(struct keybuf * fkeybuf)50 geli_export_key_buffer(struct keybuf *fkeybuf)
51 {
52 	unsigned int i;
53 
54 	for (i = 0; i < nsaved_keys; i++) {
55 		fkeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_GELI;
56 		memcpy(fkeybuf->kb_ents[i].ke_data, saved_keys[i],
57 		    G_ELI_USERKEYLEN);
58 	}
59 	fkeybuf->kb_nents = nsaved_keys;
60 	explicit_bzero(saved_keys, sizeof(saved_keys));
61 }
62 
63 /*
64  * Copy keys from a keybuf struct into local storage.
65  * Zero out the keybuf.
66  */
67 void
geli_import_key_buffer(struct keybuf * skeybuf)68 geli_import_key_buffer(struct keybuf *skeybuf)
69 {
70 	unsigned int i;
71 
72 	for (i = 0; i < skeybuf->kb_nents && i < GELI_MAX_KEYS; i++) {
73 		memcpy(saved_keys[i], skeybuf->kb_ents[i].ke_data,
74 		    G_ELI_USERKEYLEN);
75 		explicit_bzero(skeybuf->kb_ents[i].ke_data,
76 		    G_ELI_USERKEYLEN);
77 		skeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_NONE;
78 	}
79 	nsaved_keys = skeybuf->kb_nents;
80 	skeybuf->kb_nents = 0;
81 }
82 
83 void
geli_add_key(geli_ukey key)84 geli_add_key(geli_ukey key)
85 {
86 
87 	/*
88 	 * If we run out of key space, the worst that will happen is
89 	 * it will ask the user for the password again.
90 	 */
91 	if (nsaved_keys < GELI_MAX_KEYS) {
92 		memcpy(saved_keys[nsaved_keys], key, G_ELI_USERKEYLEN);
93 		nsaved_keys++;
94 	}
95 }
96 
97 static int
geli_findkey(struct geli_dev * gdev,u_char * mkey)98 geli_findkey(struct geli_dev *gdev, u_char *mkey)
99 {
100 	u_int keynum;
101 	int i;
102 
103 	if (gdev->keybuf_slot >= 0) {
104 		if (g_eli_mkey_decrypt_any(&gdev->md, saved_keys[gdev->keybuf_slot],
105 		    mkey, &keynum) == 0) {
106 			return (0);
107 		}
108 	}
109 
110 	for (i = 0; i < nsaved_keys; i++) {
111 		if (g_eli_mkey_decrypt_any(&gdev->md, saved_keys[i], mkey,
112 		    &keynum) == 0) {
113 			gdev->keybuf_slot = i;
114 			return (0);
115 		}
116 	}
117 
118 	return (1);
119 }
120 
121 /*
122  * Read the last sector of a drive or partition and see if it is GELI encrypted.
123  */
124 struct geli_dev *
geli_taste(geli_readfunc readfunc,void * readpriv,daddr_t lastsector,const char * namefmt,...)125 geli_taste(geli_readfunc readfunc, void *readpriv, daddr_t lastsector,
126     const char *namefmt, ...)
127 {
128 	va_list args;
129 	struct g_eli_metadata md;
130 	struct known_dev *kdev;
131 	struct geli_dev *gdev;
132 	u_char *buf;
133 	char devname[GELIDEV_NAMELEN];
134 	int error;
135 	off_t alignsector;
136 
137 	/*
138 	 * Format the name into a temp buffer and use that to search for an
139 	 * existing known_dev instance.  If not found, this has the side effect
140 	 * of initializing kdev to NULL.
141 	 */
142 	va_start(args, namefmt);
143 	vsnprintf(devname, sizeof(devname), namefmt, args);
144 	va_end(args);
145 	SLIST_FOREACH(kdev, &known_devs_head, entries) {
146 		if (strcmp(kdev->name, devname) == 0)
147 			return (kdev->gdev);
148 	}
149 
150         /* Determine whether the new device is geli-encrypted... */
151 	if ((buf = malloc(DEV_GELIBOOT_BSIZE)) == NULL)
152 		goto out;
153 	alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE);
154 	if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) {
155 		/* Don't read past the end of the disk */
156 		alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE -
157 		    DEV_GELIBOOT_BSIZE;
158 	}
159 	error = readfunc(NULL, readpriv, alignsector, buf, DEV_GELIBOOT_BSIZE);
160 	if (error != 0) {
161 		goto out;
162 	}
163 
164 	/*
165 	 * We have a new known_device.  Whether it's geli-encrypted or not,
166 	 * record its existence so we can avoid doing IO to probe it next time.
167 	 */
168 	if ((kdev = malloc(sizeof(*kdev))) == NULL)
169 		goto out;
170 	strlcpy(kdev->name, devname, sizeof(kdev->name));
171 	kdev->gdev = NULL;
172 	SLIST_INSERT_HEAD(&known_devs_head, kdev, entries);
173 
174 	/* Extract the last 4k sector of the disk. */
175 	error = eli_metadata_decode(buf, &md);
176 	if (error != 0) {
177 		/* Try the last 512 byte sector instead. */
178 		error = eli_metadata_decode(buf +
179 		    (DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md);
180 		if (error != 0) {
181 			goto out;
182 		}
183 	}
184 
185 	if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {
186 		/* The GELIBOOT feature is not activated */
187 		goto out;
188 	}
189 	if ((md.md_flags & G_ELI_FLAG_ONETIME)) {
190 		/* Swap device, skip it. */
191 		goto out;
192 	}
193 
194 	/*
195 	 * It's geli-encrypted, create a geli_dev for it and link it into the
196 	 * known_dev instance.
197 	 */
198 	gdev = malloc(sizeof(struct geli_dev));
199 	if (gdev == NULL)
200 		goto out;
201 	gdev->part_end = lastsector;
202 	gdev->keybuf_slot = -1;
203 	gdev->md = md;
204 	gdev->name = kdev->name;
205 	eli_metadata_softc(&gdev->sc, &md, DEV_BSIZE,
206 	    (lastsector + DEV_BSIZE) * DEV_BSIZE);
207 	kdev->gdev = gdev;
208 out:
209 	free(buf);
210 	if (kdev == NULL)
211 		return (NULL);
212 	return (kdev->gdev);
213 }
214 
215 /*
216  * Attempt to decrypt the device.  This will try existing keys first, then will
217  * prompt for a passphrase if there are no existing keys that work.
218  */
219 static int
geli_probe(struct geli_dev * gdev,const char * passphrase,u_char * mkeyp)220 geli_probe(struct geli_dev *gdev, const char *passphrase, u_char *mkeyp)
221 {
222 	u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN], *mkp;
223 	u_int keynum;
224 	struct hmac_ctx ctx;
225 	int error;
226 
227 	if (mkeyp != NULL) {
228 		memcpy(&mkey, mkeyp, G_ELI_DATAIVKEYLEN);
229 		explicit_bzero(mkeyp, G_ELI_DATAIVKEYLEN);
230 		goto found_key;
231 	}
232 
233 	if (geli_findkey(gdev, mkey) == 0) {
234 		goto found_key;
235 	}
236 
237 	g_eli_crypto_hmac_init(&ctx, NULL, 0);
238 	/*
239 	 * Prepare Derived-Key from the user passphrase.
240 	 */
241 	if (gdev->md.md_iterations < 0) {
242 		/* XXX TODO: Support loading key files. */
243 		return (1);
244 	} else if (gdev->md.md_iterations == 0) {
245 		g_eli_crypto_hmac_update(&ctx, gdev->md.md_salt,
246 		    sizeof(gdev->md.md_salt));
247 		g_eli_crypto_hmac_update(&ctx, (const uint8_t *)passphrase,
248 		    strlen(passphrase));
249 	} else if (gdev->md.md_iterations > 0) {
250 		printf("Calculating GELI Decryption Key for %s %d"
251 		    " iterations...\n", gdev->name, gdev->md.md_iterations);
252 		u_char dkey[G_ELI_USERKEYLEN];
253 
254 		pkcs5v2_genkey(dkey, sizeof(dkey), gdev->md.md_salt,
255 		    sizeof(gdev->md.md_salt), passphrase,
256 		    gdev->md.md_iterations);
257 		g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
258 		explicit_bzero(dkey, sizeof(dkey));
259 	}
260 
261 	g_eli_crypto_hmac_final(&ctx, key, 0);
262 
263 	error = g_eli_mkey_decrypt_any(&gdev->md, key, mkey, &keynum);
264 	if (error == -1) {
265 		explicit_bzero(mkey, sizeof(mkey));
266 		explicit_bzero(key, sizeof(key));
267 		printf("Bad GELI key: bad password?\n");
268 		return (error);
269 	} else if (error != 0) {
270 		explicit_bzero(mkey, sizeof(mkey));
271 		explicit_bzero(key, sizeof(key));
272 		printf("Failed to decrypt GELI master key: %d\n", error);
273 		return (error);
274 	} else {
275 		/* Add key to keychain */
276 		geli_add_key(key);
277 		explicit_bzero(&key, sizeof(key));
278 	}
279 
280 found_key:
281 	/* Store the keys */
282 	bcopy(mkey, gdev->sc.sc_mkey, sizeof(gdev->sc.sc_mkey));
283 	bcopy(mkey, gdev->sc.sc_ivkey, sizeof(gdev->sc.sc_ivkey));
284 	mkp = mkey + sizeof(gdev->sc.sc_ivkey);
285 	if ((gdev->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
286 		bcopy(mkp, gdev->sc.sc_ekey, G_ELI_DATAKEYLEN);
287 	} else {
288 		/*
289 		 * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
290 		 */
291 		g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, (const uint8_t *)"\x10", 1,
292 		    gdev->sc.sc_ekey, 0);
293 	}
294 	explicit_bzero(mkey, sizeof(mkey));
295 
296 	/* Initialize the per-sector IV. */
297 	switch (gdev->sc.sc_ealgo) {
298 	case CRYPTO_AES_XTS:
299 		break;
300 	default:
301 		SHA256_Init(&gdev->sc.sc_ivctx);
302 		SHA256_Update(&gdev->sc.sc_ivctx, gdev->sc.sc_ivkey,
303 		    sizeof(gdev->sc.sc_ivkey));
304 		break;
305 	}
306 
307 	return (0);
308 }
309 
310 int
geli_io(struct geli_dev * gdev,geli_op_t enc,off_t offset,u_char * buf,size_t bytes)311 geli_io(struct geli_dev *gdev, geli_op_t enc, off_t offset, u_char *buf,
312     size_t bytes)
313 {
314 	u_char iv[G_ELI_IVKEYLEN];
315 	u_char *pbuf;
316 	int error;
317 	off_t dstoff;
318 	uint64_t keyno;
319 	size_t n, nsec, secsize;
320 	struct g_eli_key gkey;
321 
322 	pbuf = buf;
323 
324 	secsize = gdev->sc.sc_sectorsize;
325 	nsec = bytes / secsize;
326 	if (nsec == 0) {
327 		/*
328 		 * A read of less than the GELI sector size has been
329 		 * requested. The caller provided destination buffer may
330 		 * not be big enough to boost the read to a full sector,
331 		 * so just attempt to decrypt the truncated sector.
332 		 */
333 		secsize = bytes;
334 		nsec = 1;
335 	}
336 
337 	for (n = 0, dstoff = offset; n < nsec; n++, dstoff += secsize) {
338 
339 		g_eli_crypto_ivgen(&gdev->sc, dstoff, iv, G_ELI_IVKEYLEN);
340 
341 		/* Get the key that corresponds to this offset. */
342 		keyno = (dstoff >> G_ELI_KEY_SHIFT) / secsize;
343 		g_eli_key_fill(&gdev->sc, &gkey, keyno);
344 
345 		error = geliboot_crypt(gdev->sc.sc_ealgo, enc, pbuf, secsize,
346 		    gkey.gek_key, gdev->sc.sc_ekeylen, iv);
347 
348 		if (error != 0) {
349 			explicit_bzero(&gkey, sizeof(gkey));
350 			printf("%s: Failed to %s!", __func__,
351 			    enc ? "encrypt" : "decrypt");
352 			return (error);
353 		}
354 		pbuf += secsize;
355 	}
356 	explicit_bzero(&gkey, sizeof(gkey));
357 	return (0);
358 }
359 
360 int
geli_havekey(struct geli_dev * gdev)361 geli_havekey(struct geli_dev *gdev)
362 {
363 	u_char mkey[G_ELI_DATAIVKEYLEN];
364 	int err;
365 
366 	err = ENOENT;
367 	if (geli_findkey(gdev, mkey) == 0) {
368 		if (geli_probe(gdev, NULL, mkey) == 0)
369 			err = 0;
370 		explicit_bzero(mkey, sizeof(mkey));
371 	}
372 	return (err);
373 }
374 
375 int
geli_passphrase(struct geli_dev * gdev,char * pw)376 geli_passphrase(struct geli_dev *gdev, char *pw)
377 {
378 	int i;
379 
380 	/* TODO: Implement GELI keyfile(s) support */
381 	for (i = 0; i < 3; i++) {
382 		/* Try cached passphrase */
383 		if (i == 0 && pw[0] != '\0') {
384 			if (geli_probe(gdev, pw, NULL) == 0) {
385 				return (0);
386 			}
387 		}
388 		printf("GELI Passphrase for %s ", gdev->name);
389 		pwgets(pw, GELI_PW_MAXLEN,
390 		    (gdev->md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS) == 0);
391 		printf("\n");
392 		if (geli_probe(gdev, pw, NULL) == 0) {
393 			return (0);
394 		}
395 	}
396 
397 	return (1);
398 }
399