Status GBDE attach at boot [PATCH]

Allan Fields bsd at afields.ca
Wed Jan 21 07:22:16 PST 2004


On Sun, Jan 18, 2004 at 10:19:31AM -0500, Allan Fields wrote:
> On Sun, Jan 18, 2004 at 02:43:42PM +0100, Simon L. Nielsen wrote:
> > On 2004.01.17 14:53:58 -0500, Allan Fields wrote:
> > > Hi,
> > > 
> > > I'm interested to know what may be in the pipeline as far as GBDE
> > > boot time attach/automation support.  Has anyone committed to
> > > implementing these features?  (I don't see it anymore (on the 5.3
> > > todo list) in releng pages.)
> > 
> [...]
>
> Which brings us to passphrase from file/filedesc issue vs. from tty
> / on command line.  Could password prompts be read from another
> terminal or from secure source like key device or remote terminal
> while the booting continues in the mean-time?

Attached are patches implementing -k/-K command line options for
key entry from keyfile or on stdin.  It tests out OK with the
provided test script and I've had success using it myself under
5_2_0.

I'm hoping I didn't miss anything obvious in debugging.  Let me
know if you see something.  I would appreciate some feedback /
review, especially concerning safety of reading a key from a
regular file through the vfs.

I've also attached some session logs which demonstrate how to use
the feature.  If there are problems with splitting on newlines
I provided a -r option to put it into 'raw' ascii mode.

It operates on file streams so other descriptors besides stdin
could easily be made to work for more complicated cases.  Currently
if -k- and -K- are both specified, I'm not sure what happens. (It
could be made to work OK given they are provided as a newline
delimited tuple (Current_Key \n New_Key) on stdin.)

> > course the rc.d script could be enhanced e.g. to support random keys,
> > like your "temp" feature.

A note: that in the sources this is now known as the "onetime" verb
from what I can see.

> > -- 
> > Simon L. Nielsen
> > FreeBSD Documentation Team

-- 
 Allan Fields                  _.^.  ,_ ,. ._ .
 AFRSL - http://afields.ca    <,'/-\/- /\'_| /_
 Ottawa, Canada                `'|'====-=--- -- -
                                 `---- -- -
 BSDCan 2004: May 2004, Ottawa
 See http://www.bsdcan.org for details.
