xref: /freebsd-13-stable/sys/geom/bde/g_bde_lock.c (revision f8167e0404dab9ffeaca95853dd237ab7c587f82)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2002 Poul-Henning Kamp
5  * Copyright (c) 2002 Networks Associates Technology, Inc.
6  * All rights reserved.
7  *
8  * This software was developed for the FreeBSD Project by Poul-Henning Kamp
9  * and NAI Labs, the Security Research Division of Network Associates, Inc.
10  * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
11  * DARPA CHATS research program.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 /* This souce file contains routines which operates on the lock sectors, both
35  * for the kernel and the userland program gbde(1).
36  *
37  */
38 
39 #include <sys/param.h>
40 #include <sys/queue.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/endian.h>
44 #include <sys/md5.h>
45 
46 #ifdef _KERNEL
47 #include <sys/malloc.h>
48 #include <sys/systm.h>
49 #else
50 #include <err.h>
51 #define CTASSERT(foo)
52 #define KASSERT(foo, bar) do { if(!(foo)) { warn bar ; exit (1); } } while (0)
53 #include <errno.h>
54 #include <string.h>
55 #include <stdlib.h>
56 #include <stdio.h>
57 #define g_free(foo)	free(foo)
58 #endif
59 
60 #include <crypto/rijndael/rijndael-api-fst.h>
61 #include <crypto/sha2/sha512.h>
62 
63 #include <geom/geom.h>
64 #include <geom/bde/g_bde.h>
65 
66 /*
67  * Hash the raw pass-phrase.
68  *
69  * Security objectives: produce from the pass-phrase a fixed length
70  * bytesequence with PRN like properties in a reproducible way retaining
71  * as much entropy from the pass-phrase as possible.
72  *
73  * SHA2-512 makes this easy.
74  */
75 
76 void
g_bde_hash_pass(struct g_bde_softc * sc,const void * input,u_int len)77 g_bde_hash_pass(struct g_bde_softc *sc, const void *input, u_int len)
78 {
79 	SHA512_CTX cx;
80 
81 	SHA512_Init(&cx);
82 	SHA512_Update(&cx, input, len);
83 	SHA512_Final(sc->sha2, &cx);
84 }
85 
86 /*
87  * Encode/Decode the lock structure in byte-sequence format.
88  *
89  * Security objectives: Store in pass-phrase dependent variant format.
90  *
91  * C-structure packing and byte-endianess depends on architecture, compiler
92  * and compiler options.  Writing raw structures to disk is therefore a bad
93  * idea in these enlightend days.
94  *
95  * We spend a fraction of the key-material on shuffling the fields around
96  * so they will be stored in an unpredictable sequence.
97  *
98  * For each byte of the key-material we derive two field indexes, and swap
99  * the position of those two fields.
100  *
101  * I have not worked out the statistical properties of this shuffle, but
102  * given that the key-material has PRN properties, the primary objective
103  * of making it hard to figure out which bits are where in the lock sector
104  * is sufficiently fulfilled.
105  *
106  * We include (and shuffle) an extra hash field in the stored version for
107  * identification and versioning purposes.  This field contains the MD5 hash
108  * of a version identifier (currently "0000") followed by the stored lock
109  * sector byte-sequence substituting zero bytes for the hash field.
110  *
111  * The stored keysequence is protected by AES/256/CBC elsewhere in the code
112  * so the fact that the generated byte sequence has a much higher than
113  * average density of zero bits (from the numeric fields) is not currently
114  * a concern.
115  *
116  * Should this later become a concern, a simple software update and
117  * pass-phrase change can remedy the situation.  One possible solution
118  * could be to XOR the numeric fields with a key-material derived PRN.
119  *
120  * The chosen shuffle algorithm only works as long as we have no more than 16
121  * fields in the stored part of the lock structure (hence the CTASSERT below).
122  */
123 
124 CTASSERT(NLOCK_FIELDS <= 16);
125 
126 static void
g_bde_shuffle_lock(u_char * sha2,int * buf)127 g_bde_shuffle_lock(u_char *sha2, int *buf)
128 {
129 	int j, k, l;
130 	u_int u;
131 
132 	/* Assign the fields sequential positions */
133 	for(u = 0; u < NLOCK_FIELDS; u++)
134 		buf[u] = u;
135 
136 	/* Then mix it all up */
137 	for(u = 48; u < SHA512_DIGEST_LENGTH; u++) {
138 		j = sha2[u] % NLOCK_FIELDS;
139 		k = (sha2[u] / NLOCK_FIELDS) % NLOCK_FIELDS;
140 		l = buf[j];
141 		buf[j] = buf[k];
142 		buf[k] = l;
143 	}
144 }
145 
146 int
g_bde_encode_lock(u_char * sha2,struct g_bde_key * gl,u_char * ptr)147 g_bde_encode_lock(u_char *sha2, struct g_bde_key *gl, u_char *ptr)
148 {
149 	int shuffle[NLOCK_FIELDS];
150 	u_char *hash, *p;
151 	int i;
152 	MD5_CTX c;
153 
154 	p = ptr;
155 	hash = NULL;
156 	g_bde_shuffle_lock(sha2, shuffle);
157 	for (i = 0; i < NLOCK_FIELDS; i++) {
158 		switch(shuffle[i]) {
159 		case 0:
160 			le64enc(p, gl->sector0);
161 			p += 8;
162 			break;
163 		case 1:
164 			le64enc(p, gl->sectorN);
165 			p += 8;
166 			break;
167 		case 2:
168 			le64enc(p, gl->keyoffset);
169 			p += 8;
170 			break;
171 		case 3:
172 			le32enc(p, gl->sectorsize);
173 			p += 4;
174 			break;
175 		case 4:
176 			le32enc(p, gl->flags);
177 			p += 4;
178 			break;
179 		case 5:
180 		case 6:
181 		case 7:
182 		case 8:
183 			le64enc(p, gl->lsector[shuffle[i] - 5]);
184 			p += 8;
185 			break;
186 		case 9:
187 			bcopy(gl->spare, p, sizeof gl->spare);
188 			p += sizeof gl->spare;
189 			break;
190 		case 10:
191 			bcopy(gl->salt, p, sizeof gl->salt);
192 			p += sizeof gl->salt;
193 			break;
194 		case 11:
195 			bcopy(gl->mkey, p, sizeof gl->mkey);
196 			p += sizeof gl->mkey;
197 			break;
198 		case 12:
199 			bzero(p, 16);
200 			hash = p;
201 			p += 16;
202 			break;
203 		}
204 	}
205 	if(ptr + G_BDE_LOCKSIZE != p)
206 		return(-1);
207 	if (hash == NULL)
208 		return(-1);
209 	MD5Init(&c);
210 	MD5Update(&c, "0000", 4);	/* Versioning */
211 	MD5Update(&c, ptr, G_BDE_LOCKSIZE);
212 	MD5Final(hash, &c);
213 	return(0);
214 }
215 
216 int
g_bde_decode_lock(struct g_bde_softc * sc,struct g_bde_key * gl,u_char * ptr)217 g_bde_decode_lock(struct g_bde_softc *sc, struct g_bde_key *gl, u_char *ptr)
218 {
219 	int shuffle[NLOCK_FIELDS];
220 	u_char *p;
221 	u_char hash[16], hash2[16];
222 	MD5_CTX c;
223 	int i;
224 
225 	p = ptr;
226 	g_bde_shuffle_lock(sc->sha2, shuffle);
227 	for (i = 0; i < NLOCK_FIELDS; i++) {
228 		switch(shuffle[i]) {
229 		case 0:
230 			gl->sector0 = le64dec(p);
231 			p += 8;
232 			break;
233 		case 1:
234 			gl->sectorN = le64dec(p);
235 			p += 8;
236 			break;
237 		case 2:
238 			gl->keyoffset = le64dec(p);
239 			p += 8;
240 			break;
241 		case 3:
242 			gl->sectorsize = le32dec(p);
243 			p += 4;
244 			break;
245 		case 4:
246 			gl->flags = le32dec(p);
247 			p += 4;
248 			break;
249 		case 5:
250 		case 6:
251 		case 7:
252 		case 8:
253 			gl->lsector[shuffle[i] - 5] = le64dec(p);
254 			p += 8;
255 			break;
256 		case 9:
257 			bcopy(p, gl->spare, sizeof gl->spare);
258 			p += sizeof gl->spare;
259 			break;
260 		case 10:
261 			bcopy(p, gl->salt, sizeof gl->salt);
262 			p += sizeof gl->salt;
263 			break;
264 		case 11:
265 			bcopy(p, gl->mkey, sizeof gl->mkey);
266 			p += sizeof gl->mkey;
267 			break;
268 		case 12:
269 			bcopy(p, hash2, sizeof hash2);
270 			bzero(p, sizeof hash2);
271 			p += sizeof hash2;
272 			break;
273 		}
274 	}
275 	if(ptr + G_BDE_LOCKSIZE != p)
276 		return(-1);
277 	MD5Init(&c);
278 	MD5Update(&c, "0000", 4);	/* Versioning */
279 	MD5Update(&c, ptr, G_BDE_LOCKSIZE);
280 	MD5Final(hash, &c);
281 	if (bcmp(hash, hash2, sizeof hash2))
282 		return (1);
283 	return (0);
284 }
285 
286 /*
287  * Encode/Decode the locksector address ("metadata") with key-material.
288  *
289  * Security objectives: Encode/Decode the metadata encrypted by key-material.
290  *
291  * A simple AES/128/CBC will do.  We take care to always store the metadata
292  * in the same endianness to make it MI.
293  *
294  * In the typical case the metadata is stored in encrypted format in sector
295  * zero on the media, but at the users discretion or if the piece of the
296  * device used (sector0...sectorN) does not contain sector zero, it can
297  * be stored in a filesystem or on a PostIt.
298  *
299  * The inability to easily locate the lock sectors makes an attack on a
300  * cold disk much less attractive, without unduly inconveniencing the
301  * legitimate user who can feasibly do a brute-force scan if the metadata
302  * was lost.
303  */
304 
305 int
g_bde_keyloc_encrypt(u_char * sha2,uint64_t v0,uint64_t v1,void * output)306 g_bde_keyloc_encrypt(u_char *sha2, uint64_t v0, uint64_t v1, void *output)
307 {
308 	u_char buf[16];
309 	keyInstance ki;
310 	cipherInstance ci;
311 
312 	le64enc(buf, v0);
313 	le64enc(buf + 8, v1);
314 	AES_init(&ci);
315 	AES_makekey(&ki, DIR_ENCRYPT, G_BDE_KKEYBITS, sha2 + 0);
316 	AES_encrypt(&ci, &ki, buf, output, sizeof buf);
317 	explicit_bzero(buf, sizeof buf);
318 	explicit_bzero(&ci, sizeof ci);
319 	explicit_bzero(&ki, sizeof ki);
320 	return (0);
321 }
322 
323 int
g_bde_keyloc_decrypt(u_char * sha2,void * input,uint64_t * output)324 g_bde_keyloc_decrypt(u_char *sha2, void *input, uint64_t *output)
325 {
326 	keyInstance ki;
327 	cipherInstance ci;
328 	u_char buf[16];
329 
330 	AES_init(&ci);
331 	AES_makekey(&ki, DIR_DECRYPT, G_BDE_KKEYBITS, sha2 + 0);
332 	AES_decrypt(&ci, &ki, input, buf, sizeof buf);
333 	*output = le64dec(buf);
334 	explicit_bzero(buf, sizeof buf);
335 	explicit_bzero(&ci, sizeof ci);
336 	explicit_bzero(&ki, sizeof ki);
337 	return(0);
338 }
339 
340 /*
341  * Find and Encode/Decode lock sectors.
342  *
343  * Security objective: given the pass-phrase, find, decrypt, decode and
344  * validate the lock sector contents.
345  *
346  * For ondisk metadata we cannot know beforehand which of the lock sectors
347  * a given pass-phrase opens so we must try each of the metadata copies in
348  * sector zero in turn.  If metadata was passed as an argument, we don't
349  * have this problem.
350  *
351  */
352 
353 static int
g_bde_decrypt_lockx(struct g_bde_softc * sc,u_char * meta,off_t mediasize,u_int sectorsize,u_int * nkey)354 g_bde_decrypt_lockx(struct g_bde_softc *sc, u_char *meta, off_t mediasize, u_int sectorsize, u_int *nkey)
355 {
356 	u_char *buf, *q;
357 	struct g_bde_key *gl;
358 	uint64_t off, q1;
359 	int error, m, i;
360 	keyInstance ki;
361 	cipherInstance ci;
362 
363 	gl = &sc->key;
364 
365 	/* Try to decrypt the metadata */
366 	error = g_bde_keyloc_decrypt(sc->sha2, meta, &off);
367 	if (error)
368 		return (error);
369 
370 	/* If it points into thin blue air, forget it */
371 	if (off + G_BDE_LOCKSIZE > (uint64_t)mediasize) {
372 		off = 0;
373 		return (EINVAL);
374 	}
375 
376 	/* The lock data may span two physical sectors. */
377 
378 	m = 1;
379 	if (off % sectorsize > sectorsize - G_BDE_LOCKSIZE)
380 		m++;
381 
382 	/* Read the suspected sector(s) */
383 	buf = g_read_data(sc->consumer,
384 		off - (off % sectorsize),
385 		m * sectorsize, &error);
386 	if (buf == NULL) {
387 		off = 0;
388 		return(error);
389 	}
390 
391 	/* Find the byte-offset of the stored byte sequence */
392 	q = buf + off % sectorsize;
393 
394 	/* If it is all zero, somebody nuked our lock sector */
395 	q1 = 0;
396 	for (i = 0; i < G_BDE_LOCKSIZE; i++)
397 		q1 += q[i];
398 	if (q1 == 0) {
399 		off = 0;
400 		g_free(buf);
401 		return (ESRCH);
402 	}
403 
404 	/* Decrypt the byte-sequence in place */
405 	AES_init(&ci);
406 	AES_makekey(&ki, DIR_DECRYPT, 256, sc->sha2 + 16);
407 	AES_decrypt(&ci, &ki, q, q, G_BDE_LOCKSIZE);
408 
409 	/* Decode the byte-sequence */
410 	i = g_bde_decode_lock(sc, gl, q);
411 	q = NULL;
412 	if (i < 0) {
413 		off = 0;
414 		return (EDOOFUS);	/* Programming error */
415 	} else if (i > 0) {
416 		off = 0;
417 		return (ENOTDIR);	/* Hash didn't match */
418 	}
419 
420 	bzero(buf, sectorsize * m);
421 	g_free(buf);
422 
423 	/* If the masterkey is all zeros, user destroyed it */
424 	q1 = 0;
425 	for (i = 0; i < (int)sizeof(gl->mkey); i++)
426 		q1 += gl->mkey[i];
427 	if (q1 == 0)
428 		return (ENOENT);
429 
430 	/* If we have an unsorted lock-sequence, refuse */
431 	for (i = 0; i < G_BDE_MAXKEYS - 1; i++)
432 		if (gl->lsector[i] >= gl->lsector[i + 1])
433 			return (EINVAL);
434 
435 	/* Finally, find out which key was used by matching the byte offset */
436 	for (i = 0; i < G_BDE_MAXKEYS; i++)
437 		if (nkey != NULL && off == gl->lsector[i])
438 			*nkey = i;
439 	off = 0;
440 	return (0);
441 }
442 
443 int
g_bde_decrypt_lock(struct g_bde_softc * sc,u_char * keymat,u_char * meta,off_t mediasize,u_int sectorsize,u_int * nkey)444 g_bde_decrypt_lock(struct g_bde_softc *sc, u_char *keymat, u_char *meta, off_t mediasize, u_int sectorsize, u_int *nkey)
445 {
446 	u_char *buf, buf1[16];
447 	int error, e, i;
448 
449 	/* set up the key-material */
450 	bcopy(keymat, sc->sha2, SHA512_DIGEST_LENGTH);
451 
452 	/* If passed-in metadata is non-zero, use it */
453 	bzero(buf1, sizeof buf1);
454 	if (meta != NULL && bcmp(buf1, meta, sizeof buf1))
455 		return (g_bde_decrypt_lockx(sc, meta, mediasize,
456 		    sectorsize, nkey));
457 
458 	/* Read sector zero */
459 	buf = g_read_data(sc->consumer, 0, sectorsize, &error);
460 	if (buf == NULL)
461 		return(error);
462 
463 	/* Try each index in turn, save indicative errors for final result */
464 	error = EINVAL;
465 	for (i = 0; i < G_BDE_MAXKEYS; i++) {
466 		e = g_bde_decrypt_lockx(sc, buf + i * 16, mediasize,
467 		    sectorsize, nkey);
468 		/* Success or destroyed master key terminates */
469 		if (e == 0 || e == ENOENT) {
470 			error = e;
471 			break;
472 		}
473 		if (e != 0 && error == EINVAL)
474 			error = e;
475 	}
476 	g_free(buf);
477 	return (error);
478 }
479