summaryrefslogtreecommitdiff
path: root/sys/dev/softraid_crypto.c
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2009-12-15 13:19:38 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2009-12-15 13:19:38 +0000
commit8ed27ec4f664b4978413fa34ae76cb7285d1c652 (patch)
tree45b5fb394bc8c16dd1edd4c81e42098ece90d41c /sys/dev/softraid_crypto.c
parent1fdae7d88513e611e8f7756a3c456d97a6797a16 (diff)
Factor out discipline specific create/assemble code.
"in, in, in!" marco@
Diffstat (limited to 'sys/dev/softraid_crypto.c')
-rw-r--r--sys/dev/softraid_crypto.c93
1 files changed, 87 insertions, 6 deletions
diff --git a/sys/dev/softraid_crypto.c b/sys/dev/softraid_crypto.c
index 8b0d7f03729..4b7fba4778a 100644
--- a/sys/dev/softraid_crypto.c
+++ b/sys/dev/softraid_crypto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_crypto.c,v 1.43 2009/12/07 14:27:12 jsing Exp $ */
+/* $OpenBSD: softraid_crypto.c,v 1.44 2009/12/15 13:19:37 jsing Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
@@ -64,6 +64,10 @@ int sr_crypto_encrypt(u_char *, u_char *, u_char *, size_t, int);
int sr_crypto_decrypt_key(struct sr_discipline *);
int sr_crypto_change_maskkey(struct sr_discipline *,
struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *);
+int sr_crypto_create(struct sr_discipline *,
+ struct bioc_createraid *, int, int64_t);
+int sr_crypto_assemble(struct sr_discipline *,
+ struct bioc_createraid *, int);
int sr_crypto_alloc_resources(struct sr_discipline *);
int sr_crypto_free_resources(struct sr_discipline *);
int sr_crypto_ioctl(struct sr_discipline *,
@@ -86,14 +90,19 @@ void sr_crypto_dumpkeys(struct sr_discipline *);
void
sr_crypto_discipline_init(struct sr_discipline *sd)
{
+ int i;
/* Fill out discipline members. */
sd->sd_type = SR_MD_CRYPTO;
sd->sd_capabilities = SR_CAP_SYSTEM_DISK;
- sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no;
sd->sd_max_wu = SR_CRYPTO_NOWU;
+ for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)
+ sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
+
/* Setup discipline pointers. */
+ sd->sd_create = sr_crypto_create;
+ sd->sd_assemble = sr_crypto_assemble;
sd->sd_alloc_resources = sr_crypto_alloc_resources;
sd->sd_free_resources = sr_crypto_free_resources;
sd->sd_start_discipline = NULL;
@@ -110,6 +119,77 @@ sr_crypto_discipline_init(struct sr_discipline *sd)
sd->sd_set_vol_state = sr_raid1_set_vol_state;
}
+int
+sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc,
+ int no_chunk, int64_t coerced_size)
+{
+ int rv = EINVAL;
+
+ if (no_chunk != 1)
+ goto done;
+
+ /* no hint available yet */
+ if (bc->bc_opaque_flags & BIOC_SOOUT) {
+ bc->bc_opaque_status = BIOC_SOINOUT_FAILED;
+ rv = EAGAIN;
+ goto done;
+ }
+
+ if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE))
+ goto done;
+
+ if (sr_crypto_get_kdf(bc, sd))
+ goto done;
+
+ strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name));
+ sd->sd_meta->ssdi.ssd_size = coerced_size;
+
+ sr_crypto_create_keys(sd);
+
+ sd->sd_max_ccb_per_wu = no_chunk;
+
+ rv = 0;
+done:
+ return (rv);
+}
+
+int
+sr_crypto_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
+ int no_chunk)
+{
+ int rv = EINVAL;
+
+ /* provide userland with kdf hint */
+ if (bc->bc_opaque_flags & BIOC_SOOUT) {
+ if (bc->bc_opaque == NULL)
+ goto done;
+
+ if (sizeof(sd->mds.mdd_crypto.scr_meta.scm_kdfhint) <
+ bc->bc_opaque_size)
+ goto done;
+
+ if (copyout(sd->mds.mdd_crypto.scr_meta.scm_kdfhint,
+ bc->bc_opaque, bc->bc_opaque_size))
+ goto done;
+
+ /* we're done */
+ bc->bc_opaque_status = BIOC_SOINOUT_OK;
+ rv = EAGAIN;
+ goto done;
+ }
+
+ /* get kdf with maskkey from userland */
+ if (bc->bc_opaque_flags & BIOC_SOIN)
+ if (sr_crypto_get_kdf(bc, sd))
+ goto done;
+
+ sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no;
+
+ rv = 0;
+done:
+ return (rv);
+}
+
struct cryptop *
sr_crypto_getcryptop(struct sr_workunit *wu, int encrypt)
{
@@ -594,16 +674,17 @@ sr_crypto_free_resources(struct sr_discipline *sd)
sr_hotplug_unregister(sd, sr_crypto_hotplug);
for (i = 0; sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; i++) {
- crypto_freesession(
- sd->mds.mdd_crypto.scr_sid[i]);
+ crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]);
sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
}
sr_wu_free(sd);
sr_ccb_free(sd);
- pool_destroy(&sd->mds.mdd_crypto.sr_uiopl);
- pool_destroy(&sd->mds.mdd_crypto.sr_iovpl);
+ if (sd->mds.mdd_crypto.sr_uiopl.pr_serial != 0)
+ pool_destroy(&sd->mds.mdd_crypto.sr_uiopl);
+ if (sd->mds.mdd_crypto.sr_iovpl.pr_serial != 0)
+ pool_destroy(&sd->mds.mdd_crypto.sr_iovpl);
rv = 0;
return (rv);