geliboot.c revision 344399
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 * $FreeBSD: stable/11/stand/libsa/geli/geliboot.c 344399 2019-02-20 23:55:35Z kevans $
28 */
29
30#include <stand.h>
31#include <stdarg.h>
32#include "geliboot.h"
33#include "geliboot_internal.h"
34
35struct known_dev {
36	char			name[GELIDEV_NAMELEN];
37	struct geli_dev 	*gdev;
38	SLIST_ENTRY(known_dev)	entries;
39};
40
41SLIST_HEAD(known_dev_list, known_dev) known_devs_head =
42    SLIST_HEAD_INITIALIZER(known_devs_head);
43
44static geli_ukey saved_keys[GELI_MAX_KEYS];
45static unsigned int nsaved_keys = 0;
46
47/*
48 * Copy keys from local storage to the keybuf struct.
49 * Destroy the local storage when finished.
50 */
51void
52geli_export_key_buffer(struct keybuf *fkeybuf)
53{
54	unsigned int i;
55
56	for (i = 0; i < nsaved_keys; i++) {
57		fkeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_GELI;
58		memcpy(fkeybuf->kb_ents[i].ke_data, saved_keys[i],
59		    G_ELI_USERKEYLEN);
60	}
61	fkeybuf->kb_nents = nsaved_keys;
62	explicit_bzero(saved_keys, sizeof(saved_keys));
63}
64
65/*
66 * Copy keys from a keybuf struct into local storage.
67 * Zero out the keybuf.
68 */
69void
70geli_import_key_buffer(struct keybuf *skeybuf)
71{
72	unsigned int i;
73
74	for (i = 0; i < skeybuf->kb_nents && i < GELI_MAX_KEYS; i++) {
75		memcpy(saved_keys[i], skeybuf->kb_ents[i].ke_data,
76		    G_ELI_USERKEYLEN);
77		explicit_bzero(skeybuf->kb_ents[i].ke_data,
78		    G_ELI_USERKEYLEN);
79		skeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_NONE;
80	}
81	nsaved_keys = skeybuf->kb_nents;
82	skeybuf->kb_nents = 0;
83}
84
85void
86geli_add_key(geli_ukey key)
87{
88
89	/*
90	 * If we run out of key space, the worst that will happen is
91	 * it will ask the user for the password again.
92	 */
93	if (nsaved_keys < GELI_MAX_KEYS) {
94		memcpy(saved_keys[nsaved_keys], key, G_ELI_USERKEYLEN);
95		nsaved_keys++;
96	}
97}
98
99static int
100geli_findkey(struct geli_dev *gdev, u_char *mkey)
101{
102	u_int keynum;
103	int i;
104
105	if (gdev->keybuf_slot >= 0) {
106		if (g_eli_mkey_decrypt_any(&gdev->md, saved_keys[gdev->keybuf_slot],
107		    mkey, &keynum) == 0) {
108			return (0);
109		}
110	}
111
112	for (i = 0; i < nsaved_keys; i++) {
113		if (g_eli_mkey_decrypt_any(&gdev->md, saved_keys[i], mkey,
114		    &keynum) == 0) {
115			gdev->keybuf_slot = i;
116			return (0);
117		}
118	}
119
120	return (1);
121}
122
123/*
124 * Read the last sector of a drive or partition and see if it is GELI encrypted.
125 */
126struct geli_dev *
127geli_taste(geli_readfunc readfunc, void *readpriv, daddr_t lastsector,
128    const char *namefmt, ...)
129{
130	va_list args;
131	struct g_eli_metadata md;
132	struct known_dev *kdev;
133	struct geli_dev *gdev;
134	u_char *buf;
135	char devname[GELIDEV_NAMELEN];
136	int error;
137	off_t alignsector;
138
139	/*
140	 * Format the name into a temp buffer and use that to search for an
141	 * existing known_dev instance.  If not found, this has the side effect
142	 * of initializing kdev to NULL.
143	 */
144	va_start(args, namefmt);
145	vsnprintf(devname, sizeof(devname), namefmt, args);
146	va_end(args);
147	SLIST_FOREACH(kdev, &known_devs_head, entries) {
148		if (strcmp(kdev->name, devname) == 0)
149			return (kdev->gdev);
150	}
151
152        /* Determine whether the new device is geli-encrypted... */
153	if ((buf = malloc(DEV_GELIBOOT_BSIZE)) == NULL)
154		goto out;
155	alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE);
156	if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) {
157		/* Don't read past the end of the disk */
158		alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE -
159		    DEV_GELIBOOT_BSIZE;
160	}
161	error = readfunc(NULL, readpriv, alignsector, buf, DEV_GELIBOOT_BSIZE);
162	if (error != 0) {
163		goto out;
164	}
165
166	/*
167	 * We have a new known_device.  Whether it's geli-encrypted or not,
168	 * record its existance so we can avoid doing IO to probe it next time.
169	 */
170	if ((kdev = malloc(sizeof(*kdev))) == NULL)
171		goto out;
172	strlcpy(kdev->name, devname, sizeof(kdev->name));
173	kdev->gdev = NULL;
174	SLIST_INSERT_HEAD(&known_devs_head, kdev, entries);
175
176	/* Extract the last 4k sector of the disk. */
177	error = eli_metadata_decode(buf, &md);
178	if (error != 0) {
179		/* Try the last 512 byte sector instead. */
180		error = eli_metadata_decode(buf +
181		    (DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md);
182		if (error != 0) {
183			goto out;
184		}
185	}
186
187	if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {
188		/* The GELIBOOT feature is not activated */
189		goto out;
190	}
191	if ((md.md_flags & G_ELI_FLAG_ONETIME)) {
192		/* Swap device, skip it. */
193		goto out;
194	}
195
196	/*
197	 * It's geli-encrypted, create a geli_dev for it and link it into the
198	 * known_dev instance.
199	 */
200	gdev = malloc(sizeof(struct geli_dev));
201	if (gdev == NULL)
202		goto out;
203	gdev->part_end = lastsector;
204	gdev->keybuf_slot = -1;
205	gdev->md = md;
206	gdev->name = kdev->name;
207	eli_metadata_softc(&gdev->sc, &md, DEV_BSIZE,
208	    (lastsector + DEV_BSIZE) * DEV_BSIZE);
209	kdev->gdev = gdev;
210out:
211	free(buf);
212	if (kdev == NULL)
213		return (NULL);
214	return (kdev->gdev);
215}
216
217/*
218 * Attempt to decrypt the device.  This will try existing keys first, then will
219 * prompt for a passphrase if there are no existing keys that work.
220 */
221static int
222geli_probe(struct geli_dev *gdev, const char *passphrase, u_char *mkeyp)
223{
224	u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN], *mkp;
225	u_int keynum;
226	struct hmac_ctx ctx;
227	int error;
228
229	if (mkeyp != NULL) {
230		memcpy(&mkey, mkeyp, G_ELI_DATAIVKEYLEN);
231		explicit_bzero(mkeyp, G_ELI_DATAIVKEYLEN);
232		goto found_key;
233	}
234
235	if (geli_findkey(gdev, mkey) == 0) {
236		goto found_key;
237	}
238
239	g_eli_crypto_hmac_init(&ctx, NULL, 0);
240	/*
241	 * Prepare Derived-Key from the user passphrase.
242	 */
243	if (gdev->md.md_iterations < 0) {
244		/* XXX TODO: Support loading key files. */
245		return (1);
246	} else if (gdev->md.md_iterations == 0) {
247		g_eli_crypto_hmac_update(&ctx, gdev->md.md_salt,
248		    sizeof(gdev->md.md_salt));
249		g_eli_crypto_hmac_update(&ctx, (const uint8_t *)passphrase,
250		    strlen(passphrase));
251	} else if (gdev->md.md_iterations > 0) {
252		printf("Calculating GELI Decryption Key for %s %d"
253		    " iterations...\n", gdev->name, gdev->md.md_iterations);
254		u_char dkey[G_ELI_USERKEYLEN];
255
256		pkcs5v2_genkey(dkey, sizeof(dkey), gdev->md.md_salt,
257		    sizeof(gdev->md.md_salt), passphrase,
258		    gdev->md.md_iterations);
259		g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
260		explicit_bzero(dkey, sizeof(dkey));
261	}
262
263	g_eli_crypto_hmac_final(&ctx, key, 0);
264
265	error = g_eli_mkey_decrypt_any(&gdev->md, key, mkey, &keynum);
266	if (error == -1) {
267		explicit_bzero(mkey, sizeof(mkey));
268		explicit_bzero(key, sizeof(key));
269		printf("Bad GELI key: bad password?\n");
270		return (error);
271	} else if (error != 0) {
272		explicit_bzero(mkey, sizeof(mkey));
273		explicit_bzero(key, sizeof(key));
274		printf("Failed to decrypt GELI master key: %d\n", error);
275		return (error);
276	} else {
277		/* Add key to keychain */
278		geli_add_key(key);
279		explicit_bzero(&key, sizeof(key));
280	}
281
282found_key:
283	/* Store the keys */
284	bcopy(mkey, gdev->sc.sc_mkey, sizeof(gdev->sc.sc_mkey));
285	bcopy(mkey, gdev->sc.sc_ivkey, sizeof(gdev->sc.sc_ivkey));
286	mkp = mkey + sizeof(gdev->sc.sc_ivkey);
287	if ((gdev->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
288		bcopy(mkp, gdev->sc.sc_ekey, G_ELI_DATAKEYLEN);
289	} else {
290		/*
291		 * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
292		 */
293		g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, (const uint8_t *)"\x10", 1,
294		    gdev->sc.sc_ekey, 0);
295	}
296	explicit_bzero(mkey, sizeof(mkey));
297
298	/* Initialize the per-sector IV. */
299	switch (gdev->sc.sc_ealgo) {
300	case CRYPTO_AES_XTS:
301		break;
302	default:
303		SHA256_Init(&gdev->sc.sc_ivctx);
304		SHA256_Update(&gdev->sc.sc_ivctx, gdev->sc.sc_ivkey,
305		    sizeof(gdev->sc.sc_ivkey));
306		break;
307	}
308
309	return (0);
310}
311
312int
313geli_read(struct geli_dev *gdev, off_t offset, u_char *buf, size_t bytes)
314{
315	u_char iv[G_ELI_IVKEYLEN];
316	u_char *pbuf;
317	int error;
318	off_t dstoff;
319	uint64_t keyno;
320	size_t n, nsec, secsize;
321	struct g_eli_key gkey;
322
323	pbuf = buf;
324
325	secsize = gdev->sc.sc_sectorsize;
326	nsec = bytes / secsize;
327	if (nsec == 0) {
328		/*
329		 * A read of less than the GELI sector size has been
330		 * requested. The caller provided destination buffer may
331		 * not be big enough to boost the read to a full sector,
332		 * so just attempt to decrypt the truncated sector.
333		 */
334		secsize = bytes;
335		nsec = 1;
336	}
337
338	for (n = 0, dstoff = offset; n < nsec; n++, dstoff += secsize) {
339
340		g_eli_crypto_ivgen(&gdev->sc, dstoff, iv, G_ELI_IVKEYLEN);
341
342		/* Get the key that corresponds to this offset. */
343		keyno = (dstoff >> G_ELI_KEY_SHIFT) / secsize;
344		g_eli_key_fill(&gdev->sc, &gkey, keyno);
345
346		error = geliboot_crypt(gdev->sc.sc_ealgo, 0, pbuf, secsize,
347		    gkey.gek_key, gdev->sc.sc_ekeylen, iv);
348
349		if (error != 0) {
350			explicit_bzero(&gkey, sizeof(gkey));
351			printf("Failed to decrypt in geli_read()!");
352			return (error);
353		}
354		pbuf += secsize;
355	}
356	explicit_bzero(&gkey, sizeof(gkey));
357	return (0);
358}
359
360int
361geli_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
375int
376geli_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