Refactor softraid crypto code to allow use of a discipline-specific data
structure for RAID1C volumes, as requested by jsing@ during review of my
initial RAID1C patch.

This patch should effectively be a cosmetic change.
The whole point of this patch is to allow the data structure changes
made here in softraidvar.h.

It works in my testing but more testing would be very welcome, given
that this touches the disk I/O path of machines using softraid crypto.

ok?
 
diff d5cea33885618bf7e096efc36fffbecc9b13ed21 
fcfd3d6487eca3ffe994e6a46e37df66b37e80d1
blob - d143a2398b5aba3070dc25bafd02e38f8f10a0c1
blob + 48bd613f374bc6ad085ae5d9e0eeef50a6367941
--- sys/dev/softraid_crypto.c
+++ sys/dev/softraid_crypto.c
@@ -54,30 +54,44 @@
 
 #include <dev/softraidvar.h>
 
-struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int);
-int            sr_crypto_create_keys(struct sr_discipline *);
-int            sr_crypto_get_kdf(struct bioc_createraid *,
-                   struct sr_discipline *);
+struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *,
+                   struct sr_crypto *, int);
 int            sr_crypto_decrypt(u_char *, u_char *, u_char *, size_t, int);
 int            sr_crypto_encrypt(u_char *, u_char *, u_char *, size_t, int);
-int            sr_crypto_decrypt_key(struct sr_discipline *);
+int            sr_crypto_decrypt_key(struct sr_discipline *,
+                   struct sr_crypto *);
 int            sr_crypto_change_maskkey(struct sr_discipline *,
-                   struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *);
+                   struct sr_crypto *, struct sr_crypto_kdfinfo *,
+                   struct sr_crypto_kdfinfo *);
 int            sr_crypto_create(struct sr_discipline *,
                    struct bioc_createraid *, int, int64_t);
 int            sr_crypto_meta_create(struct sr_discipline *,
-                   struct bioc_createraid *);
+                   struct sr_crypto *, struct bioc_createraid *);
+int            sr_crypto_set_key(struct sr_discipline *, struct sr_crypto *,
+                   struct bioc_createraid *, int, void *);
 int            sr_crypto_assemble(struct sr_discipline *,
                    struct bioc_createraid *, int, void *);
+void           sr_crypto_free_sessions(struct sr_discipline *,
+                   struct sr_crypto *);
+int            sr_crypto_alloc_resources_internal(struct sr_discipline *,
+                   struct sr_crypto *);
 int            sr_crypto_alloc_resources(struct sr_discipline *);
+void           sr_crypto_free_resources_internal(struct sr_discipline *,
+                   struct sr_crypto *);
 void           sr_crypto_free_resources(struct sr_discipline *);
+int            sr_crypto_ioctl_internal(struct sr_discipline *,
+                   struct sr_crypto *, struct bioc_discipline *);
 int            sr_crypto_ioctl(struct sr_discipline *,
                    struct bioc_discipline *);
+int            sr_crypto_meta_opt_handler_internal(struct sr_discipline *,
+                   struct sr_crypto *, struct sr_meta_opt_hdr *);
 int            sr_crypto_meta_opt_handler(struct sr_discipline *,
                    struct sr_meta_opt_hdr *);
 void           sr_crypto_write(struct cryptop *);
 int            sr_crypto_rw(struct sr_workunit *);
 int            sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *);
+void           sr_crypto_done_internal(struct sr_workunit *,
+                   struct sr_crypto *);
 void           sr_crypto_done(struct sr_workunit *);
 void           sr_crypto_read(struct cryptop *);
 void           sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int,
@@ -85,7 +99,7 @@ void          sr_crypto_calculate_check_hmac_sha1(u_int8_t *, 
 void           sr_crypto_hotplug(struct sr_discipline *, struct disk *, int);
 
 #ifdef SR_DEBUG0
-void            sr_crypto_dumpkeys(struct sr_discipline *);
+void            sr_crypto_dumpkeys(struct sr_crypto *);
 #endif
 
 /* Discipline initialisation. */
@@ -129,7 +143,7 @@ sr_crypto_create(struct sr_discipline *sd, struct bioc
 
        sd->sd_meta->ssdi.ssd_size = coerced_size;
 
-       rv = sr_crypto_meta_create(sd, bc);
+       rv = sr_crypto_meta_create(sd, &sd->mds.mdd_crypto, bc);
        if (rv)
                return (rv);
 
@@ -138,7 +152,8 @@ sr_crypto_create(struct sr_discipline *sd, struct bioc
 }
 
 int
-sr_crypto_meta_create(struct sr_discipline *sd, struct bioc_createraid *bc)
+sr_crypto_meta_create(struct sr_discipline *sd, struct sr_crypto *mdd_crypto,
+    struct bioc_createraid *bc)
 {
        struct sr_meta_opt_item *omi;
        int                     rv = EINVAL;
@@ -158,19 +173,19 @@ sr_crypto_meta_create(struct sr_discipline *sd, struct
        omi->omi_som->som_type = SR_OPT_CRYPTO;
        omi->omi_som->som_length = sizeof(struct sr_meta_crypto);
        SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link);
-       sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)omi->omi_som;
+       mdd_crypto->scr_meta = (struct sr_meta_crypto *)omi->omi_som;
        sd->sd_meta->ssdi.ssd_opt_no++;
 
-       sd->mds.mdd_crypto.key_disk = NULL;
+       mdd_crypto->key_disk = NULL;
 
        if (bc->bc_key_disk != NODEV) {
 
                /* Create a key disk. */
-               if (sr_crypto_get_kdf(bc, sd))
+               if (sr_crypto_get_kdf(bc, sd, mdd_crypto))
                        goto done;
-               sd->mds.mdd_crypto.key_disk =
-                   sr_crypto_create_key_disk(sd, bc->bc_key_disk);
-               if (sd->mds.mdd_crypto.key_disk == NULL)
+               mdd_crypto->key_disk =
+                   sr_crypto_create_key_disk(sd, mdd_crypto, bc->bc_key_disk);
+               if (mdd_crypto->key_disk == NULL)
                        goto done;
                sd->sd_capabilities |= SR_CAP_AUTO_ASSEMBLE;
 
@@ -181,14 +196,14 @@ sr_crypto_meta_create(struct sr_discipline *sd, struct
                rv = EAGAIN;
                goto done;
 
-       } else if (sr_crypto_get_kdf(bc, sd))
+       } else if (sr_crypto_get_kdf(bc, sd, mdd_crypto))
                goto done;
 
        /* Passphrase volumes cannot be automatically assembled. */
        if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV)
                goto done;
 
-       sr_crypto_create_keys(sd);
+       sr_crypto_create_keys(sd, mdd_crypto);
 
        rv = 0;
 done:
@@ -196,37 +211,37 @@ done:
 }
 
 int
