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, §orsize); 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 --- |