-------------- next part --------------
diff -r src-5_2/sbin/gbde/gbde.c src-5_2-afields/sbin/gbde/gbde.c
42a43,46
>  * Introduce -c, cipher specification
>  *
>  * Introduce -o, one-time-pad source
>  *
49,50d52
<  * Introduce -k/-K get pass-phrase part from file/cmd
<  *
64a67,68
>  * Investigate process memory scrubbing and file caching issues further
>  *
144a149,152
> 	fprintf(stderr, "Key entry:\n");
> 	fprintf(stderr, "\tBy default the user is prompted on the tty.  From the command line:\n");
> 	fprintf(stderr, "\t-p/-P <passphrase>\t\t-k/-K <keyfile>\n");
> 	fprintf(stderr, "\t-k-/-K- for input on stdin\t-r toggles 'raw' mode\n");
236a245,273
> static const char *
> read_keyfile(const char *keyf, int raw)
> { /* XXX: to be reviewed by authors */
> 	static FILE * kf;
> 	char kbuf[BUFSIZ];
> 	char c; int i;
> 
> 	if (strchr(&keyf[0],'-')&&
> 	    strchr(&keyf[1],'\0'))
> 		kf = fdopen(STDIN_FILENO,"r");
> 	else	kf = fopen(keyf,"r");
> 	if (kf == NULL)
> 		errx(errno,"Error opening keyfile: %s\n",strerror(errno));
> 
> 	bzero(kbuf, sizeof(kbuf));
> 	for (i = 0; (c = getc(kf)) != EOF && (i < BUFSIZ-1); i++) {
> 		if (raw == 0 && (c=='\n' || c=='\r')) break;
> 		kbuf[i] = c;
> 	}   /*  kbuf[BUFSIZ] = '\0'; */
> 
> 	if (ferror(kf) != 0)
> 		errx(errno, "Error reading keyfile: %s",strerror(errno));
> 	else if (strlen(kbuf) < 3)
> 		errx(1,"Too short passphrase from keyfile\n");
> 		
> 	(void)fclose(kf);
> 	return strdup(kbuf); /* XXX: No way to scrub buf before return? */
> }
> 
695c732,733
< 	const char *f_opt;
---
> 	const char *k_opt, *K_opt;
> 	const char *f_opt, *pbuf;
697c735
< 	int i_opt, n_opt, ch, dfd, doopen;
---
> 	int i_opt, n_opt, r_opt, ch, dfd, doopen;
716c754
< 		opts = "l:p:";
---
> 		opts = "l:p:k:r";
723c761
< 		opts = "f:iL:P:";
---
> 		opts = "f:iL:P:K:r";
727c765
< 		opts = "n:l:L:p:P:";
---
> 		opts = "n:l:L:p:k:P:K:r";
731c769
< 		opts = "l:p:";
---
> 		opts = "l:p:k:r";
735c773
< 		opts = "l:p:n:";
---
> 		opts = "n:l:p:k:r";
745a784
> 	pbuf  = NULL;
749a789,791
> 	k_opt = NULL;
> 	K_opt = NULL;
> 	r_opt = 0;
772a815,823
> 		case 'k':
> 			k_opt = optarg;
> 			break;
> 		case 'K':
> 			K_opt = optarg;
> 			break;
> 		case 'r':
> 			r_opt = 1;
> 			break;
782a834,836
> 	if (p_opt && k_opt) usage("Duplicate key spec: -p and -k\n");
> 	if (P_opt && K_opt) usage("Duplicate key spec: -P and -K\n");
> 
806c860,863
< 		setup_passphrase(&sc, 0, p_opt);
---
> 		if (k_opt)	pbuf = read_keyfile(k_opt, r_opt);
> 		else if (p_opt) pbuf = strdup(p_opt);
> 		setup_passphrase(&sc, 0, pbuf);
> 
814c871,875
< 		setup_passphrase(&sc, 1, P_opt);
---
> 
> 		if (K_opt)	pbuf = read_keyfile(K_opt, r_opt);
> 		else if (P_opt) pbuf = strdup(P_opt);
> 		setup_passphrase(&sc, 1, pbuf);
> 
818c879,882
< 		setup_passphrase(&sc, 0, p_opt);
---
> 		if (k_opt)	pbuf = read_keyfile(k_opt, r_opt);
> 		else if (p_opt) pbuf = strdup(p_opt);
> 		setup_passphrase(&sc, 0, pbuf);
> 
822c886,890
< 		setup_passphrase(&sc, 1, P_opt);
---
> 
> 		if (K_opt)	pbuf = read_keyfile(K_opt, r_opt);
> 		else if (P_opt) pbuf = strdup(P_opt);
> 		setup_passphrase(&sc, 1, pbuf);
> 
826c894,897
< 		setup_passphrase(&sc, 0, p_opt);
---
> 		if (k_opt)	pbuf = read_keyfile(k_opt, r_opt);
> 		else if (p_opt) pbuf = strdup(p_opt);
> 		setup_passphrase(&sc, 0, pbuf);
> 
833c904,907
< 		setup_passphrase(&sc, 0, p_opt);
---
> 		if (k_opt)	pbuf = read_keyfile(k_opt, r_opt);
> 		else if (p_opt) pbuf = strdup(p_opt);
> 		setup_passphrase(&sc, 0, pbuf);
> 
diff -r src-5_2/sbin/gbde/test.sh src-5_2-afields/sbin/gbde/test.sh
4a5
> GBDE=./gbde
8d8
< 
13,40c13,40
< ./gbde init $D -P foo -L /tmp/_l1
< ./gbde setkey $D -p foo -l /tmp/_l1 -P bar -L /tmp/_l1
< ./gbde setkey $D -p bar -l /tmp/_l1 -P foo -L /tmp/_l1
< 
< ./gbde setkey $D -p foo  -l /tmp/_l1 -n 2 -P foo2 -L /tmp/_l2
< ./gbde setkey $D -p foo2 -l /tmp/_l2 -n 3 -P foo3 -L /tmp/_l3
< ./gbde setkey $D -p foo3 -l /tmp/_l3 -n 4 -P foo4 -L /tmp/_l4
< ./gbde setkey $D -p foo4 -l /tmp/_l4 -n 1 -P foo1 -L /tmp/_l1
< 
< ./gbde nuke $D -p foo1 -l /tmp/_l1 -n 4
< if ./gbde nuke $D -p foo4 -l /tmp/_l4 -n 3 ; then false ; fi
< ./gbde destroy $D -p foo2 -l /tmp/_l2
< if ./gbde destroy $D -p foo2 -l /tmp/_l2 ; then false ; fi
< 
< ./gbde nuke $D -p foo1 -l /tmp/_l1 -n -1
< if ./gbde nuke $D -p foo1 -l /tmp/_l1 -n -1 ; then false ; fi
< if ./gbde nuke $D -p foo2 -l /tmp/_l2 -n -1 ; then false ; fi
< if ./gbde nuke $D -p foo3 -l /tmp/_l3 -n -1 ; then false ; fi
< if ./gbde nuke $D -p foo4 -l /tmp/_l4 -n -1 ; then false ; fi
< 
< ./gbde init $D -P foo 
< ./gbde setkey $D -p foo -P bar
< ./gbde setkey $D -p bar -P foo
< 
< ./gbde setkey $D -p foo  -n 2 -P foo2
< ./gbde setkey $D -p foo2 -n 3 -P foo3
< ./gbde setkey $D -p foo3 -n 4 -P foo4
< ./gbde setkey $D -p foo4 -n 1 -P foo1
---
> ${GBDE} init $D -P foo -L /tmp/_l1
> ${GBDE} setkey $D -p foo -l /tmp/_l1 -P bar -L /tmp/_l1
> ${GBDE} setkey $D -p bar -l /tmp/_l1 -P foo -L /tmp/_l1
> 
> ${GBDE} setkey $D -p foo  -l /tmp/_l1 -n 2 -P foo2 -L /tmp/_l2
> ${GBDE} setkey $D -p foo2 -l /tmp/_l2 -n 3 -P foo3 -L /tmp/_l3
> ${GBDE} setkey $D -p foo3 -l /tmp/_l3 -n 4 -P foo4 -L /tmp/_l4
> ${GBDE} setkey $D -p foo4 -l /tmp/_l4 -n 1 -P foo1 -L /tmp/_l1
> 
> ${GBDE} nuke $D -p foo1 -l /tmp/_l1 -n 4
> if ${GBDE} nuke $D -p foo4 -l /tmp/_l4 -n 3 ; then false ; fi
> ${GBDE} destroy $D -p foo2 -l /tmp/_l2
> if ${GBDE} destroy $D -p foo2 -l /tmp/_l2 ; then false ; fi
> 
> ${GBDE} nuke $D -p foo1 -l /tmp/_l1 -n -1
> if ${GBDE} nuke $D -p foo1 -l /tmp/_l1 -n -1 ; then false ; fi
> if ${GBDE} nuke $D -p foo2 -l /tmp/_l2 -n -1 ; then false ; fi
> if ${GBDE} nuke $D -p foo3 -l /tmp/_l3 -n -1 ; then false ; fi
> if ${GBDE} nuke $D -p foo4 -l /tmp/_l4 -n -1 ; then false ; fi
> 
> ${GBDE} init $D -P foo 
> ${GBDE} setkey $D -p foo -P bar
> ${GBDE} setkey $D -p bar -P foo
> 
> ${GBDE} setkey $D -p foo  -n 2 -P foo2
> ${GBDE} setkey $D -p foo2 -n 3 -P foo3
> ${GBDE} setkey $D -p foo3 -n 4 -P foo4
> ${GBDE} setkey $D -p foo4 -n 1 -P foo1
50c50
< gbde attach $D -p foo
---
> ${GBDE} attach $D -p foo
52c52
< gbde detach $D
---
> ${GBDE} detach $D
-------------- next part --------------
Script started on Wed Jan 21 07:31:38 2004
You have mail.
bsddev#	make
Warning: Object directory not changed from original /usr/src-5_2-afields/sbin/gbde
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c gbde.c
file2c 'const char template[] = {' ',0};'  < /usr/src-5_2-afields/sbin/gbde/template.txt > template.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c template.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c /usr/src-5_2-afields/sbin/gbde/../../sys/crypto/rijndael/rijndael-alg-fst.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c /usr/src-5_2-afields/sbin/gbde/../../sys/crypto/rijndael/rijndael-api-fst.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c /usr/src-5_2-afields/sbin/gbde/../../sys/crypto/sha2/sha2.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align  -c /usr/src-5_2-afields/sbin/gbde/../../sys/geom/bde/g_bde_lock.c
cc -O -pipe -mcpu=pentiumpro -I/usr/src-5_2-afields/sbin/gbde/../../sys -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align   -o gbde gbde.o template.o rijndael-alg-fst.o rijndael-api-fst.o sha2.o g_bde_lock.o -lmd -lutil -lgeom
gzip -cn gbde.8 > gbde.8.gz
bsddev#	make test
sh /usr/src-5_2-afields/sbin/gbde/test.sh /usr/src-5_2-afields/sbin/gbde
Wrote key 0 at 49152
Opened with key 0
Wrote key 0 at 49152
Opened with key 0
Wrote key 0 at 49152
Opened with key 0
Wrote key 1 at 538624
Opened with key 1
Wrote key 2 at 748032
Opened with key 2
Wrote key 3 at 755712
Opened with key 3
Wrote key 0 at 49152
Opened with key 0
Nuked key 3
gbde: Lock was nuked.
Opened with key 1
Wrote key 1 at 538624
gbde: Lock was destroyed.
Opened with key 0
Nuked key 0
Nuked key 1
Nuked key 2
Nuked key 3
gbde: Lock was nuked.
gbde: Lock was nuked.
gbde: Lock was nuked.
gbde: Lock was nuked.
Wrote key 0 at 120832
Opened with key 0
Wrote key 0 at 120832
Opened with key 0
Wrote key 0 at 120832
Opened with key 0
Wrote key 1 at 240640
Opened with key 1
Wrote key 2 at 325120
Opened with key 2
Wrote key 3 at 371200
Opened with key 3
Wrote key 0 at 120832
** /dev/md99.bde
** Last Mounted on 
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
1 files, 1 used, 398 free (14 frags, 48 blocks, 3.5% fragmentation)
***********
Test passed
***********
bsddev#	ls
CVS			gbde.c			sha2.o
Makefile		gbde.o			template.c
g_bde_lock.o		image.uu		template.o
gbde			rijndael-alg-fst.o	template.txt
gbde.8			rijndael-api-fst.o	test.sh
gbde.8.gz		sbin-gbde.log
bsddev#	^D
exit