-sr_crypto_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
-    int no_chunk, void *data)
+sr_crypto_set_key(struct sr_discipline *sd, struct sr_crypto *mdd_crypto,
+    struct bioc_createraid *bc, int no_chunk, void *data)
 {
        int     rv = EINVAL;
 
-       sd->mds.mdd_crypto.key_disk = NULL;
+       mdd_crypto->key_disk = NULL;
 
        /* Crypto optional metadata must already exist... */
-       if (sd->mds.mdd_crypto.scr_meta == NULL)
+       if (mdd_crypto->scr_meta == NULL)
                goto done;
 
        if (data != NULL) {
                /* Kernel already has mask key. */
-               memcpy(sd->mds.mdd_crypto.scr_maskkey, data,
-                   sizeof(sd->mds.mdd_crypto.scr_maskkey));
+               memcpy(mdd_crypto->scr_maskkey, data,
+                   sizeof(mdd_crypto->scr_maskkey));
        } else if (bc->bc_key_disk != NODEV) {
                /* Read the mask key from the key disk. */
-               sd->mds.mdd_crypto.key_disk =
-                   sr_crypto_read_key_disk(sd, bc->bc_key_disk);
-               if (sd->mds.mdd_crypto.key_disk == NULL)
+               mdd_crypto->key_disk =
+                   sr_crypto_read_key_disk(sd, mdd_crypto, bc->bc_key_disk);
+               if (mdd_crypto->key_disk == NULL)
                        goto done;
        } else if (bc->bc_opaque_flags & BIOC_SOOUT) {
                /* provide userland with kdf hint */
                if (bc->bc_opaque == NULL)
                        goto done;
 
-               if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) <
+               if (sizeof(mdd_crypto->scr_meta->scm_kdfhint) <
                    bc->bc_opaque_size)
                        goto done;
 
-               if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
+               if (copyout(mdd_crypto->scr_meta->scm_kdfhint,
                    bc->bc_opaque, bc->bc_opaque_size))
                        goto done;
 
@@ -236,23 +251,36 @@ sr_crypto_assemble(struct sr_discipline *sd, struct bi
                goto done;
        } else if (bc->bc_opaque_flags & BIOC_SOIN) {
                /* get kdf with maskkey from userland */
-               if (sr_crypto_get_kdf(bc, sd))
+               if (sr_crypto_get_kdf(bc, sd, mdd_crypto))
                        goto done;
        } else
                goto done;
 
+
+       rv = 0;
+done:
+       return (rv);
+}
+
+int
+sr_crypto_assemble(struct sr_discipline *sd,
+    struct bioc_createraid *bc, int no_chunk, void *data)
+{
+       int rv;
+
+       rv = sr_crypto_set_key(sd, &sd->mds.mdd_crypto, bc, no_chunk, data);
+       if (rv)
+               return (rv);
+
        sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no;
-
-       rv = 0;
-done:
-       return (rv);
+       return (0);
 }
 
 struct sr_crypto_wu *
-sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
+sr_crypto_prepare(struct sr_workunit *wu, struct sr_crypto *mdd_crypto,
+    int encrypt)
 {
        struct scsi_xfer        *xs = wu->swu_xs;
-       struct sr_discipline    *sd = wu->swu_dis;
        struct sr_crypto_wu     *crwu;
        struct cryptodesc       *crd;
        int                     flags, i, n;
@@ -260,7 +288,7 @@ sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
        u_int                   keyndx;
 
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_prepare wu %p encrypt %d\n",
-           DEVNAME(sd->sd_sc), wu, encrypt);
+           DEVNAME(wu->swu_dis->sd_sc), wu, encrypt);
 
        crwu = (struct sr_crypto_wu *)wu;
        crwu->cr_uio.uio_iovcnt = 1;
@@ -292,7 +320,7 @@ sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
         * this is already broken by the use of scr_key[0] below.
         */
        keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT;
-       crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx];
+       crwu->cr_crp->crp_sid = mdd_crypto->scr_sid[keyndx];
 
        crwu->cr_crp->crp_opaque = crwu;
        crwu->cr_crp->crp_ilen = xs->datalen;
@@ -305,9 +333,9 @@ sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
                crd->crd_len = DEV_BSIZE;
                crd->crd_inject = 0;
                crd->crd_flags = flags;
-               crd->crd_alg = sd->mds.mdd_crypto.scr_alg;
-               crd->crd_klen = sd->mds.mdd_crypto.scr_klen;
-               crd->crd_key = sd->mds.mdd_crypto.scr_key[0];
+               crd->crd_alg = mdd_crypto->scr_alg;
+               crd->crd_klen = mdd_crypto->scr_klen;
+               crd->crd_key = mdd_crypto->scr_key[0];
                memcpy(crd->crd_iv, &blkno, sizeof(blkno));
        }
 
@@ -315,7 +343,8 @@ sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
 }
 
 int
-sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd)
+sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto)
 {
        int                     rv = EINVAL;
        struct sr_crypto_kdfinfo *kdfinfo;
@@ -336,19 +365,18 @@ sr_crypto_get_kdf(struct bioc_createraid *bc, struct s
 
        /* copy KDF hint to disk meta data */
        if (kdfinfo->flags & SR_CRYPTOKDF_HINT) {
-               if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) <
+               if (sizeof(mdd_crypto->scr_meta->scm_kdfhint) <
                    kdfinfo->genkdf.len)
                        goto out;
-               memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
+               memcpy(mdd_crypto->scr_meta->scm_kdfhint,
                    &kdfinfo->genkdf, kdfinfo->genkdf.len);
        }
 
        /* copy mask key to run-time meta data */
        if ((kdfinfo->flags & SR_CRYPTOKDF_KEY)) {
-               if (sizeof(sd->mds.mdd_crypto.scr_maskkey) <
-                   sizeof(kdfinfo->maskkey))
+               if (sizeof(mdd_crypto->scr_maskkey) < sizeof(kdfinfo->maskkey))
                        goto out;
-               memcpy(sd->mds.mdd_crypto.scr_maskkey, &kdfinfo->maskkey,
+               memcpy(mdd_crypto->scr_maskkey, &kdfinfo->maskkey,
                    sizeof(kdfinfo->maskkey));
        }
 
@@ -441,44 +469,42 @@ sr_crypto_calculate_check_hmac_sha1(u_int8_t *maskkey,
 }
 
 int
-sr_crypto_decrypt_key(struct sr_discipline *sd)
+sr_crypto_decrypt_key(struct sr_discipline *sd, struct sr_crypto *mdd_crypto)
 {
        u_char                  check_digest[SHA1_DIGEST_LENGTH];
        int                     rv = 1;
 
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc));
 
-       if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
+       if (mdd_crypto->scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
                goto out;
 
-       if (sr_crypto_decrypt((u_char *)sd->mds.mdd_crypto.scr_meta->scm_key,
-           (u_char *)sd->mds.mdd_crypto.scr_key,
-           sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key),
-           sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
+       if (sr_crypto_decrypt((u_char *)mdd_crypto->scr_meta->scm_key,
+           (u_char *)mdd_crypto->scr_key,
+           mdd_crypto->scr_maskkey, sizeof(mdd_crypto->scr_key),
+           mdd_crypto->scr_meta->scm_mask_alg) == -1)
                goto out;
 
 #ifdef SR_DEBUG0
-       sr_crypto_dumpkeys(sd);
+       sr_crypto_dumpkeys(mdd_crypto);
 #endif
 
        /* Check that the key decrypted properly. */
-       sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey,
-           sizeof(sd->mds.mdd_crypto.scr_maskkey),
-           (u_int8_t *)sd->mds.mdd_crypto.scr_key,
-           sizeof(sd->mds.mdd_crypto.scr_key),
-           check_digest);
-       if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac,
+       sr_crypto_calculate_check_hmac_sha1(mdd_crypto->scr_maskkey,
+           sizeof(mdd_crypto->scr_maskkey), (u_int8_t *)mdd_crypto->scr_key,
+           sizeof(mdd_crypto->scr_key), check_digest);
+       if (memcmp(mdd_crypto->scr_meta->chk_hmac_sha1.sch_mac,
            check_digest, sizeof(check_digest)) != 0) {
-               explicit_bzero(sd->mds.mdd_crypto.scr_key,
-                   sizeof(sd->mds.mdd_crypto.scr_key));
+               explicit_bzero(mdd_crypto->scr_key,
+                   sizeof(mdd_crypto->scr_key));
                goto out;
        }
 
        rv = 0; /* Success */
 out:
        /* we don't need the mask key anymore */
-       explicit_bzero(&sd->mds.mdd_crypto.scr_maskkey,
-           sizeof(sd->mds.mdd_crypto.scr_maskkey));
+       explicit_bzero(&mdd_crypto->scr_maskkey,
+           sizeof(mdd_crypto->scr_maskkey));
 
        explicit_bzero(check_digest, sizeof(check_digest));
 
@@ -486,53 +512,49 @@ out:
 }
 
 int
-sr_crypto_create_keys(struct sr_discipline *sd)
+sr_crypto_create_keys(struct sr_discipline *sd, struct sr_crypto *mdd_crypto)
 {
 
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n",
            DEVNAME(sd->sd_sc));
 
-       if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey))
+       if (AES_MAXKEYBYTES < sizeof(mdd_crypto->scr_maskkey))
                return (1);
 
        /* XXX allow user to specify */
-       sd->mds.mdd_crypto.scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256;
+       mdd_crypto->scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256;
 
        /* generate crypto keys */
-       arc4random_buf(sd->mds.mdd_crypto.scr_key,
-           sizeof(sd->mds.mdd_crypto.scr_key));
+       arc4random_buf(mdd_crypto->scr_key, sizeof(mdd_crypto->scr_key));
 
        /* Mask the disk keys. */
-       sd->mds.mdd_crypto.scr_meta->scm_mask_alg = SR_CRYPTOM_AES_ECB_256;
-       sr_crypto_encrypt((u_char *)sd->mds.mdd_crypto.scr_key,
-           (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key,
-           sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key),
-           sd->mds.mdd_crypto.scr_meta->scm_mask_alg);
+       mdd_crypto->scr_meta->scm_mask_alg = SR_CRYPTOM_AES_ECB_256;
+       sr_crypto_encrypt((u_char *)mdd_crypto->scr_key,
+           (u_char *)mdd_crypto->scr_meta->scm_key,
+           mdd_crypto->scr_maskkey, sizeof(mdd_crypto->scr_key),
+           mdd_crypto->scr_meta->scm_mask_alg);
 
        /* Prepare key decryption check code. */
-       sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
-       sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey,
-           sizeof(sd->mds.mdd_crypto.scr_maskkey),
-           (u_int8_t *)sd->mds.mdd_crypto.scr_key,
-           sizeof(sd->mds.mdd_crypto.scr_key),
-           sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac);
+       mdd_crypto->scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
+       sr_crypto_calculate_check_hmac_sha1(mdd_crypto->scr_maskkey,
+           sizeof(mdd_crypto->scr_maskkey),
+           (u_int8_t *)mdd_crypto->scr_key, sizeof(mdd_crypto->scr_key),
+           mdd_crypto->scr_meta->chk_hmac_sha1.sch_mac);
 
        /* Erase the plaintext disk keys */
