]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/geli/geliboot.c
MFC Loader Fixes 2017q1: r311458,r312237,r312314,r312374,r312947,r313042,
[FreeBSD/FreeBSD.git] / sys / boot / geli / geliboot.c
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$
28  */
29
30 #include "geliboot_internal.h"
31 #include "geliboot.h"
32
33 SLIST_HEAD(geli_list, geli_entry) geli_head = SLIST_HEAD_INITIALIZER(geli_head);
34 struct geli_list *geli_headp;
35
36 typedef u_char geli_ukey[G_ELI_USERKEYLEN];
37
38 static geli_ukey saved_keys[GELI_MAX_KEYS];
39 static unsigned int nsaved_keys = 0;
40
41 /*
42  * Copy keys from local storage to the keybuf struct.
43  * Destroy the local storage when finished.
44  */
45 void
46 geli_fill_keybuf(struct keybuf *fkeybuf)
47 {
48         unsigned int i;
49
50         for (i = 0; i < nsaved_keys; i++) {
51                 fkeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_GELI;
52                 memcpy(fkeybuf->kb_ents[i].ke_data, saved_keys[i],
53                     G_ELI_USERKEYLEN);
54         }
55         fkeybuf->kb_nents = nsaved_keys;
56         explicit_bzero(saved_keys, sizeof(saved_keys));
57 }
58
59 /*
60  * Copy keys from a keybuf struct into local storage.
61  * Zero out the keybuf.
62  */
63 void
64 geli_save_keybuf(struct keybuf *skeybuf)
65 {
66         unsigned int i;
67
68         for (i = 0; i < skeybuf->kb_nents && i < GELI_MAX_KEYS; i++) {
69                 memcpy(saved_keys[i], skeybuf->kb_ents[i].ke_data,
70                     G_ELI_USERKEYLEN);
71                 explicit_bzero(skeybuf->kb_ents[i].ke_data,
72                     G_ELI_USERKEYLEN);
73                 skeybuf->kb_ents[i].ke_type = KEYBUF_TYPE_NONE;
74         }
75         nsaved_keys = skeybuf->kb_nents;
76         skeybuf->kb_nents = 0;
77 }
78
79 static void
80 save_key(geli_ukey key)
81 {
82
83         /*
84          * If we run out of key space, the worst that will happen is
85          * it will ask the user for the password again.
86          */
87         if (nsaved_keys < GELI_MAX_KEYS) {
88                 memcpy(saved_keys[nsaved_keys], key, G_ELI_USERKEYLEN);
89                 nsaved_keys++;
90         }
91 }
92
93 static int
94 geli_same_device(struct geli_entry *ge, struct dsk *dskp)
95 {
96
97         if (ge->dsk->drive == dskp->drive &&
98             dskp->part == 255 && ge->dsk->part == dskp->slice) {
99                 /*
100                  * Sometimes slice = slice, and sometimes part = slice
101                  * If the incoming struct dsk has part=255, it means look at
102                  * the slice instead of the part number
103                  */
104                 return (0);
105         }
106
107         /* Is this the same device? */
108         if (ge->dsk->drive != dskp->drive ||
109             ge->dsk->slice != dskp->slice ||
110             ge->dsk->part != dskp->part) {
111                 return (1);
112         }
113
114         return (0);
115 }
116
117 static int
118 geli_findkey(struct geli_entry *ge, struct dsk *dskp, u_char *mkey)
119 {
120         u_int keynum;
121         int i;
122
123         if (ge->keybuf_slot >= 0) {
124                 if (g_eli_mkey_decrypt(&ge->md, saved_keys[ge->keybuf_slot],
125                     mkey, &keynum) == 0) {
126                         return (0);
127                 }
128         }
129
130         for (i = 0; i < nsaved_keys; i++) {
131                 if (g_eli_mkey_decrypt(&ge->md, saved_keys[i], mkey,
132                     &keynum) == 0) {
133                         ge->keybuf_slot = i;
134                         return (0);
135                 }
136         }
137
138         return (1);
139 }
140
141 void
142 geli_init(void)
143 {
144
145         geli_count = 0;
146         SLIST_INIT(&geli_head);
147 }
148
149 /*
150  * Read the last sector of the drive or partition pointed to by dsk and see
151  * if it is GELI encrypted
152  */
153 int
154 geli_taste(int read_func(void *vdev, void *priv, off_t off, void *buf,
155     size_t bytes), struct dsk *dskp, daddr_t lastsector)
156 {
157         struct g_eli_metadata md;
158         u_char buf[DEV_GELIBOOT_BSIZE];
159         int error;
160         off_t alignsector;
161
162         alignsector = rounddown2(lastsector * DEV_BSIZE, DEV_GELIBOOT_BSIZE);
163         if (alignsector + DEV_GELIBOOT_BSIZE > ((lastsector + 1) * DEV_BSIZE)) {
164                 /* Don't read past the end of the disk */
165                 alignsector = (lastsector * DEV_BSIZE) + DEV_BSIZE
166                     - DEV_GELIBOOT_BSIZE;
167         }
168         error = read_func(NULL, dskp, alignsector, &buf, DEV_GELIBOOT_BSIZE);
169         if (error != 0) {
170                 return (error);
171         }
172         /* Extract the last 4k sector of the disk. */
173         error = eli_metadata_decode(buf, &md);
174         if (error != 0) {
175                 /* Try the last 512 byte sector instead. */
176                 error = eli_metadata_decode(buf +
177                     (DEV_GELIBOOT_BSIZE - DEV_BSIZE), &md);
178                 if (error != 0) {
179                         return (error);
180                 }
181         }
182
183         if (!(md.md_flags & G_ELI_FLAG_GELIBOOT)) {
184                 /* The GELIBOOT feature is not activated */
185                 return (1);
186         }
187         if ((md.md_flags & G_ELI_FLAG_ONETIME)) {
188                 /* Swap device, skip it. */
189                 return (1);
190         }
191         if (md.md_iterations < 0) {
192                 /* XXX TODO: Support loading key files. */
193                 /* Disk does not have a passphrase, skip it. */
194                 return (1);
195         }
196         geli_e = malloc(sizeof(struct geli_entry));
197         if (geli_e == NULL)
198                 return (2);
199
200         geli_e->dsk = malloc(sizeof(struct dsk));
201         if (geli_e->dsk == NULL)
202                 return (2);
203         memcpy(geli_e->dsk, dskp, sizeof(struct dsk));
204         geli_e->part_end = lastsector;
205         if (dskp->part == 255) {
206                 geli_e->dsk->part = dskp->slice;
207         }
208         geli_e->keybuf_slot = -1;
209
210         geli_e->md = md;
211         eli_metadata_softc(&geli_e->sc, &md, DEV_BSIZE,
212             (lastsector + DEV_BSIZE) * DEV_BSIZE);
213
214         SLIST_INSERT_HEAD(&geli_head, geli_e, entries);
215         geli_count++;
216
217         return (0);
218 }
219
220 /*
221  * Attempt to decrypt the device
222  */
223 int
224 geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp)
225 {
226         u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN], *mkp;
227         u_int keynum;
228         struct hmac_ctx ctx;
229         int error;
230
231         if (mkeyp != NULL) {
232                 memcpy(&mkey, mkeyp, G_ELI_DATAIVKEYLEN);
233                 explicit_bzero(mkeyp, G_ELI_DATAIVKEYLEN);
234         }
235
236         SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
237                 if (geli_same_device(geli_e, dskp) != 0) {
238                         continue;
239                 }
240
241                 if (mkeyp != NULL || geli_findkey(geli_e, dskp, mkey) == 0) {
242                         goto found_key;
243                 }
244
245                 g_eli_crypto_hmac_init(&ctx, NULL, 0);
246                 /*
247                  * Prepare Derived-Key from the user passphrase.
248                  */
249                 if (geli_e->md.md_iterations < 0) {
250                         /* XXX TODO: Support loading key files. */
251                         return (1);
252                 } else if (geli_e->md.md_iterations == 0) {
253                         g_eli_crypto_hmac_update(&ctx, geli_e->md.md_salt,
254                             sizeof(geli_e->md.md_salt));
255                         g_eli_crypto_hmac_update(&ctx, passphrase,
256                             strlen(passphrase));
257                 } else if (geli_e->md.md_iterations > 0) {
258                         printf("Calculating GELI Decryption Key disk%dp%d @ %d"
259                             " iterations...\n", dskp->unit,
260                             (dskp->slice > 0 ? dskp->slice : dskp->part),
261                             geli_e->md.md_iterations);
262                         u_char dkey[G_ELI_USERKEYLEN];
263
264                         pkcs5v2_genkey(dkey, sizeof(dkey), geli_e->md.md_salt,
265                             sizeof(geli_e->md.md_salt), passphrase,
266                             geli_e->md.md_iterations);
267                         g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
268                         explicit_bzero(dkey, sizeof(dkey));
269                 }
270
271                 g_eli_crypto_hmac_final(&ctx, key, 0);
272
273                 error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
274                 if (error == -1) {
275                         explicit_bzero(mkey, sizeof(mkey));
276                         explicit_bzero(key, sizeof(key));
277                         printf("Bad GELI key: bad password?\n");
278                         return (error);
279                 } else if (error != 0) {
280                         explicit_bzero(mkey, sizeof(mkey));
281                         explicit_bzero(key, sizeof(key));
282                         printf("Failed to decrypt GELI master key: %d\n", error);
283                         return (error);
284                 } else {
285                         /* Add key to keychain */
286                         save_key(key);
287                         explicit_bzero(&key, sizeof(key));
288                 }
289
290 found_key:
291                 /* Store the keys */
292                 bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
293                 bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
294                 mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
295                 if ((geli_e->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
296                         bcopy(mkp, geli_e->sc.sc_ekey, G_ELI_DATAKEYLEN);
297                 } else {
298                         /*
299                          * The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
300                          */
301                         g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, "\x10", 1,
302                             geli_e->sc.sc_ekey, 0);
303                 }
304                 explicit_bzero(mkey, sizeof(mkey));
305
306                 /* Initialize the per-sector IV. */
307                 switch (geli_e->sc.sc_ealgo) {
308                 case CRYPTO_AES_XTS:
309                         break;
310                 default:
311                         SHA256_Init(&geli_e->sc.sc_ivctx);
312                         SHA256_Update(&geli_e->sc.sc_ivctx, geli_e->sc.sc_ivkey,
313                             sizeof(geli_e->sc.sc_ivkey));
314                         break;
315                 }
316
317                 return (0);
318         }
319
320         /* Disk not found. */
321         return (2);
322 }
323
324 int
325 is_geli(struct dsk *dskp)
326 {
327         SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
328                 if (geli_same_device(geli_e, dskp) == 0) {
329                         return (0);
330                 }
331         }
332
333         return (1);
334 }
335
336 int
337 geli_read(struct dsk *dskp, off_t offset, u_char *buf, size_t bytes)
338 {
339         u_char iv[G_ELI_IVKEYLEN];
340         u_char *pbuf;
341         int error;
342         off_t dstoff;
343         uint64_t keyno;
344         size_t n, nsec, secsize;
345         struct g_eli_key gkey;
346
347         pbuf = buf;
348         SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
349                 if (geli_same_device(geli_e, dskp) != 0) {
350                         continue;
351                 }
352
353                 secsize = geli_e->sc.sc_sectorsize;
354                 nsec = bytes / secsize;
355                 if (nsec == 0) {
356                         /*
357                          * A read of less than the GELI sector size has been
358                          * requested. The caller provided destination buffer may
359                          * not be big enough to boost the read to a full sector,
360                          * so just attempt to decrypt the truncated sector.
361                          */
362                         secsize = bytes;
363                         nsec = 1;
364                 }
365
366                 for (n = 0, dstoff = offset; n < nsec; n++, dstoff += secsize) {
367
368                         g_eli_crypto_ivgen(&geli_e->sc, dstoff, iv,
369                             G_ELI_IVKEYLEN);
370
371                         /* Get the key that corresponds to this offset. */
372                         keyno = (dstoff >> G_ELI_KEY_SHIFT) / secsize;
373                         g_eli_key_fill(&geli_e->sc, &gkey, keyno);
374
375                         error = geliboot_crypt(geli_e->sc.sc_ealgo, 0, pbuf,
376                             secsize, gkey.gek_key,
377                             geli_e->sc.sc_ekeylen, iv);
378
379                         if (error != 0) {
380                                 explicit_bzero(&gkey, sizeof(gkey));
381                                 printf("Failed to decrypt in geli_read()!");
382                                 return (error);
383                         }
384                         pbuf += secsize;
385                 }
386                 explicit_bzero(&gkey, sizeof(gkey));
387                 return (0);
388         }
389
390         printf("GELI provider not found\n");
391         return (1);
392 }
393
394 int
395 geli_havekey(struct dsk *dskp)
396 {
397         u_char mkey[G_ELI_DATAIVKEYLEN];
398
399         SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
400                 if (geli_same_device(geli_e, dskp) != 0) {
401                         continue;
402                 }
403
404                 if (geli_findkey(geli_e, dskp, mkey) == 0) {
405                         if (geli_attach(dskp, NULL, mkey) == 0) {
406                                 return (0);
407                         }
408                 }
409         }
410         explicit_bzero(mkey, sizeof(mkey));
411
412         return (1);
413 }
414
415 int
416 geli_passphrase(char *pw, int disk, int parttype, int part, struct dsk *dskp)
417 {
418         int i;
419
420         /* TODO: Implement GELI keyfile(s) support */
421         for (i = 0; i < 3; i++) {
422                 /* Try cached passphrase */
423                 if (i == 0 && pw[0] != '\0') {
424                         if (geli_attach(dskp, pw, NULL) == 0) {
425                                 return (0);
426                         }
427                 }
428                 printf("GELI Passphrase for disk%d%c%d: ", disk, parttype, part);
429                 pwgets(pw, GELI_PW_MAXLEN);
430                 printf("\n");
431                 if (geli_attach(dskp, pw, NULL) == 0) {
432                         return (0);
433                 }
434         }
435
436         return (1);
437 }