Script done on Wed Jan 21 07:32:09 2004
-------------- next part --------------
Script started on Wed Jan 21 08:44:57 2004
You have mail.
bsddev#	bash
bash-2.05# ls /dev/md*
/dev/md0	/dev/mdctl
bash-2.05# echo "obscure enough?"|bdes -b>/mnt/cf/test.key  # if not:
Enter key: 
bash-2.05# dd if=/dev/urandom bs=1k count=4 |bdes -b>/mnt/cf/md.key
4+0 records in
4+0 records out
Enter key: 4096 bytes transferred in 0.012768 secs (320801 bytes/sec)

bash-2.05# bdes -b</mnt/cf/md.key|./gbde init /dev/md0 -L/mnt/cf/md.lock -K-

Enter key: 
Wrote key 0 at 182681
bash-2.05# bdes -b</mnt/cf/md.key|./gbde attach /dev/md0 -l/mnt/cf/md.lock -k-

Enter key: 
bash-2.05# ls /dev/md*
/dev/md0	/dev/md0.bde	/dev/mdctl
bash-2.05# newfs /dev/md0.bde
/dev/md0.bde: 7.8MB (15872 sectors) block size 16384, fragment size 2048
	using 4 cylinder groups of 1.95MB, 125 blks, 256 inodes.