-       explicit_bzero(sd->mds.mdd_crypto.scr_key,
-           sizeof(sd->mds.mdd_crypto.scr_key));
+       explicit_bzero(mdd_crypto->scr_key, sizeof(mdd_crypto->scr_key));
 
 #ifdef SR_DEBUG0
-       sr_crypto_dumpkeys(sd);
+       sr_crypto_dumpkeys(mdd_crypto);
 #endif
 
-       sd->mds.mdd_crypto.scr_meta->scm_flags = SR_CRYPTOF_KEY |
-           SR_CRYPTOF_KDFHINT;
+       mdd_crypto->scr_meta->scm_flags = SR_CRYPTOF_KEY | SR_CRYPTOF_KDFHINT;
 
        return (0);
 }
 
 int
-sr_crypto_change_maskkey(struct sr_discipline *sd,
+sr_crypto_change_maskkey(struct sr_discipline *sd, struct sr_crypto 
*mdd_crypto,
   struct sr_crypto_kdfinfo *kdfinfo1, struct sr_crypto_kdfinfo *kdfinfo2)
 {
        u_char                  check_digest[SHA1_DIGEST_LENGTH];
@@ -543,26 +565,26 @@ sr_crypto_change_maskkey(struct sr_discipline *sd,
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_change_maskkey\n",
            DEVNAME(sd->sd_sc));
 
-       if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
+       if (mdd_crypto->scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
                goto out;
 
-       c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key;
-       ksz = sizeof(sd->mds.mdd_crypto.scr_key);
+       c = (u_char *)mdd_crypto->scr_meta->scm_key;
+       ksz = sizeof(mdd_crypto->scr_key);
        p = malloc(ksz, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
        if (p == NULL)
                goto out;
 
        if (sr_crypto_decrypt(c, p, kdfinfo1->maskkey, ksz,
-           sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
+           mdd_crypto->scr_meta->scm_mask_alg) == -1)
                goto out;
 
 #ifdef SR_DEBUG0
-       sr_crypto_dumpkeys(sd);
+       sr_crypto_dumpkeys(mdd_crypto);
 #endif
 
        sr_crypto_calculate_check_hmac_sha1(kdfinfo1->maskkey,
            sizeof(kdfinfo1->maskkey), p, ksz, check_digest);
-       if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac,
+       if (memcmp(mdd_crypto->scr_meta->chk_hmac_sha1.sch_mac,
            check_digest, sizeof(check_digest)) != 0) {
                sr_error(sd->sd_sc, "incorrect key or passphrase");
                rv = EPERM;
@@ -572,29 +594,29 @@ sr_crypto_change_maskkey(struct sr_discipline *sd,
        /* Copy new KDF hint to metadata, if supplied. */
        if (kdfinfo2->flags & SR_CRYPTOKDF_HINT) {
                if (kdfinfo2->genkdf.len >
-                   sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint))
+                   sizeof(mdd_crypto->scr_meta->scm_kdfhint))
                        goto out;
-               explicit_bzero(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
-                   sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint));
-               memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
+               explicit_bzero(mdd_crypto->scr_meta->scm_kdfhint,
+                   sizeof(mdd_crypto->scr_meta->scm_kdfhint));
+               memcpy(mdd_crypto->scr_meta->scm_kdfhint,
                    &kdfinfo2->genkdf, kdfinfo2->genkdf.len);
        }
 
        /* Mask the disk keys. */
-       c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key;
+       c = (u_char *)mdd_crypto->scr_meta->scm_key;
        if (sr_crypto_encrypt(p, c, kdfinfo2->maskkey, ksz,
-           sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
+           mdd_crypto->scr_meta->scm_mask_alg) == -1)
                goto out;
 
        /* Prepare key decryption check code. */
-       sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
+       mdd_crypto->scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
        sr_crypto_calculate_check_hmac_sha1(kdfinfo2->maskkey,
-           sizeof(kdfinfo2->maskkey), (u_int8_t *)sd->mds.mdd_crypto.scr_key,
-           sizeof(sd->mds.mdd_crypto.scr_key), check_digest);
+           sizeof(kdfinfo2->maskkey), (u_int8_t *)mdd_crypto->scr_key,
+           sizeof(mdd_crypto->scr_key), check_digest);
 
        /* Copy new encrypted key and HMAC to metadata. */
-       memcpy(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, check_digest,
-           sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac));
+       memcpy(mdd_crypto->scr_meta->chk_hmac_sha1.sch_mac, check_digest,
+           sizeof(mdd_crypto->scr_meta->chk_hmac_sha1.sch_mac));
 
        rv = 0; /* Success */
 
@@ -612,7 +634,8 @@ out:
 }
 
 struct sr_chunk *
