summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/softraid.c34
-rw-r--r--sys/dev/softraid_crypto.c115
-rw-r--r--sys/dev/softraidvar.h18
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);