diff options
-rw-r--r-- | sys/dev/softraid.c | 34 | ||||
-rw-r--r-- | sys/dev/softraid_crypto.c | 115 | ||||
-rw-r--r-- | sys/dev/softraidvar.h | 18 |
3 files changed, 114 insertions, 53 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c index cf11d846605..02bf54b4b9b 100644 --- a/sys/dev/softraid.c +++ b/sys/dev/softraid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid.c,v 1.102 2008/02/07 15:08:49 marco Exp $ */ +/* $OpenBSD: softraid.c,v 1.103 2008/02/14 22:04:34 ckuethe Exp $ */ /* * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us> * @@ -716,9 +716,6 @@ 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; @@ -810,37 +807,18 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user) vol_size = ch_entry->src_meta.scm_coerced_size; break; #if 0 +#ifdef CRYPTO case 'C': 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; + vol_size = ch_entry->src_meta.scm_size; + /* create crypto keys and encrypt them */ + sr_crypto_create_keys(sd); sr_crypto_encrypt_key(sd); break; +#endif /* CRYPTO */ #endif default: goto unwind; diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c index 99f9ada6547..8968f23baa5 100644 --- a/sys/dev/softraid_crypto.c +++ b/sys/dev/softraid_crypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid_crypto.c,v 1.9 2008/02/07 15:08:49 marco Exp $ */ +/* $OpenBSD: softraid_crypto.c,v 1.10 2008/02/14 22:04:34 ckuethe Exp $ */ /* * Copyright (c) 2007 Ted Unangst <tedu@openbsd.org> * Copyright (c) 2008 Marco Peereboom <marco@openbsd.org> @@ -39,6 +39,7 @@ #include <sys/uio.h> #include <crypto/cryptodev.h> +#include <crypto/md5.h> #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> @@ -66,6 +67,7 @@ sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt) struct uio *uio; int flags, i, n; daddr64_t blk = 0; + MD5_CTX ctx; DNPRINTF(SR_D_DIS, "%s: sr_crypto_getcryptop wu: %p encrypt: %d\n", DEVNAME(sd->sd_sc), wu, encrypt); @@ -89,7 +91,7 @@ sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt) else if (xs->cmdlen == 6) blk = _3btol(((struct scsi_rw *)xs->cmd)->addr); - n = xs->datalen >> 9; + n = xs->datalen >> DEV_BSHIFT; flags = (encrypt ? CRD_F_ENCRYPT : 0) | CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT; @@ -101,16 +103,24 @@ sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt) crp->crp_ilen = xs->datalen; crp->crp_alloctype = M_DEVBUF; crp->crp_buf = uio; - for (i = 0, crd = crp->crp_desc; crd; i++, crd = crd->crd_next) { - crd->crd_skip = 512 * i; - crd->crd_len = 512; + for (i = 0, crd = crp->crp_desc; crd; i++, blk++, crd = crd->crd_next) { + crd->crd_skip = i << DEV_BSHIFT; + crd->crd_len = DEV_BSIZE; crd->crd_inject = 0; crd->crd_flags = flags; crd->crd_alg = CRYPTO_AES_CBC; - crd->crd_klen = 256; - crd->crd_rnd = 14; - crd->crd_key = sd->mds.mdd_crypto.scr_key; - memset(crd->crd_iv, blk + i, sizeof(crd->crd_iv)); + crd->crd_klen = SR_CRYPTO_KEYBITS; + crd->crd_rnd = SR_CRYPTO_ROUNDS; + crd->crd_key = + sd->mds.mdd_crypto.scr_key2[blk % SR_CRYPTO_MAXKEYS]; + + /* use MD5 for IV because is exactly 16 bytes */ + MD5Init(&ctx); + MD5Update(&ctx, + sd->mds.mdd_crypto.scr_key1[blk % SR_CRYPTO_MAXKEYS], + sizeof(sd->mds.mdd_crypto.scr_key1[0])); + MD5Update(&ctx, (void *)&blk, sizeof blk); + MD5Final(crd->crd_iv, &ctx); } return (crp); @@ -144,10 +154,20 @@ sr_crypto_putcryptop(struct cryptop *crp) int sr_crypto_decrypt_key(struct sr_discipline *sd) { + int i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", + DEVNAME(sd->sd_sc)); + /* 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)); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + bcopy(sd->mds.mdd_crypto.scr_meta[0].scm_key1[i], + sd->mds.mdd_crypto.scr_key1[i], + sizeof(sd->mds.mdd_crypto.scr_key1[i])); + bcopy(sd->mds.mdd_crypto.scr_meta[0].scm_key2[i], + sd->mds.mdd_crypto.scr_key2[i], + sizeof(sd->mds.mdd_crypto.scr_key2[i])); + } return (0); } @@ -155,14 +175,61 @@ sr_crypto_decrypt_key(struct sr_discipline *sd) int sr_crypto_encrypt_key(struct sr_discipline *sd) { + int i; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_encrypt_key\n", + DEVNAME(sd->sd_sc)); + /* 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)); + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + bcopy(sd->mds.mdd_crypto.scr_key1[i], + sd->mds.mdd_crypto.scr_meta[0].scm_key1[i], + sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_key1[i])); + bcopy(sd->mds.mdd_crypto.scr_key2[i], + sd->mds.mdd_crypto.scr_meta[0].scm_key2[i], + sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_key2[i])); + } return (0); } +void +sr_crypto_create_keys(struct sr_discipline *sd) +{ + u_int32_t *pk1, *pk2, sz; + int i, x; + + DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n", + DEVNAME(sd->sd_sc)); + + /* generate crypto keys */ + for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) { + sz = sizeof(sd->mds.mdd_crypto.scr_key1[i]) / 4; + pk1 = (u_int32_t *)sd->mds.mdd_crypto.scr_key1[i]; + pk2 = (u_int32_t *)sd->mds.mdd_crypto.scr_key2[i]; + for (x = 0; x < sz; x++) { + *pk1++ = arc4random(); + *pk2++ = arc4random(); + } + } + + /* generate salt */ + sz = sizeof(sd->mds.mdd_crypto.scr_meta[0].scm_salt) / 4; + pk1 = (u_int32_t *) + sd->mds.mdd_crypto.scr_meta[0].scm_salt; + for (i = 0; i < sz; i++) + *pk1++ = 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; +} + int sr_crypto_alloc_resources(struct sr_discipline *sd) { @@ -185,10 +252,14 @@ sr_crypto_alloc_resources(struct sr_discipline *sd) 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.scr_key; - + cri.cri_klen = SR_CRYPTO_KEYBITS; + cri.cri_rnd = SR_CRYPTO_ROUNDS; + cri.cri_key = sd->mds.mdd_crypto.scr_key2[0]; + + /* + * XXX maybe we need to revisit the fact that we are only using one + * session even though we have 64 keys. + */ return (crypto_newsession(&sd->mds.mdd_crypto.scr_sid, &cri, 0)); } @@ -207,8 +278,10 @@ sr_crypto_free_resources(struct sr_discipline *sd) sr_free_ccb(sd); if (sd->sd_meta) { - bzero(sd->mds.mdd_crypto.scr_key, - sizeof(sd->mds.mdd_crypto.scr_key)); + bzero(sd->mds.mdd_crypto.scr_key1, + sizeof(sd->mds.mdd_crypto.scr_key1)); + bzero(sd->mds.mdd_crypto.scr_key2, + sizeof(sd->mds.mdd_crypto.scr_key2)); free(sd->sd_meta, M_DEVBUF); } diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h index f2f1af32612..292d667ddcc 100644 --- a/sys/dev/softraidvar.h +++ b/sys/dev/softraidvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: softraidvar.h,v 1.44 2008/02/07 15:08:49 marco Exp $ */ +/* $OpenBSD: softraidvar.h,v 1.45 2008/02/14 22:04:34 ckuethe Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> * @@ -134,6 +134,11 @@ struct sr_raid1 { }; /* CRYPTO */ +#define SR_CRYPTO_MAXKEYS 32 +#define SR_CRYPTO_KEYBITS 256 +#define SR_CRYPTO_KEYBYTES (SR_CRYPTO_KEYBITS >> 3) +#define SR_CRYPTO_ROUNDS 14 + struct sr_crypto_metadata { u_int32_t scm_flags; #define SR_CRYPTOF_INVALID (0) @@ -142,8 +147,9 @@ struct sr_crypto_metadata { #define SR_CRYPTOF_PASSPHRASE (1<<2) u_int32_t scm_pad; - char scm_key[64]; - char scm_salt[64]; + u_int8_t scm_key1[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; + u_int8_t scm_key2[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; + u_int8_t scm_salt[64]; char scm_passphrase[128]; /* _PASSWORD_LEN */ }; @@ -155,8 +161,11 @@ struct sr_crypto { */ struct sr_crypto_metadata scr_meta[2]; + /* decrypted keys */ + u_int8_t scr_key1[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; + u_int8_t scr_key2[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; + u_int64_t scr_sid; - char scr_key[64]; /* unencrypted key */ }; #define SR_META_SIZE 32 /* save space at chunk beginning */ @@ -421,6 +430,7 @@ 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 *); +void sr_crypto_create_keys(struct sr_discipline *); #ifdef SR_DEBUG void sr_dump_mem(u_int8_t *, int); |