-sr_crypto_create_key_disk(struct sr_discipline *sd, dev_t dev)
+sr_crypto_create_key_disk(struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto, dev_t dev)
 {
        struct sr_softc         *sc = sd->sd_sc;
        struct sr_discipline    *fakesd = NULL;
@@ -730,8 +753,8 @@ sr_crypto_create_key_disk(struct sr_discipline *sd, de
        SLIST_INSERT_HEAD(&fakesd->sd_vol.sv_chunk_list, key_disk, src_link);
 
        /* Generate mask key. */
-       arc4random_buf(sd->mds.mdd_crypto.scr_maskkey,
-           sizeof(sd->mds.mdd_crypto.scr_maskkey));
+       arc4random_buf(mdd_crypto->scr_maskkey,
+           sizeof(mdd_crypto->scr_maskkey));
 
        /* Copy mask key to optional metadata area. */
        omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF,
@@ -741,7 +764,7 @@ sr_crypto_create_key_disk(struct sr_discipline *sd, de
        omi->omi_som->som_type = SR_OPT_KEYDISK;
        omi->omi_som->som_length = sizeof(struct sr_meta_keydisk);
        skm = (struct sr_meta_keydisk *)omi->omi_som;
-       memcpy(&skm->skm_maskkey, sd->mds.mdd_crypto.scr_maskkey,
+       memcpy(&skm->skm_maskkey, mdd_crypto->scr_maskkey,
            sizeof(skm->skm_maskkey));
        SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link);
        fakesd->sd_meta->ssdi.ssd_opt_no++;
@@ -774,7 +797,8 @@ done:
 }
 
 struct sr_chunk *
-sr_crypto_read_key_disk(struct sr_discipline *sd, dev_t dev)
+sr_crypto_read_key_disk(struct sr_discipline *sd, struct sr_crypto *mdd_crypto,
+    dev_t dev)
 {
        struct sr_softc         *sc = sd->sd_sc;
        struct sr_metadata      *sm = NULL;
@@ -866,13 +890,13 @@ sr_crypto_read_key_disk(struct sr_discipline *sd, dev_
                omh = omi->omi_som;
                if (omh->som_type == SR_OPT_KEYDISK) {
                        skm = (struct sr_meta_keydisk *)omh;
-                       memcpy(sd->mds.mdd_crypto.scr_maskkey, 
&skm->skm_maskkey,
-                           sizeof(sd->mds.mdd_crypto.scr_maskkey));
+                       memcpy(mdd_crypto->scr_maskkey, &skm->skm_maskkey,
+                           sizeof(mdd_crypto->scr_maskkey));
                } else if (omh->som_type == SR_OPT_CRYPTO) {
                        /* Original keydisk format with key in crypto area. */
-                       memcpy(sd->mds.mdd_crypto.scr_maskkey,
+                       memcpy(mdd_crypto->scr_maskkey,
                            omh + sizeof(struct sr_meta_opt_hdr),
-                           sizeof(sd->mds.mdd_crypto.scr_maskkey));
+                           sizeof(mdd_crypto->scr_maskkey));
                }
        }
 
@@ -895,21 +919,22 @@ done:
        return key_disk;
 }
 
-static void
-sr_crypto_free_sessions(struct sr_discipline *sd)
+void
+sr_crypto_free_sessions(struct sr_discipline *sd, struct sr_crypto *mdd_crypto)
 {
        u_int                   i;
 
        for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
-               if (sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1) {
-                       crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]);
-                       sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
+               if (mdd_crypto->scr_sid[i] != (u_int64_t)-1) {
+                       crypto_freesession(mdd_crypto->scr_sid[i]);
+                       mdd_crypto->scr_sid[i] = (u_int64_t)-1;
                }
        }
 }
 
 int
-sr_crypto_alloc_resources(struct sr_discipline *sd)
+sr_crypto_alloc_resources_internal(struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto)
 {
        struct sr_workunit      *wu;
        struct sr_crypto_wu     *crwu;
@@ -919,13 +944,13 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n",
            DEVNAME(sd->sd_sc));
 
-       sd->mds.mdd_crypto.scr_alg = CRYPTO_AES_XTS;
-       switch (sd->mds.mdd_crypto.scr_meta->scm_alg) {
+       mdd_crypto->scr_alg = CRYPTO_AES_XTS;
+       switch (mdd_crypto->scr_meta->scm_alg) {
        case SR_CRYPTOA_AES_XTS_128:
-               sd->mds.mdd_crypto.scr_klen = 256;
+               mdd_crypto->scr_klen = 256;
                break;
        case SR_CRYPTOA_AES_XTS_256:
-               sd->mds.mdd_crypto.scr_klen = 512;
+               mdd_crypto->scr_klen = 512;
                break;
        default:
                sr_error(sd->sd_sc, "unknown crypto algorithm");
@@ -933,7 +958,7 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        }
 
        for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)
-               sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
+               mdd_crypto->scr_sid[i] = (u_int64_t)-1;
 
        if (sr_wu_alloc(sd)) {
                sr_error(sd->sd_sc, "unable to allocate work units");
@@ -943,7 +968,7 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
                sr_error(sd->sd_sc, "unable to allocate CCBs");
                return (ENOMEM);
        }
-       if (sr_crypto_decrypt_key(sd)) {
+       if (sr_crypto_decrypt_key(sd, mdd_crypto)) {
                sr_error(sd->sd_sc, "incorrect key or passphrase");
                return (EPERM);
        }
@@ -964,8 +989,8 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        }
 
        memset(&cri, 0, sizeof(cri));
-       cri.cri_alg = sd->mds.mdd_crypto.scr_alg;
-       cri.cri_klen = sd->mds.mdd_crypto.scr_klen;
+       cri.cri_alg = mdd_crypto->scr_alg;
+       cri.cri_klen = mdd_crypto->scr_klen;
 
        /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */
        num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >>
@@ -973,10 +998,10 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        if (num_keys > SR_CRYPTO_MAXKEYS)
                return (EFBIG);
        for (i = 0; i < num_keys; i++) {
-               cri.cri_key = sd->mds.mdd_crypto.scr_key[i];
-               if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i],
+               cri.cri_key = mdd_crypto->scr_key[i];
+               if (crypto_newsession(&mdd_crypto->scr_sid[i],
                    &cri, 0) != 0) {
-                       sr_crypto_free_sessions(sd);
+                       sr_crypto_free_sessions(sd, mdd_crypto);
                        return (EINVAL);
                }
        }
@@ -986,8 +1011,15 @@ sr_crypto_alloc_resources(struct sr_discipline *sd)
        return (0);
 }
 
+int
+sr_crypto_alloc_resources(struct sr_discipline *sd)
+{
+       return sr_crypto_alloc_resources_internal(sd, &sd->mds.mdd_crypto);
+}
+
 void
-sr_crypto_free_resources(struct sr_discipline *sd)
+sr_crypto_free_resources_internal(struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto)
 {
        struct sr_workunit      *wu;
        struct sr_crypto_wu     *crwu;
@@ -995,16 +1027,16 @@ sr_crypto_free_resources(struct sr_discipline *sd)
        DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n",
            DEVNAME(sd->sd_sc));
 