super-block backups (for fsck -b #) at:
 160, 4160, 8160, 12160
bash-2.05# mkdir /mnt/tmp
bash-2.05# mount /dev/md0.bde /mnt/tmp
bash-2.05# ls /mnt/tmp
.snap
bash-2.05# mkdir /mnt/tmp/TEST
bash-2.05# ls /mnt/tmp
.snap	TEST
bash-2.05# umount /mnt/tmp
bash-2.05# ./gbde detach md0
bash-2.05# bdes -b</mnt/cf/md.key|./gbde attach /dev/md0 -l /mnt/cf/md.lock -k-

Enter key:
bash-2.05# mount /dev/md0.bde /mnt/tmp
bash-2.05# ls /mnt/tmp
.snap	TEST
bash-2.05# umount /mnt/tmp
bash-2.05# ./gbde detach md0
Script done on Wed Jan 21 09:14:34 2004
-------------- next part --------------
Script started on Wed Jan 21 07:34:07 2004
You have mail.
bsddev#	bash
bash-2.05# dd if=/dev/zero of=/tmp/test.img bs=1m count=8
8+0 records in
8+0 records out
8388608 bytes transferred in 1.494038 secs (5614722 bytes/sec)
bash-2.05# mdconfig -af /tmp/test.img
md0
bash-2.05# cat >/tmp/test.key
not a safe key file, this is a test
^D
bash-2.05# ./gbde init /dev/md0 -K/tmp/test.key
Wrote key 0 at 2314752
bash-2.05# cat /tmp/test.key|./gbde attach /dev/md0 -k-
bash-2.05# ls /dev/md*
/dev/md0	/dev/md0.bde	/dev/mdctl
bash-2.05# newfs /dev/md0.bde
/dev/md0.bde: 7.8MB (15872 sectors) block size 16384, fragment size 2048
	using 4 cylinder groups of 1.95MB, 125 blks, 256 inodes.
super-block backups (for fsck -b #) at:
 160, 4160, 8160, 12160
bash-2.05# fsck_ffs /dev/md0.bde
** /dev/md0.bde
** Last Mounted on 
** Phase 1 - Check Blocks and Sizes
** Phase 2 - Check Pathnames
** Phase 3 - Check Connectivity
** Phase 4 - Check Reference Counts
** Phase 5 - Check Cyl groups
2 files, 2 used, 3733 free (21 frags, 464 blocks, 0.6% fragmentation)
bash-2.05# mkdir tmpmnt
bash-2.05# mount /dev/md0.bde tmpmnt
bash-2.05# cd tmpmnt
bash-2.05# mkdir TEST
bash-2.05# cat >bla
bla bla lba
yadda yadda so on and so on
^D
bash-2.05# ls -l
total 6
drwxrwxr-x  2 root  operator  512 Jan 21 07:37 .snap
drwxr-xr-x  2 root  wheel     512 Jan 21 07:38 TEST
-rw-r--r--  1 root  wheel      40 Jan 21 07:38 bla
bash-2.05# cd ..
bash-2.05# umount tmpmnt
bash-2.05# ./gbde detach /dev/md0
bash-2.05# ./gbde attach /dev/md0
Enter passphrase: 
bash-2.05# ls /dev/md*
/dev/md0	/dev/md0.bde	/dev/mdctl
bash-2.05# mount /dev/md0.bde tmpmnt
bash-2.05# ls tmpmnt
.snap	TEST	bla
bash-2.05# umount tmpmnt
bash-2.05# ./gbde detach /dev/md0
bash-2.05# ./gbde attach -p"not a safe file" -k/tmp/test.key
Usage error: Duplicate key spec: -p and -k
Usage:
	gbde attach dest [-l lockfile]
	gbde detach dest
	gbde init /dev/dest [-i] [-f filename] [-L lockfile]
	gbde setkey dest [-n key] [-l lockfile] [-L lockfile]
	gbde destroy dest [-n key] [-l lockfile] [-L lockfile]
Key entry:
	By default the user is prompted on the tty.  On the command line:
	-p/-P <passphrase>		-k/-K <keyfile>
	-k-/-K- for input on stdin	-r toggles raw mode
bash-2.05# ./gbde attach /dev/md0 -p"not a safe key file, this is a test"
bash-2.05# ls /dev/md*
/dev/md0	/dev/md0.bde	/dev/mdctl
bash-2.05# mount /dev/md0.bde tmpmnt
bash-2.05# cat tmpmnt/bla
bla bla lba
yadda yadda so on and so on
bash-2.05# umount tmpmnt
bsddev#	^D
exit
Script done on Wed Jan 21 07:44:19 2004
---


More information about the freebsd-hackers mailing list