Deleted Added
full compact
gbde.c (106227) gbde.c (106407)
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9 * DARPA CHATS research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
9 * DARPA CHATS research program.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The names of the authors may not be used to endorse or promote
20 * products derived from this software without specific prior written
21 * permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
35 * $FreeBSD: head/sbin/gbde/gbde.c 106227 2002-10-30 22:14:34Z phk $
32 * $FreeBSD: head/sbin/gbde/gbde.c 106407 2002-11-04 09:27:01Z phk $
36 */
37
38#include <sys/types.h>
39#include <sys/queue.h>
40#include <sys/mutex.h>
41#include <md5.h>
42#include <readpassphrase.h>
43#include <string.h>
44#include <stdint.h>
45#include <unistd.h>
46#include <fcntl.h>
47#include <strings.h>
48#include <stdlib.h>
49#include <err.h>
50#include <stdio.h>
51#include <libutil.h>
52#include <sys/errno.h>
53#include <sys/disk.h>
33 */
34
35#include <sys/types.h>
36#include <sys/queue.h>
37#include <sys/mutex.h>
38#include <md5.h>
39#include <readpassphrase.h>
40#include <string.h>
41#include <stdint.h>
42#include <unistd.h>
43#include <fcntl.h>
44#include <strings.h>
45#include <stdlib.h>
46#include <err.h>
47#include <stdio.h>
48#include <libutil.h>
49#include <sys/errno.h>
50#include <sys/disk.h>
51#include <sys/stat.h>
54#include <crypto/rijndael/rijndael.h>
52#include <crypto/rijndael/rijndael.h>
53#include <crypto/sha2/sha2.h>
55
54
55#define KASSERT(foo, bar) do { if(!(foo)) { warn bar ; exit (1); } } while (0)
56
56#include <geom/geom.h>
57#include <geom/bde/g_bde.h>
58
59extern const char template[];
60
57#include <geom/geom.h>
58#include <geom/bde/g_bde.h>
59
60extern const char template[];
61
62
63#if 0
64static void
65g_hexdump(void *ptr, int length)
66{
67 int i, j, k;
68 unsigned char *cp;
69
70 cp = ptr;
71 for (i = 0; i < length; i+= 16) {
72 printf("%04x ", i);
73 for (j = 0; j < 16; j++) {
74 k = i + j;
75 if (k < length)
76 printf(" %02x", cp[k]);
77 else
78 printf(" ");
79 }
80 printf(" |");
81 for (j = 0; j < 16; j++) {
82 k = i + j;
83 if (k >= length)
84 printf(" ");
85 else if (cp[k] >= ' ' && cp[k] <= '~')
86 printf("%c", cp[k]);
87 else
88 printf(".");
89 }
90 printf("|\n");
91 }
92}
93#endif
94
61static void __dead2
62usage(const char *reason)
63{
64 const char *p;
65
66 p = getprogname();
67 fprintf(stderr, "Usage error: %s", reason);
68 fprintf(stderr, "Usage:\n");

--- 40 unchanged lines hidden (view full) ---

109 }
110
111 i = read(fdr, p, len);
112 if (i != (int)len)
113 err(1, "read from /dev/urandom");
114}
115
116/* XXX: not nice */
95static void __dead2
96usage(const char *reason)
97{
98 const char *p;
99
100 p = getprogname();
101 fprintf(stderr, "Usage error: %s", reason);
102 fprintf(stderr, "Usage:\n");

--- 40 unchanged lines hidden (view full) ---

143 }
144
145 i = read(fdr, p, len);
146 if (i != (int)len)
147 err(1, "read from /dev/urandom");
148}
149
150/* XXX: not nice */
117static u_char sbox[256];
151static u_char sha2[SHA512_DIGEST_LENGTH];
118
119static void
120reset_passphrase(struct g_bde_softc *sc)
121{
122
152
153static void
154reset_passphrase(struct g_bde_softc *sc)
155{
156
123 memcpy(sc->arc4_sbox, sbox, 256);
124 sc->arc4_i = sc->arc4_j = 0;
157 memcpy(sc->sha2, sha2, SHA512_DIGEST_LENGTH);
125}
126
127static void
128setup_passphrase(struct g_bde_softc *sc, int sure, const char *input)
129{
130 char buf1[BUFSIZ], buf2[BUFSIZ], *p;
131
132 if (input != NULL) {
158}
159
160static void
161setup_passphrase(struct g_bde_softc *sc, int sure, const char *input)
162{
163 char buf1[BUFSIZ], buf2[BUFSIZ], *p;
164
165 if (input != NULL) {
133 g_bde_arc4_seed(sc, input, strlen(input));
134 memcpy(sbox, sc->arc4_sbox, 256);
166 g_bde_hash_pass(sc, input, strlen(input));
167 memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH);
135 return;
136 }
137 for (;;) {
138 p = readpassphrase(
139 sure ? "Enter new passphrase:" : "Enter passphrase: ",
140 buf1, sizeof buf1,
141 RPP_ECHO_OFF | RPP_REQUIRE_TTY);
142 if (p == NULL)

--- 12 unchanged lines hidden (view full) ---

155 }
156 }
157 if (strlen(buf1) < 3) {
158 printf("Too short passphrase.\n");
159 continue;
160 }
161 break;
162 }
168 return;
169 }
170 for (;;) {
171 p = readpassphrase(
172 sure ? "Enter new passphrase:" : "Enter passphrase: ",
173 buf1, sizeof buf1,
174 RPP_ECHO_OFF | RPP_REQUIRE_TTY);
175 if (p == NULL)

--- 12 unchanged lines hidden (view full) ---

188 }
189 }
190 if (strlen(buf1) < 3) {
191 printf("Too short passphrase.\n");
192 continue;
193 }
194 break;
195 }
163 g_bde_arc4_seed(sc, buf1, strlen(buf1));
164 memcpy(sbox, sc->arc4_sbox, 256);
196 g_bde_hash_pass(sc, buf1, strlen(buf1));
197 memcpy(sha2, sc->sha2, SHA512_DIGEST_LENGTH);
165}
166
167static void
198}
199
200static void
168encrypt_sector(void *d, int len, void *key)
201encrypt_sector(void *d, int len, int klen, void *key)
169{
170 keyInstance ki;
171 cipherInstance ci;
172 int error;
173
174 error = rijndael_cipherInit(&ci, MODE_CBC, NULL);
175 if (error <= 0)
176 errx(1, "rijndael_cipherInit=%d", error);
202{
203 keyInstance ki;
204 cipherInstance ci;
205 int error;
206
207 error = rijndael_cipherInit(&ci, MODE_CBC, NULL);
208 if (error <= 0)
209 errx(1, "rijndael_cipherInit=%d", error);
177 error = rijndael_makeKey(&ki, DIR_ENCRYPT, 128, key);
210 error = rijndael_makeKey(&ki, DIR_ENCRYPT, klen, key);
178 if (error <= 0)
179 errx(1, "rijndael_makeKeY=%d", error);
180 error = rijndael_blockEncrypt(&ci, &ki, d, len * 8, d);
181 if (error <= 0)
182 errx(1, "rijndael_blockEncrypt=%d", error);
183}
184
185static void

--- 14 unchanged lines hidden (view full) ---

200 gcg.flag = 0;
201 gcg.len = sizeof buf;
202 gcg.ptr = buf;
203
204 if (lfile != NULL) {
205 ffd = open(lfile, O_RDONLY, 0);
206 if (ffd < 0)
207 err(1, lfile);
211 if (error <= 0)
212 errx(1, "rijndael_makeKeY=%d", error);
213 error = rijndael_blockEncrypt(&ci, &ki, d, len * 8, d);
214 if (error <= 0)
215 errx(1, "rijndael_blockEncrypt=%d", error);
216}
217
218static void

--- 14 unchanged lines hidden (view full) ---

233 gcg.flag = 0;
234 gcg.len = sizeof buf;
235 gcg.ptr = buf;
236
237 if (lfile != NULL) {
238 ffd = open(lfile, O_RDONLY, 0);
239 if (ffd < 0)
240 err(1, lfile);
208 read(ffd, buf + 256, 16);
241 read(ffd, buf + sizeof(sc->sha2), 16);
209 close(ffd);
210 } else {
242 close(ffd);
243 } else {
211 memset(buf + 256, 0, 16);
244 memset(buf + sizeof(sc->sha2), 0, 16);
212 }
245 }
213 memcpy(buf, sc->arc4_sbox, 256);
246 memcpy(buf, sc->sha2, sizeof(sc->sha2));
214
215 i = ioctl(gfd, GEOMCONFIGGEOM, &gcg);
216 if (i != 0)
217 err(1, "ioctl(GEOMCONFIGGEOM)");
218 exit (0);
219}
220
221static void