-       if (sd->mds.mdd_crypto.key_disk != NULL) {
-               explicit_bzero(sd->mds.mdd_crypto.key_disk,
-                   sizeof(*sd->mds.mdd_crypto.key_disk));
-               free(sd->mds.mdd_crypto.key_disk, M_DEVBUF,
-                   sizeof(*sd->mds.mdd_crypto.key_disk));
+       if (mdd_crypto->key_disk != NULL) {
+               explicit_bzero(mdd_crypto->key_disk,
+                   sizeof(*mdd_crypto->key_disk));
+               free(mdd_crypto->key_disk, M_DEVBUF,
+                   sizeof(*mdd_crypto->key_disk));
        }
 
        sr_hotplug_unregister(sd, sr_crypto_hotplug);
 
-       sr_crypto_free_sessions(sd);
+       sr_crypto_free_sessions(sd, mdd_crypto);
 
        TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) {
                crwu = (struct sr_crypto_wu *)wu;
@@ -1018,8 +1050,16 @@ sr_crypto_free_resources(struct sr_discipline *sd)
        sr_ccb_free(sd);
 }
 
+void
+sr_crypto_free_resources(struct sr_discipline *sd)
+{
+       struct sr_crypto *mdd_crypto = &sd->mds.mdd_crypto;
+       sr_crypto_free_resources_internal(sd, mdd_crypto);
+}
+
 int
-sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd)
+sr_crypto_ioctl_internal(struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto, struct bioc_discipline *bd)
 {
        struct sr_crypto_kdfpair kdfpair;
        struct sr_crypto_kdfinfo kdfinfo1, kdfinfo2;
@@ -1032,10 +1072,10 @@ sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_
        case SR_IOCTL_GET_KDFHINT:
 
                /* Get KDF hint for userland. */
-               size = sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint);
+               size = sizeof(mdd_crypto->scr_meta->scm_kdfhint);
                if (bd->bd_data == NULL || bd->bd_size > size)
                        goto bad;
-               if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
+               if (copyout(mdd_crypto->scr_meta->scm_kdfhint,
                    bd->bd_data, bd->bd_size))
                        goto bad;
 
@@ -1065,7 +1105,8 @@ sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_
                if (copyin(kdfpair.kdfinfo2, &kdfinfo2, size))
                        goto bad;
 
-               if (sr_crypto_change_maskkey(sd, &kdfinfo1, &kdfinfo2))
+               if (sr_crypto_change_maskkey(sd, mdd_crypto, &kdfinfo1,
+                   &kdfinfo2))
                        goto bad;
 
                /* Save metadata to disk. */
@@ -1083,12 +1124,20 @@ bad:
 }
 
 int
-sr_crypto_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr 
*om)
+sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd)
 {
+       struct sr_crypto *mdd_crypto = &sd->mds.mdd_crypto;
+       return sr_crypto_ioctl_internal(sd, mdd_crypto, bd);
+}
+
+int
+sr_crypto_meta_opt_handler_internal(struct sr_discipline *sd,
+    struct sr_crypto *mdd_crypto, struct sr_meta_opt_hdr *om)
+{
        int rv = EINVAL;
 
        if (om->som_type == SR_OPT_CRYPTO) {
-               sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)om;
+               mdd_crypto->scr_meta = (struct sr_meta_crypto *)om;
                rv = 0;
        }
 
@@ -1096,9 +1145,17 @@ sr_crypto_meta_opt_handler(struct sr_discipline *sd, s
 }
 
 int
+sr_crypto_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr 
*om)
+{
+       struct sr_crypto *mdd_crypto = &sd->mds.mdd_crypto;
+       return sr_crypto_meta_opt_handler_internal(sd, mdd_crypto, om);
+}
+
+int
 sr_crypto_rw(struct sr_workunit *wu)
 {
        struct sr_crypto_wu     *crwu;
+       struct sr_crypto        *mdd_crypto;
        daddr_t                 blkno;
        int                     rv = 0;
 
@@ -1109,7 +1166,8 @@ sr_crypto_rw(struct sr_workunit *wu)
                return (1);
 
        if (wu->swu_xs->flags & SCSI_DATA_OUT) {
-               crwu = sr_crypto_prepare(wu, 1);
+               mdd_crypto = &wu->swu_dis->mds.mdd_crypto;
+               crwu = sr_crypto_prepare(wu, mdd_crypto, 1);
                crwu->cr_crp->crp_callback = sr_crypto_write;
                rv = crypto_dispatch(crwu->cr_crp);
                if (rv == 0)
@@ -1177,7 +1235,7 @@ bad:
 }
 
 void
-sr_crypto_done(struct sr_workunit *wu)
+sr_crypto_done_internal(struct sr_workunit *wu, struct sr_crypto *mdd_crypto)
 {
        struct scsi_xfer        *xs = wu->swu_xs;
        struct sr_crypto_wu     *crwu;
@@ -1188,7 +1246,7 @@ sr_crypto_done(struct sr_workunit *wu)
 
        /* If this was a successful read, initiate decryption of the data. */
        if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) {
-               crwu = sr_crypto_prepare(wu, 0);
+               crwu = sr_crypto_prepare(wu, mdd_crypto, 0);
                crwu->cr_crp->crp_callback = sr_crypto_read;
                DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n",
                    DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp);
@@ -1202,6 +1260,13 @@ sr_crypto_done(struct sr_workunit *wu)
 }
 
 void
+sr_crypto_done(struct sr_workunit *wu)
+{
+       struct sr_crypto *mdd_crypto = &wu->swu_dis->mds.mdd_crypto;
+       sr_crypto_done_internal(wu, mdd_crypto);
+}
+
+void
 sr_crypto_read(struct cryptop *crp)
 {
        struct sr_crypto_wu     *crwu = crp->crp_opaque;
@@ -1228,7 +1293,7 @@ sr_crypto_hotplug(struct sr_discipline *sd, struct dis
 
 #ifdef SR_DEBUG0
 void
-sr_crypto_dumpkeys(struct sr_discipline *sd)
+sr_crypto_dumpkeys(struct sr_crypto *mdd_crypto)
 {
        int                     i, j;
 
@@ -1236,8 +1301,7 @@ sr_crypto_dumpkeys(struct sr_discipline *sd)
        for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
                printf("\tscm_key[%d]: 0x", i);
                for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) {
-                       printf("%02x",
-                           sd->mds.mdd_crypto.scr_meta->scm_key[i][j]);
+                       printf("%02x", mdd_crypto->scr_meta->scm_key[i][j]);
                }
                printf("\n");
        }
@@ -1245,8 +1309,7 @@ sr_crypto_dumpkeys(struct sr_discipline *sd)
        for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
                printf("\tscr_key[%d]: 0x", i);
                for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) {
-                       printf("%02x",
-                           sd->mds.mdd_crypto.scr_key[i][j]);
+                       printf("%02x", mdd_crypto->scr_key[i][j]);
                }
                printf("\n");
        }
