diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2009-12-31 14:00:46 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2009-12-31 14:00:46 +0000 |
commit | 6c48a0797c3ce6da990d15cfd72f07f067df8e92 (patch) | |
tree | 9a9a5dbe741b0f8687bbcd65c0491e04aef8c4ee /sbin/bioctl/bioctl.c | |
parent | de50ae56c1a30c7995a9b681464dbd29776af065 (diff) |
Add support for key disks. This allows a crypto volume to be constructed
without using a passphrase - instead the encryption mask key is stored on
the specified key disk partition (ideally being one on a removable device).
This also enables automatic assembly of crypto volumes at boot time.
ok marco@
Diffstat (limited to 'sbin/bioctl/bioctl.c')
-rw-r--r-- | sbin/bioctl/bioctl.c | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c index 83eb44bc925..607969ce9ec 100644 --- a/sbin/bioctl/bioctl.c +++ b/sbin/bioctl/bioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.c,v 1.87 2009/12/24 10:06:35 sobrado Exp $ */ +/* $OpenBSD: bioctl.c,v 1.88 2009/12/31 14:00:45 jsing Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom @@ -76,7 +76,7 @@ int bio_getvolbyname(char *); void bio_setstate(char *, int, char *); void bio_setblink(char *, char *, int); void bio_blink(char *, int, int); -void bio_createraid(u_int16_t, char *); +void bio_createraid(u_int16_t, char *, char *); void bio_deleteraid(char *); void bio_changepass(char *); u_int32_t bio_createflags(char *); @@ -101,6 +101,7 @@ main(int argc, char *argv[]) char *bioc_dev = NULL, *sd_dev = NULL; char *realname = NULL, *al_arg = NULL; char *bl_arg = NULL, *dev_list = NULL; + char *key_disk = NULL; const char *errstr; int ch, rv, blink = 0, changepass = 0, diskinq = 0; int ss_func = 0; @@ -109,7 +110,7 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - while ((ch = getopt(argc, argv, "a:b:C:c:dH:hil:Pp:qr:R:vu:")) != + while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:Pp:qr:R:vu:")) != -1) { switch (ch) { case 'a': /* alarm */ @@ -151,6 +152,9 @@ main(int argc, char *argv[]) case 'i': /* inquiry */ func |= BIOC_INQ; break; + case 'k': /* Key disk. */ + key_disk = optarg; + break; case 'l': /* device list */ func |= BIOC_DEVLIST; dev_list = optarg; @@ -239,7 +243,7 @@ main(int argc, char *argv[]) errx(1, "need -l parameter"); if (sd_dev) errx(1, "can't use sd device"); - bio_createraid(cr_level, dev_list); + bio_createraid(cr_level, dev_list, key_disk); } return (0); @@ -258,7 +262,7 @@ usage(void) "\t[-u channel:target[.lun]] " "device\n" " %s [-dhiPqv] " - "[-C flag[,flag,...]] [-c raidlevel]\n" + "[-C flag[,flag,...]] [-c raidlevel] [-k special]\n" "\t[-l special[,special,...]] [-p passfile]\n" "\t[-R device | channel:target[.lun] [-r rounds] " "device\n", __progname, __progname); @@ -446,7 +450,9 @@ bio_inq(char *name) snprintf(volname, sizeof volname, " %3u", bd.bd_diskid); - if (human) + if (bv.bv_level == 'C' && bd.bd_size == 0) + snprintf(size, sizeof size, "%14s", "key disk"); + else if (human) fmt_scaled(bd.bd_size, size); else snprintf(size, sizeof size, "%14llu", @@ -689,13 +695,14 @@ bio_blink(char *enclosure, int target, int blinktype) } void -bio_createraid(u_int16_t level, char *dev_list) +bio_createraid(u_int16_t level, char *dev_list, char *key_disk) { struct bioc_createraid create; struct sr_crypto_kdfinfo kdfinfo; struct sr_crypto_kdf_pbkdf2 kdfhint; - int rv, no_dev; - dev_t *dt; + struct stat sb; + int rv, no_dev, i; + dev_t *dt, kd = NODEV; u_int16_t min_disks = 0; if (!dev_list) @@ -742,11 +749,15 @@ bio_createraid(u_int16_t level, char *dev_list) create.bc_dev_list_len = no_dev * sizeof(dev_t); create.bc_dev_list = dt; create.bc_flags = BIOC_SCDEVT | cflags; + create.bc_key_disk = NODEV; + + if (level == 'C' && key_disk == NULL) { - if (level == 'C') { memset(&kdfinfo, 0, sizeof(kdfinfo)); memset(&kdfhint, 0, sizeof(kdfhint)); + create.bc_flags |= BIOC_SCNOAUTOASSEMBLE; + create.bc_opaque = &kdfhint; create.bc_opaque_size = sizeof(kdfhint); create.bc_opaque_flags = BIOC_SOOUT; @@ -760,13 +771,29 @@ bio_createraid(u_int16_t level, char *dev_list) memset(&kdfhint, 0, sizeof(kdfhint)); } else { bio_kdf_generate(&kdfinfo); - /* no auto assembling */ - create.bc_flags |= BIOC_SCNOAUTOASSEMBLE; } create.bc_opaque = &kdfinfo; create.bc_opaque_size = sizeof(kdfinfo); create.bc_opaque_flags = BIOC_SOIN; + + } else if (level == 'C' && key_disk != NULL) { + + if (stat(key_disk, &sb) == -1) + err(1, "could not stat %s", key_disk); + create.bc_key_disk = sb.st_rdev; + + memset(&kdfinfo, 0, sizeof(kdfinfo)); + + kdfinfo.genkdf.len = sizeof(kdfinfo.genkdf); + kdfinfo.genkdf.type = SR_CRYPTOKDFT_KEYDISK; + kdfinfo.len = sizeof(kdfinfo); + kdfinfo.flags = SR_CRYPTOKDF_HINT; + + create.bc_opaque = &kdfinfo; + create.bc_opaque_size = sizeof(kdfinfo); + create.bc_opaque_flags = BIOC_SOIN; + } rv = ioctl(devh, BIOCCREATERAID, &create); @@ -815,7 +842,7 @@ bio_kdf_generate(struct sr_crypto_kdfinfo *kdfinfo) kdfinfo->pbkdf2.type = SR_CRYPTOKDFT_PBKDF2; kdfinfo->pbkdf2.rounds = rflag; kdfinfo->len = sizeof(*kdfinfo); - kdfinfo->flags = (SR_CRYPTOKDF_KEY | SR_CRYPTOKDF_HINT); + kdfinfo->flags = SR_CRYPTOKDF_KEY | SR_CRYPTOKDF_HINT; /* generate salt */ arc4random_buf(kdfinfo->pbkdf2.salt, sizeof(kdfinfo->pbkdf2.salt)); |