--- 14 unchanged lines hidden (view full) ---

236
237 i = ioctl(gfd, GEOMCONFIGGEOM, &gcg);
238 if (i != 0)
239 err(1, "ioctl(GEOMCONFIGGEOM)");
240 exit (0);
241}
242
243static void
247
248 i = ioctl(gfd, GEOMCONFIGGEOM, &gcg);
249 if (i != 0)
250 err(1, "ioctl(GEOMCONFIGGEOM)");
251 exit (0);
252}
253
254static void

--- 14 unchanged lines hidden (view full) ---

269
270 i = ioctl(gfd, GEOMCONFIGGEOM, &gcg);
271 if (i != 0)
272 err(1, "ioctl(GEOMCONFIGGEOM)");
273 exit (0);
274}
275
276static void
244cmd_open(struct g_bde_softc *sc, int dfd __unused, const char *l_opt, u_int *nkey)
277cmd_open(struct g_bde_softc *sc, int dfd , const char *l_opt, u_int *nkey)
245{
246 int error;
247 int ffd;
248 u_char keyloc[16];
278{
279 int error;
280 int ffd;
281 u_char keyloc[16];
282 u_int sectorsize;
283 off_t mediasize;
284 struct stat st;
249
285
286 error = ioctl(dfd, DIOCGSECTORSIZE, &sectorsize);
287 if (error)
288 sectorsize = 512;
289 error = ioctl(dfd, DIOCGMEDIASIZE, &mediasize);
290 if (error) {
291 error = fstat(dfd, &st);
292 if (error == 0 && S_ISREG(st.st_mode))
293 mediasize = st.st_size;
294 else
295 error = ENOENT;
296 }
297 if (error)
298 mediasize = (off_t)-1;
250 if (l_opt != NULL) {
251 ffd = open(l_opt, O_RDONLY, 0);
252 if (ffd < 0)
253 err(1, l_opt);
254 read(ffd, keyloc, sizeof keyloc);
255 close(ffd);
256 } else {
257 memset(keyloc, 0, sizeof keyloc);
258 }
259
299 if (l_opt != NULL) {
300 ffd = open(l_opt, O_RDONLY, 0);
301 if (ffd < 0)
302 err(1, l_opt);
303 read(ffd, keyloc, sizeof keyloc);
304 close(ffd);
305 } else {
306 memset(keyloc, 0, sizeof keyloc);
307 }
308
260 error = g_bde_decrypt_lock(sc, sbox, keyloc, 0xffffffff,
261 512, nkey);
309 error = g_bde_decrypt_lock(sc, sc->sha2, keyloc, mediasize,
310 sectorsize, nkey);
262 if (error == ENOENT)
263 errx(1, "Lock was destroyed.");
264 if (error == ESRCH)
265 errx(1, "Lock was nuked.");
266 if (error == ENOTDIR)
267 errx(1, "Lock not found");
268 if (error != 0)
269 errx(1, "Error %d decrypting lock", error);

--- 19 unchanged lines hidden (view full) ---

289 if (i != (int)gl->sectorsize)
290 err(1, "write");
291 printf("Nuked key %d\n", key);
292}
293
294static void
295cmd_write(struct g_bde_key *gl, struct g_bde_softc *sc, int dfd , int key, const char *l_opt)
296{
311 if (error == ENOENT)
312 errx(1, "Lock was destroyed.");
313 if (error == ESRCH)
314 errx(1, "Lock was nuked.");
315 if (error == ENOTDIR)
316 errx(1, "Lock not found");
317 if (error != 0)
318 errx(1, "Error %d decrypting lock", error);

--- 19 unchanged lines hidden (view full) ---

338 if (i != (int)gl->sectorsize)
339 err(1, "write");
340 printf("Nuked key %d\n", key);
341}
342
343static void
344cmd_write(struct g_bde_key *gl, struct g_bde_softc *sc, int dfd , int key, const char *l_opt)
345{
297 char buf[BUFSIZ];
298 int i, ffd;
299 uint64_t off[2];
300 u_char keyloc[16];
301 u_char *sbuf, *q;
346 int i, ffd;
347 uint64_t off[2];
348 u_char keyloc[16];
349 u_char *sbuf, *q;
302 MD5_CTX c;
303 off_t offset, offset2;
304
305 sbuf = malloc(gl->sectorsize);
306 /*
307 * Find the byte-offset in the lock sector where we will put the lock
308 * data structure. We can put it any random place as long as the
309 * structure fits.
310 */

--- 36 unchanged lines hidden (view full) ---

347 errx(1, "No -L option and no space in sector 0 for lockfile");
348 }
349
350 /* Allocate a sectorbuffer and fill it with random junk */
351 if (sbuf == NULL)
352 err(1, "malloc");
353 random_bits(sbuf, gl->sectorsize);
354
350 off_t offset, offset2;
351
352 sbuf = malloc(gl->sectorsize);
353 /*
354 * Find the byte-offset in the lock sector where we will put the lock
355 * data structure. We can put it any random place as long as the
356 * structure fits.
357 */

--- 36 unchanged lines hidden (view full) ---

394 errx(1, "No -L option and no space in sector 0 for lockfile");
395 }
396
397 /* Allocate a sectorbuffer and fill it with random junk */
398 if (sbuf == NULL)
399 err(1, "malloc");
400 random_bits(sbuf, gl->sectorsize);
401
355 /* Fill in the hash field with something we can recognize again */
356 g_bde_arc4_seq(sc, buf, 16);
357 MD5Init(&c);
358 MD5Update(&c, "0000", 4); /* XXX: for future versioning */
359 MD5Update(&c, buf, 16);
360 MD5Final(gl->hash, &c);
361
362 /* Fill random bits in the spare field */
363 random_bits(gl->spare, sizeof(gl->spare));
364
365 /* Encode the structure where we want it */
366 q = sbuf + (off[0] % gl->sectorsize);
402 /* Fill random bits in the spare field */
403 random_bits(gl->spare, sizeof(gl->spare));
404
405 /* Encode the structure where we want it */
406 q = sbuf + (off[0] % gl->sectorsize);
367 g_bde_encode_lock(gl, q);
407 i = g_bde_encode_lock(sc, gl, q);
408 if (i < 0)
409 errx(1, "programming error encoding lock");
368
410
369 /*
370 * The encoded structure likely contains long sequences of zeros
371 * which stick out as a sore thumb, so we XOR with key-material
372 * to make it harder to recognize in a brute-force attack
373 */
374 g_bde_arc4_seq(sc, buf, G_BDE_LOCKSIZE);
375 for (i = 0; i < G_BDE_LOCKSIZE; i++)
376 q[i] ^= buf[i];
377
378 g_bde_arc4_seq(sc, buf, 16);
379
380 encrypt_sector(q, G_BDE_LOCKSIZE, buf);
411 encrypt_sector(q, G_BDE_LOCKSIZE, 256, sc->sha2 + 16);
381 offset = gl->lsector[key] & ~(gl->sectorsize - 1);
382 offset2 = lseek(dfd, offset, SEEK_SET);
383 if (offset2 != offset)
384 err(1, "lseek");
385 i = write(dfd, sbuf, gl->sectorsize);
386 if (i != (int)gl->sectorsize)
387 err(1, "write");
388 printf("Wrote key %d at %jd\n", key, (intmax_t)offset);

--- 363 unchanged lines hidden ---
412 offset = gl->lsector[key] & ~(gl->sectorsize - 1);
413 offset2 = lseek(dfd, offset, SEEK_SET);
414 if (offset2 != offset)
415 err(1, "lseek");
416 i = write(dfd, sbuf, gl->sectorsize);
417 if (i != (int)gl->sectorsize)
418 err(1, "write");
419 printf("Wrote key %d at %jd\n", key, (intmax_t)offset);

--- 363 unchanged lines hidden ---