blob - 2d851110c73028356d050655d1dc7f22ce3d0f37
blob + 98587608408952c53677e39f2fa0c7e796b0575a
--- sys/dev/softraid_raid1c.c
+++ sys/dev/softraid_raid1c.c
@@ -53,9 +53,15 @@ int  sr_raid1c_create(struct sr_discipline *, struct bi
 int    sr_raid1c_add_offline_chunks(struct sr_discipline *, int);
 int    sr_raid1c_assemble(struct sr_discipline *, struct bioc_createraid *,
            int, void *);
+int    sr_raid1c_alloc_resources(struct sr_discipline *);
+void   sr_raid1c_free_resources(struct sr_discipline *sd);
+int    sr_raid1c_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd);
+int    sr_raid1c_meta_opt_handler(struct sr_discipline *,
+           struct sr_meta_opt_hdr *);
 void   sr_raid1c_write(struct cryptop *);
 int    sr_raid1c_rw(struct sr_workunit *);
 int    sr_raid1c_dev_rw(struct sr_workunit *, struct sr_crypto_wu *);
+void   sr_raid1c_done(struct sr_workunit *wu);
 
 /* RAID1 functions */
 extern int     sr_raid1_init(struct sr_discipline *sd);
@@ -66,18 +72,22 @@ extern void sr_raid1_set_chunk_state(struct sr_discipl
 extern void    sr_raid1_set_vol_state(struct sr_discipline *);
 
 /* CRYPTO raid functions */
-extern struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int);
+extern struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *,
+                   struct sr_crypto *, int);
 extern int     sr_crypto_meta_create(struct sr_discipline *,
-                   struct bioc_createraid *);
-extern int     sr_crypto_assemble(struct sr_discipline *,
-                   struct bioc_createraid *, int, void *);
-extern int     sr_crypto_alloc_resources(struct sr_discipline *);
-extern void    sr_crypto_free_resources(struct sr_discipline *);
-extern int     sr_crypto_ioctl(struct sr_discipline *,
-                   struct bioc_discipline *);
-extern int     sr_crypto_meta_opt_handler(struct sr_discipline *,
-                   struct sr_meta_opt_hdr *);
-void           sr_crypto_done(struct sr_workunit *);
+                   struct sr_crypto *, struct bioc_createraid *);
+extern int     sr_crypto_set_key(struct sr_discipline *,
+                   struct sr_crypto *, struct bioc_createraid *, int, void *);
+extern int     sr_crypto_alloc_resources_internal(struct sr_discipline *,
+                   struct sr_crypto *);
+extern void    sr_crypto_free_resources_internal(struct sr_discipline *,
+                   struct sr_crypto *);
+extern int     sr_crypto_ioctl_internal(struct sr_discipline *,
+                   struct sr_crypto *, struct bioc_discipline *);
+int            sr_crypto_meta_opt_handler_internal(struct sr_discipline *,
+                   struct sr_crypto *, struct sr_meta_opt_hdr *);
+void           sr_crypto_done_internal(struct sr_workunit *,
+                   struct sr_crypto *);
 
 /* Discipline initialisation. */
 void
@@ -94,17 +104,17 @@ sr_raid1c_discipline_init(struct sr_discipline *sd)
        sd->sd_max_wu = SR_RAID1C_NOWU;
 
        for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)
-               sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
+               sd->mds.mdd_raid1c.sr1c_crypto.scr_sid[i] = (u_int64_t)-1;
 
        /* Setup discipline specific function pointers. */
-       sd->sd_alloc_resources = sr_crypto_alloc_resources;
+       sd->sd_alloc_resources = sr_raid1c_alloc_resources;
        sd->sd_assemble = sr_raid1c_assemble;
        sd->sd_create = sr_raid1c_create;
-       sd->sd_free_resources = sr_crypto_free_resources;
-       sd->sd_ioctl_handler = sr_crypto_ioctl;
-       sd->sd_meta_opt_handler = sr_crypto_meta_opt_handler;
+       sd->sd_free_resources = sr_raid1c_free_resources;
+       sd->sd_ioctl_handler = sr_raid1c_ioctl;
+       sd->sd_meta_opt_handler = sr_raid1c_meta_opt_handler;
        sd->sd_scsi_rw = sr_raid1c_rw;
-       sd->sd_scsi_done = sr_crypto_done;
+       sd->sd_scsi_done = sr_raid1c_done;
        sd->sd_scsi_wu_done = sr_raid1_wu_done;
        sd->sd_set_chunk_state = sr_raid1_set_chunk_state;
        sd->sd_set_vol_state = sr_raid1_set_vol_state;
@@ -128,7 +138,7 @@ sr_raid1c_create(struct sr_discipline *sd, struct bioc
        if (rv)
                return rv;
 
-       return sr_crypto_meta_create(sd, bc);
+       return sr_crypto_meta_create(sd, &sd->mds.mdd_raid1c.sr1c_crypto, bc);
 }
 
 int
