diff options
author | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2008-06-12 18:13:28 +0000 |
---|---|---|
committer | Hans-Joerg Hoexer <hshoexer@cvs.openbsd.org> | 2008-06-12 18:13:28 +0000 |
commit | 71f6bf6d70d8513918b8a08ae9afbd10e1f8ab9b (patch) | |
tree | 0779e45bbf8c87531e66af71f79409105d6fc42c /sys/dev | |
parent | b708509aedc6e50723e1d8a500ccbbc9c6fa6db6 (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.c | 38 | ||||
-rw-r--r-- | sys/dev/softraid_crypto.c | 74 | ||||
-rw-r--r-- | sys/dev/softraidvar.h | 26 |
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 |