summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2008-02-07 15:08:50 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2008-02-07 15:08:50 +0000
commit6b3f36a8d54742b75994faffc0399f5a367d8d63 (patch)
tree9065f6dff13d6234951e82079ff4a8829397710a
parentfade589199b3a9aabf48bb6277411f0a64f605ac (diff)
Add optional metadata memebers.
Randomize Crypto password and add salt array. Add mock key encryption functions.
-rw-r--r--sys/dev/softraid.c109
-rw-r--r--sys/dev/softraid_crypto.c45
-rw-r--r--sys/dev/softraidvar.h36
3 files changed, 166 insertions, 24 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index 5616185c256..cf11d846605 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.101 2008/02/05 16:49:25 marco Exp $ */
+/* $OpenBSD: softraid.c,v 1.102 2008/02/07 15:08:49 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
*
@@ -716,6 +716,9 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
int i, s, no_chunk, rv = EINVAL, vol;
int no_meta, updatemeta = 0;
u_int64_t vol_size;
+#if 0
+ u_int32_t *pk, sz;
+#endif
int32_t strip_size = 0;
struct sr_chunk_head *cl;
struct sr_discipline *sd = NULL;
@@ -808,10 +811,35 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
break;
#if 0
case 'C':
- if (no_chunk < 2)
+ if (no_chunk < 1 || no_chunk > 2)
goto unwind;
strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name));
vol_size = ch_entry->src_meta.scm_coerced_size;
+
+ /* generate crypto key */
+ sz = sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_key) / 4;
+ pk = (u_int32_t *)
+ sd->mds.mdd_crypto.scr_meta[0].scm_key;
+ for (i = 0; i < sz; i++)
+ *pk++ = arc4random();
+
+ /* generate salt */
+ sz = sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_salt) /4;
+ pk = (u_int32_t *)
+ sd->mds.mdd_crypto.scr_meta[0].scm_salt;
+ for (i = 0; i < sz; i++)
+ *pk++ = arc4random();
+
+ sd->mds.mdd_crypto.scr_meta[0].scm_flags =
+ SR_CRYPTOF_KEY | SR_CRYPTOF_SALT;
+
+ strlcpy(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase,
+ "my super secret passphrase ZOMGPASSWD",
+ sizeof(sd->mds.mdd_crypto.scr_meta[1].scm_passphrase));
+ sd->mds.mdd_crypto.scr_meta[1].scm_flags =
+ SR_CRYPTOF_PASSPHRASE;
+
+ sr_crypto_encrypt_key(sd);
break;
#endif
default:
@@ -1103,6 +1131,7 @@ sr_read_meta(struct sr_discipline *sd)
struct buf b;
struct sr_vol_meta *mv;
struct sr_chunk_meta *mc;
+ struct sr_opt_meta *mo;
size_t sz = SR_META_SIZE * 512;
int no_chunk = 0;
u_int32_t volid, ondisk = 0, cid;
@@ -1217,6 +1246,19 @@ sr_read_meta(struct sr_discipline *sd)
no_chunk = -1;
goto bad;
}
+
+ /* 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) {
+ no_chunk = -1;
+ goto bad;
+ }
+ bcopy(&mo->som_meta,
+ &sd->mds.mdd_crypto.scr_meta[m->ssd_chunk_id],
+ sizeof(sd->mds.mdd_crypto.scr_meta[m->ssd_chunk_id])
+ );
+ }
}
if (no_chunk != m->ssd_chunk_no) {
@@ -1677,10 +1719,11 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
struct sr_metadata *sm = sd->sd_meta;
struct sr_vol_meta *sv = &sd->sd_vol.sv_meta, *im_sv;
struct sr_chunk_meta *im_sc;
+ struct sr_opt_meta *im_so;
struct sr_chunk *src;
struct buf b;
struct sr_workunit wu;
- int i, rv = 1, ch = 0;
+ int i, rv = 1, ch = 0, no_chunk, sz_opt;
size_t sz = SR_META_SIZE * 512;
DNPRINTF(SR_D_META, "%s: sr_save_metadata %s\n",
@@ -1693,10 +1736,18 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
im_sv = (struct sr_vol_meta *)(sm + 1);
im_sc = (struct sr_chunk_meta *)(im_sv + 1);
+ no_chunk = sd->sd_vol.sv_meta.svm_no_chunk;
+ im_so = (struct sr_opt_meta *)(im_sc + no_chunk);
+
+ /* XXX this is a temporary hack until meta is properly redone */
+ if (sd->sd_type == SR_MD_CRYPTO)
+ sz_opt = sizeof(struct sr_opt_meta);
+ else
+ sz_opt = 0;
if (sizeof(struct sr_metadata) + sizeof(struct sr_vol_meta) +
- (sizeof(struct sr_chunk_meta) * sd->sd_vol.sv_meta.svm_no_chunk) >
- sz) {
+ (sizeof(struct sr_chunk_meta) * no_chunk) +
+ sz_opt > sz) {
printf("%s: too much metadata; metadata NOT written\n",
DEVNAME(sc));
goto bad;
@@ -1722,18 +1773,24 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
sm->ssd_vd_size = sizeof(struct sr_vol_meta);
/* chunk */
- for (i = 0; i < sd->sd_vol.sv_meta.svm_no_chunk; i++)
+ for (i = 0; i < no_chunk; i++)
bcopy(sd->sd_vol.sv_chunks[i], &im_sc[i],
sizeof(struct sr_chunk_meta));
sm->ssd_chunk_ver = SR_CHUNK_VERSION;
sm->ssd_chunk_size = sizeof(struct sr_chunk_meta);
- sm->ssd_chunk_no = sd->sd_vol.sv_meta.svm_no_chunk;
+ sm->ssd_chunk_no = no_chunk;
/* optional */
sm->ssd_opt_ver = SR_OPT_VERSION;
- sm->ssd_opt_size = 0; /* unused */
- sm->ssd_opt_no = 0; /* unused */
+ if (sd->sd_type == SR_MD_CRYPTO) {
+ bzero(im_so, sizeof(*im_so));
+ sm->ssd_opt_size = sizeof(struct sr_opt_meta);
+ sm->ssd_opt_no = 1;
+ } else {
+ sm->ssd_opt_size = 0;
+ sm->ssd_opt_no = 0;
+ }
}
/* from here on out metadata is updated */
@@ -1747,6 +1804,8 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
sm->ssd_chunk_chk ^= sr_checksum(DEVNAME(sc),
(u_int32_t *)&im_sc[ch], sm->ssd_chunk_size);
+ /* XXX do checksum on optional meta too */
+
sr_print_metadata(sm);
for (i = 0; i < sm->ssd_chunk_no; i++) {
@@ -1758,11 +1817,20 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
if (src->src_meta.scm_status == BIOC_SDOFFLINE)
continue;
+ /* copy encrypted key / passphrase into optinal metadata area */
+ if (sd->sd_type == SR_MD_CRYPTO && i < 2) {
+ im_so->som_type = SR_OPT_CRYPTO;
+ bcopy(&sd->mds.mdd_crypto.scr_meta[i],
+ &im_so->som_meta.smm_crypto,
+ sizeof(im_so->som_meta.smm_crypto));
+ }
+
/* calculate metdata checksum and ids */
sm->ssd_vd_volid = im_sv->svm_volid;
sm->ssd_chunk_id = i;
sm->ssd_checksum = sr_checksum(DEVNAME(sc),
(u_int32_t *)sm, sm->ssd_size);
+
DNPRINTF(SR_D_META, "%s: sr_save_metadata %s: volid: %d "
"chunkid: %d checksum: 0x%x\n",
DEVNAME(sc), src->src_meta.scm_devname,
@@ -1782,9 +1850,12 @@ sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
b.b_iodone = NULL;
LIST_INIT(&b.b_dep);
bdevsw_lookup(b.b_dev)->d_strategy(&b);
+
biowait(&b);
/* make sure in memory copy is clean */
+ if (sd->sd_type == SR_MD_CRYPTO)
+ bzero(im_so, sizeof(*im_so));
sm->ssd_vd_volid = 0;
sm->ssd_chunk_id = 0;
sm->ssd_checksum = 0;
@@ -2388,6 +2459,7 @@ sr_print_metadata(struct sr_metadata *sm)
{
struct sr_vol_meta *im_sv;
struct sr_chunk_meta *im_sc;
+ struct sr_opt_meta *im_so;
int ch;
if (!(sr_debug & SR_D_META))
@@ -2395,6 +2467,7 @@ sr_print_metadata(struct sr_metadata *sm)
im_sv = (struct sr_vol_meta *)(sm + 1);
im_sc = (struct sr_chunk_meta *)(im_sv + 1);
+ im_so = (struct sr_opt_meta *)(im_sc + im_sv->svm_no_chunk);
DNPRINTF(SR_D_META, "\tmeta magic 0x%llx\n", sm->ssd_magic);
DNPRINTF(SR_D_META, "\tmeta version %d\n", sm->ssd_version);
@@ -2412,6 +2485,13 @@ sr_print_metadata(struct sr_metadata *sm)
DNPRINTF(SR_D_META, "\tchunk size %u\n", sm->ssd_chunk_size);
DNPRINTF(SR_D_META, "\tchunk id %u\n", sm->ssd_chunk_id);
DNPRINTF(SR_D_META, "\tchunk checksum 0x%x\n", sm->ssd_chunk_chk);
+ if (sm->ssd_opt_no) {
+ DNPRINTF(SR_D_META, "\topt version %d\n", sm->ssd_opt_ver);
+ DNPRINTF(SR_D_META, "\topt items %d\n", sm->ssd_opt_no);
+ DNPRINTF(SR_D_META, "\topt size %d\n", sm->ssd_opt_size);
+ DNPRINTF(SR_D_META, "\topt chk 0x%x\n", sm->ssd_opt_chk);
+ }
+
DNPRINTF(SR_D_META, "\t\tvol id %d\n", im_sv->svm_volid);
DNPRINTF(SR_D_META, "\t\tvol status %d\n", im_sv->svm_status);
@@ -2444,4 +2524,15 @@ sr_print_metadata(struct sr_metadata *sm)
sr_print_uuid(&im_sc[ch].scm_uuid, 1);
}
}
+
+void
+sr_dump_mem(u_int8_t *p, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ printf("%02x ", *p++);
+ printf("\n");
+}
+
#endif /* SR_DEBUG */
diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c
index 28979c249cf..99f9ada6547 100644
--- a/sys/dev/softraid_crypto.c
+++ b/sys/dev/softraid_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_crypto.c,v 1.8 2008/02/05 16:49:25 marco Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.9 2008/02/07 15:08:49 marco Exp $ */
/*
* Copyright (c) 2007 Ted Unangst <tedu@openbsd.org>
* Copyright (c) 2008 Marco Peereboom <marco@openbsd.org>
@@ -49,6 +49,7 @@
struct cryptop * sr_crypto_getcryptop(struct sr_workunit *, int);
void *sr_crypto_putcryptop(struct cryptop *);
+int sr_crypto_decrypt_key(struct sr_discipline *);
int sr_crypto_write(struct cryptop *);
int sr_crypto_rw2(struct sr_workunit *, struct cryptop *);
void sr_crypto_intr(struct buf *);
@@ -96,7 +97,7 @@ sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt)
if (crp == NULL)
goto unwind;
- crp->crp_sid = sd->mds.mdd_crypto.src_sid;
+ crp->crp_sid = sd->mds.mdd_crypto.scr_sid;
crp->crp_ilen = xs->datalen;
crp->crp_alloctype = M_DEVBUF;
crp->crp_buf = uio;
@@ -108,7 +109,7 @@ sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt)
crd->crd_alg = CRYPTO_AES_CBC;
crd->crd_klen = 256;
crd->crd_rnd = 14;
- crd->crd_key = sd->mds.mdd_crypto.src_key;
+ crd->crd_key = sd->mds.mdd_crypto.scr_key;
memset(crd->crd_iv, blk + i, sizeof(crd->crd_iv));
}
@@ -139,6 +140,29 @@ sr_crypto_putcryptop(struct cryptop *crp)
return (wu);
}
+
+int
+sr_crypto_decrypt_key(struct sr_discipline *sd)
+{
+ /* XXX decrypt for real! */
+ bcopy(sd->mds.mdd_crypto.scr_meta[0].scm_key,
+ sd->mds.mdd_crypto.scr_key,
+ sizeof(sd->mds.mdd_crypto.scr_key));
+
+ return (0);
+}
+
+int
+sr_crypto_encrypt_key(struct sr_discipline *sd)
+{
+ /* XXX encrypt for real! */
+ bcopy(sd->mds.mdd_crypto.scr_key,
+ sd->mds.mdd_crypto.scr_meta[0].scm_key,
+ sizeof(sd->mds.mdd_crypto.scr_key));
+
+ return (0);
+}
+
int
sr_crypto_alloc_resources(struct sr_discipline *sd)
{
@@ -155,17 +179,17 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
if (sr_alloc_ccb(sd))
return (ENOMEM);
- /* XXX we need a real key later */
- memset(sd->mds.mdd_crypto.src_key, 'k',
- sizeof sd->mds.mdd_crypto.src_key);
+ if (sr_crypto_decrypt_key(sd)) {
+ return (1);
+ }
bzero(&cri, sizeof(cri));
cri.cri_alg = CRYPTO_AES_CBC;
cri.cri_klen = 256;
cri.cri_rnd = 14;
- cri.cri_key = sd->mds.mdd_crypto.src_key;
+ cri.cri_key = sd->mds.mdd_crypto.scr_key;
- return (crypto_newsession(&sd->mds.mdd_crypto.src_sid, &cri, 0));
+ return (crypto_newsession(&sd->mds.mdd_crypto.scr_sid, &cri, 0));
}
int
@@ -182,8 +206,11 @@ sr_crypto_free_resources(struct sr_discipline *sd)
sr_free_wu(sd);
sr_free_ccb(sd);
- if (sd->sd_meta)
+ if (sd->sd_meta) {
+ bzero(sd->mds.mdd_crypto.scr_key,
+ sizeof(sd->mds.mdd_crypto.scr_key));
free(sd->sd_meta, M_DEVBUF);
+ }
rv = 0;
return (rv);
diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h
index 1d6aa3bf2e3..f2f1af32612 100644
--- a/sys/dev/softraidvar.h
+++ b/sys/dev/softraidvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraidvar.h,v 1.43 2008/02/05 16:49:25 marco Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.44 2008/02/07 15:08:49 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -133,11 +133,30 @@ struct sr_raid1 {
u_int32_t sr1_counter;
};
-/* RAID CRYPTO */
+/* CRYPTO */
+struct sr_crypto_metadata {
+ u_int32_t scm_flags;
+#define SR_CRYPTOF_INVALID (0)
+#define SR_CRYPTOF_KEY (1<<0)
+#define SR_CRYPTOF_SALT (1<<1)
+#define SR_CRYPTOF_PASSPHRASE (1<<2)
+
+ u_int32_t scm_pad;
+ char scm_key[64];
+ char scm_salt[64];
+ char scm_passphrase[128]; /* _PASSWORD_LEN */
+};
+
#define SR_CRYPTO_NOWU 16
struct sr_crypto {
- u_int64_t src_sid;
- char src_key[64];
+ /*
+ * [0] contains encrypted key & salt
+ * [1] contains password
+ */
+ struct sr_crypto_metadata scr_meta[2];
+
+ u_int64_t scr_sid;
+ char scr_key[64]; /* unencrypted key */
};
#define SR_META_SIZE 32 /* save space at chunk beginning */
@@ -192,11 +211,11 @@ SLIST_HEAD(sr_metadata_list_head, sr_metadata_list);
#define SR_OPT_VERSION 1 /* bump when sr_opt_meta changes */
struct sr_opt_meta {
u_int32_t som_type;
- u_int32_t som_pad;
#define SR_OPT_INVALID 0x00
#define SR_OPT_CRYPTO 0x01
+ u_int32_t som_pad;
union {
- struct sr_crypto smm_crypto;
+ struct sr_crypto_metadata smm_crypto;
} som_meta;
};
@@ -401,5 +420,10 @@ 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_encrypt_key(struct sr_discipline *);
+
+#ifdef SR_DEBUG
+void sr_dump_mem(u_int8_t *, int);
+#endif
#endif /* SOFTRAIDVAR_H */