@@ -165,6 +175,7 @@ int
 sr_raid1c_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
     int no_chunk, void *data)
 {
+       struct sr_raid1c *mdd_raid1c = &sd->mds.mdd_raid1c;
        int rv;
 
        /* Create NODEV place-holders for missing chunks. */
@@ -176,16 +187,39 @@ sr_raid1c_assemble(struct sr_discipline *sd, struct bi
 
        rv = sr_raid1_assemble(sd, bc, no_chunk, NULL);
        if (rv)
-               return rv;
+               return (rv);
 
-       return sr_crypto_assemble(sd, bc, no_chunk, data);
+       return sr_crypto_set_key(sd, &mdd_raid1c->sr1c_crypto, bc,
+           no_chunk, data);
 }
 
 int
+sr_raid1c_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd)
+{
+       struct sr_raid1c *mdd_raid1c = &sd->mds.mdd_raid1c;
+       return sr_crypto_ioctl_internal(sd, &mdd_raid1c->sr1c_crypto, bd);
+}
+
+int
+sr_raid1c_alloc_resources(struct sr_discipline *sd)
+{
+       struct sr_raid1c *mdd_raid1c = &sd->mds.mdd_raid1c;
+       return sr_crypto_alloc_resources_internal(sd, &mdd_raid1c->sr1c_crypto);
+}
+
+void
+sr_raid1c_free_resources(struct sr_discipline *sd)
+{
+       struct sr_raid1c *mdd_raid1c = &sd->mds.mdd_raid1c;
+       sr_crypto_free_resources_internal(sd, &mdd_raid1c->sr1c_crypto);
+}
+
+int
 sr_raid1c_dev_rw(struct sr_workunit *wu, struct sr_crypto_wu *crwu)
 {
        struct sr_discipline    *sd = wu->swu_dis;
        struct scsi_xfer        *xs = wu->swu_xs;
+       struct sr_raid1c        *mdd_raid1c = &sd->mds.mdd_raid1c;
        struct sr_ccb           *ccb;
        struct uio              *uio;
        struct sr_chunk         *scp;
@@ -204,7 +238,7 @@ sr_raid1c_dev_rw(struct sr_workunit *wu, struct sr_cry
                        rt = 0;
 ragain:
                        /* interleave reads */
-                       chunk = sd->mds.mdd_crypto.scr_raid1.sr1_counter++ %
+                       chunk = mdd_raid1c->sr1c_raid1.sr1_counter++ %
                            sd->sd_meta->ssdi.ssd_chunk_no;
                        scp = sd->sd_vol.sv_chunks[chunk];
                        switch (scp->src_meta.scm_status) {
@@ -299,9 +333,18 @@ sr_raid1c_write(struct cryptop *crp)
 }
 
 int
+sr_raid1c_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr 
*om)
+{
+       struct sr_raid1c *mdd_raid1c = &sd->mds.mdd_raid1c;
+       return sr_crypto_meta_opt_handler_internal(sd,
+           &mdd_raid1c->sr1c_crypto, om);
+}
+
+int
 sr_raid1c_rw(struct sr_workunit *wu)
 {
        struct sr_crypto_wu     *crwu;
+       struct sr_raid1c        *mdd_raid1c;
        daddr_t                 blkno;
        int                     rv = 0;
 
@@ -313,7 +356,8 @@ sr_raid1c_rw(struct sr_workunit *wu)
        
        if (ISSET(wu->swu_xs->flags, SCSI_DATA_OUT) &&
            !ISSET(wu->swu_flags, SR_WUF_REBUILD)) {
-               crwu = sr_crypto_prepare(wu, 1);
+               mdd_raid1c = &wu->swu_dis->mds.mdd_raid1c;
+               crwu = sr_crypto_prepare(wu, &mdd_raid1c->sr1c_crypto, 1);
                crwu->cr_crp->crp_callback = sr_raid1c_write;
                rv = crypto_dispatch(crwu->cr_crp);
                if (rv == 0)
@@ -323,3 +367,10 @@ sr_raid1c_rw(struct sr_workunit *wu)
 
        return (rv);
 }
+
+void
+sr_raid1c_done(struct sr_workunit *wu)
+{
+       struct sr_raid1c *mdd_raid1c = &wu->swu_dis->mds.mdd_raid1c;
+       sr_crypto_done_internal(wu, &mdd_raid1c->sr1c_crypto);
+}
blob - e66adcc2b0ccccf61c8d28a2415442ba7757b00b
blob + eb1fb33006cc466a11604e16eba1ca72150ffb32
--- sys/dev/softraidvar.h
+++ sys/dev/softraidvar.h
@@ -468,8 +468,6 @@ struct sr_crypto {
        u_int8_t                scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES];
        u_int8_t                scr_maskkey[SR_CRYPTO_MAXKEYBYTES];
        u_int64_t               scr_sid[SR_CRYPTO_MAXKEYS];
-
-       struct sr_raid1         scr_raid1; /* for RAID1C */
 };
 
 #define SR_CONCAT_NOWU         16
@@ -478,7 +476,10 @@ struct sr_concat {
 
 /* RAID 1C */
 #define SR_RAID1C_NOWU         16
-/* Uses sr_crypto */
+struct sr_raid1c {
+       struct sr_crypto        sr1c_crypto;
+       struct sr_raid1         sr1c_raid1;
+};
 
 struct sr_chunk {
        struct sr_meta_chunk    src_meta;       /* chunk meta data */
@@ -543,6 +544,7 @@ struct sr_discipline {
            struct sr_concat    mdd_concat;
 #ifdef CRYPTO
            struct sr_crypto    mdd_crypto;
+           struct sr_raid1c    mdd_raid1c;
 #endif /* CRYPTO */
        }                       sd_dis_specific;/* dis specific members */
 #define mds                    sd_dis_specific
@@ -731,10 +733,13 @@ void                      
sr_raid1c_discipline_init(struct sr_discipline 
 
 /* Crypto discipline hooks. */
 int                    sr_crypto_get_kdf(struct bioc_createraid *,
-                           struct sr_discipline *);
-int                    sr_crypto_create_keys(struct sr_discipline *);
-struct sr_chunk *      sr_crypto_create_key_disk(struct sr_discipline *, 
dev_t);
-struct sr_chunk *      sr_crypto_read_key_disk(struct sr_discipline *, dev_t);
+                           struct sr_discipline *, struct sr_crypto *);
+int                    sr_crypto_create_keys(struct sr_discipline *,
+                           struct sr_crypto *);
+struct sr_chunk *      sr_crypto_create_key_disk(struct sr_discipline *,
+                           struct sr_crypto *, dev_t);
+struct sr_chunk *      sr_crypto_read_key_disk(struct sr_discipline *,
+                           struct sr_crypto *, dev_t);
 
 /* Hibernate I/O function */
 int                    sr_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr,



Reply via email to