summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2008-06-12 18:13:28 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2008-06-12 18:13:28 +0000
commit71f6bf6d70d8513918b8a08ae9afbd10e1f8ab9b (patch)
tree0779e45bbf8c87531e66af71f79409105d6fc42c /sys/dev
parentb708509aedc6e50723e1d8a500ccbbc9c6fa6db6 (diff)
Get mask keying for on-disk keys from user space and keep a "hint" for key
generation used by user space in the meta data. Actually use the masking key for encryption and decryption of on-disk key at run time. ok djm marco
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/softraid.c38
-rw-r--r--sys/dev/softraid_crypto.c74
-rw-r--r--sys/dev/softraidvar.h26
3 files changed, 110 insertions, 28 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index 3ea83e31c57..6015ffe3fc0 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.109 2008/06/12 01:26:16 marco Exp $ */
+/* $OpenBSD: softraid.c,v 1.110 2008/06/12 18:13:27 hshoexer Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -821,10 +821,6 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
#if 0
#ifdef CRYPTO
case 'C':
- /*
- * XXX we need the masking keys and salt here,
- * provided by bioctl.
- */
DNPRINTF(SR_D_IOCTL,
"%s: sr_ioctl_createraid: no_chunk %d\n",
DEVNAME(sc), no_chunk);
@@ -832,11 +828,17 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
if (no_chunk != 1)
goto unwind;
+ if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE))
+ goto unwind;
+
+ if (sr_crypto_get_kdf(bc, sd))
+ goto unwind;
+
strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name));
vol_size = ch_entry->src_meta.scm_size;
- /* create crypto keys and encrypt them */
sr_crypto_create_keys(sd);
+
break;
#endif /* CRYPTO */
#endif
@@ -870,6 +872,28 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
"metadata\n", DEVNAME(sc));
goto unwind;
}
+#ifdef CRYPTO
+ /* provide userland with kdf hint */
+ if (bc->bc_opaque_flags & BIOC_SOOUT) {
+ if (bc->bc_opaque == NULL)
+ goto unwind;
+
+ if (sr_read_meta(sd) == 0)
+ goto unwind;
+
+ if (sizeof(sd->mds.mdd_crypto.scr_meta.scm_kdfhint) <
+ bc->bc_opaque_size)
+ goto unwind;
+
+ if (copyout(sd->mds.mdd_crypto.scr_meta.scm_kdfhint,
+ bc->bc_opaque, bc->bc_opaque_size))
+ goto unwind;
+
+ /* we're done */
+ rv = 0;
+ goto unwind;
+ }
+#endif /* CRYPTO */
if (sr_already_assembled(sd)) {
printf("%s: disk ", DEVNAME(sc));
sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
@@ -1279,7 +1303,7 @@ sr_read_meta(struct sr_discipline *sd)
/* XXX fix this check, sd_type isnt filled in yet */
if (mv->svm_level == 'C') {
mo = (struct sr_opt_meta *)(mc + mv->svm_no_chunk);
- if (m->ssd_chunk_id > 2) {
+ if (m->ssd_chunk_id > 1) {
no_chunk = -1;
goto bad;
}
diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c
index 09215ba2f45..26942181717 100644
--- a/sys/dev/softraid_crypto.c
+++ b/sys/dev/softraid_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_crypto.c,v 1.19 2008/06/11 00:26:18 hshoexer Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.20 2008/06/12 18:13:27 hshoexer Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
@@ -51,6 +51,8 @@
struct cryptop *sr_crypto_getcryptop(struct sr_workunit *, int);
int sr_crypto_create_keys(struct sr_discipline *);
void *sr_crypto_putcryptop(struct cryptop *);
+int sr_crypto_get_kdf(struct bioc_createraid *,
+ struct sr_discipline *);
int sr_crypto_decrypt_key(struct sr_discipline *);
int sr_crypto_alloc_resources(struct sr_discipline *);
int sr_crypto_free_resources(struct sr_discipline *);
@@ -161,6 +163,48 @@ sr_crypto_putcryptop(struct cryptop *crp)
}
int
+sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd)
+{
+ struct sr_crypto_kdfinfo *kdfinfo;
+ int rv = EINVAL;
+
+ if (!(bc->bc_opaque_flags & BIOC_SOIN))
+ return (rv);
+ if (bc->bc_opaque == NULL)
+ return (rv);
+ if (bc->bc_opaque_size < sizeof(*kdfinfo))
+ return (rv);
+
+ kdfinfo = malloc(bc->bc_opaque_size, M_DEVBUF, M_WAITOK | M_ZERO);
+ if (copyin(bc->bc_opaque, kdfinfo, bc->bc_opaque_size))
+ goto out;
+
+ if (kdfinfo->len != bc->bc_opaque_size)
+ goto out;
+ if (!(kdfinfo->flags & SR_CRYPTOKDF_KEY) ||
+ !(kdfinfo->flags & SR_CRYPTOKDF_HINT))
+ goto out;
+
+ /* copy KDF hint to disk meta data */
+ if (sizeof(sd->mds.mdd_crypto.scr_meta.scm_kdfhint) <
+ kdfinfo->kdfhint.len)
+ goto out;
+ bcopy(&kdfinfo->kdfhint, sd->mds.mdd_crypto.scr_meta.scm_kdfhint,
+ kdfinfo->kdfhint.len);
+
+ /* copy mask key to run-time meta data */
+ bcopy(&kdfinfo->maskkey, sd->mds.mdd_crypto.scr_maskkey,
+ sizeof(kdfinfo->maskkey));
+
+ rv = 0;
+out:
+ bzero(kdfinfo, bc->bc_opaque_size);
+ free(kdfinfo, M_DEVBUF);
+
+ return (rv);
+}
+
+int
sr_crypto_decrypt_key(struct sr_discipline *sd)
{
rijndael_ctx ctx;
@@ -170,11 +214,13 @@ sr_crypto_decrypt_key(struct sr_discipline *sd)
DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc));
- if (rijndael_set_key(&ctx, sd->mds.mdd_crypto.scr_meta.scm_kdfhint,
- 128) != 0) {
+ if (rijndael_set_key(&ctx, sd->mds.mdd_crypto.scr_maskkey, 128) != 0) {
bzero(&ctx, sizeof(ctx));
return (1);
}
+ /* we don't need the mask key anymore */
+ bzero(&sd->mds.mdd_crypto.scr_maskkey,
+ sizeof(sd->mds.mdd_crypto.scr_maskkey));
c = (u_char *)sd->mds.mdd_crypto.scr_meta.scm_key;
p = (u_char *)sd->mds.mdd_crypto.scr_key;
@@ -187,13 +233,6 @@ sr_crypto_decrypt_key(struct sr_discipline *sd)
#ifdef SR_DEBUG0
sr_crypto_dumpkeys(sd);
#endif
-
- /*
- * XXX de-mask keys instead of bcopy
- */
- bcopy(sd->mds.mdd_crypto.scr_meta.scm_key, sd->mds.mdd_crypto.scr_key,
- sizeof(sd->mds.mdd_crypto.scr_meta.scm_key));
-
return (0);
}
@@ -201,7 +240,6 @@ int
sr_crypto_create_keys(struct sr_discipline *sd)
{
rijndael_ctx ctx;
- u_int8_t kdfhint[SR_CRYPTO_KDFHINTBYTES]; /* XXX fake */
u_char *p, *c;
size_t ksz;
int i;
@@ -209,11 +247,8 @@ sr_crypto_create_keys(struct sr_discipline *sd)
DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n",
DEVNAME(sd->sd_sc));
- /* XXX fake for now */
- memset(kdfhint, 0xdeadbeef, sizeof(kdfhint));
-
- bcopy(kdfhint, sd->mds.mdd_crypto.scr_meta.scm_kdfhint,
- sizeof(sd->mds.mdd_crypto.scr_meta.scm_kdfhint));
+ if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey))
+ return (1);
/* generate crypto keys */
arc4random_buf(sd->mds.mdd_crypto.scr_key,
@@ -222,7 +257,8 @@ sr_crypto_create_keys(struct sr_discipline *sd)
/* XXX 128 for now */
sd->mds.mdd_crypto.scr_meta.scm_alg = SR_CRYPTOA_AES_XTS_128;
- if (rijndael_set_key_enc_only(&ctx, kdfhint, 128) != 0) {
+ if (rijndael_set_key_enc_only(&ctx, sd->mds.mdd_crypto.scr_maskkey,
+ 128) != 0) {
bzero(sd->mds.mdd_crypto.scr_key,
sizeof(sd->mds.mdd_crypto.scr_key));
bzero(&ctx, sizeof(ctx));
@@ -331,8 +367,8 @@ sr_crypto_rw(struct sr_workunit *wu)
int
sr_crypto_write(struct cryptop *crp)
{
- int s;
-struct sr_workunit *wu = crp->crp_opaque;
+ int s;
+ struct sr_workunit *wu = crp->crp_opaque;
DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %x xs: %x\n",
DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs);
diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h
index 93de4e4b6b2..9526a9c2da7 100644
--- a/sys/dev/softraidvar.h
+++ b/sys/dev/softraidvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraidvar.h,v 1.51 2008/06/12 00:19:15 marco Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.52 2008/06/12 18:13:27 hshoexer Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -29,6 +29,8 @@
#include <scsi/scsi_disk.h>
#include <scsi/scsiconf.h>
+#include <crypto/rijndael.h>
+
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
/* #define SR_DEBUG */
@@ -138,7 +140,24 @@ struct sr_raid1 {
#define SR_CRYPTO_MAXKEYS 32
#define SR_CRYPTO_KEYBITS 512 /* AES-XTS with 2 * 256 bit keys */
#define SR_CRYPTO_KEYBYTES (SR_CRYPTO_KEYBITS >> 3)
-#define SR_CRYPTO_KDFHINTBYTES 64
+#define SR_CRYPTO_KDFHINTBYTES 256
+
+struct sr_crypto_genkdf {
+ u_int32_t len;
+ u_int32_t type;
+#define SR_CRYPTOKDFT_INVALID (0)
+#define SR_CRYPTOKDFT_PBKDF2 (1<<0)
+};
+
+struct sr_crypto_kdfinfo {
+ u_int32_t len;
+ u_int32_t flags;
+#define SR_CRYPTOKDF_INVALID (0)
+#define SR_CRYPTOKDF_KEY (1<<0)
+#define SR_CRYPTOKDF_HINT (1<<1)
+ u_int8_t maskkey[AES_MAXKEYBYTES];
+ struct sr_crypto_genkdf kdfhint;
+};
struct sr_crypto_metadata {
u_int32_t scm_alg;
@@ -158,6 +177,7 @@ struct sr_crypto {
struct sr_crypto_metadata scr_meta;
u_int8_t scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES];
+ u_int8_t scr_maskkey[AES_MAXKEYBYTES];
u_int64_t scr_sid/*[SR_CRYPTO_MAXKEYS]*/;
};
@@ -424,6 +444,8 @@ void sr_raid1_set_vol_state(struct sr_discipline *);
int sr_crypto_alloc_resources(struct sr_discipline *);
int sr_crypto_free_resources(struct sr_discipline *);
int sr_crypto_rw(struct sr_workunit *);
+int sr_crypto_get_kdf(struct bioc_createraid *,
+ struct sr_discipline *);
int sr_crypto_create_keys(struct sr_discipline *);
#ifdef SR_DEBUG