diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2008-02-07 15:08:50 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2008-02-07 15:08:50 +0000 |
commit | 6b3f36a8d54742b75994faffc0399f5a367d8d63 (patch) | |
tree | 9065f6dff13d6234951e82079ff4a8829397710a | |
parent | fade589199b3a9aabf48bb6277411f0a64f605ac (diff) |
Add optional metadata memebers.
Randomize Crypto password and add salt array.
Add mock key encryption functions.
-rw-r--r-- | sys/dev/softraid.c | 109 | ||||
-rw-r--r-- | sys/dev/softraid_crypto.c | 45 | ||||
-rw-r--r-- | sys/dev/softraidvar.h | 36 |
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 */ |