LCOV - code coverage report
Current view: top level - dev - softraid_crypto.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 538 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: softraid_crypto.c,v 1.137 2017/06/12 16:39:51 jsing Exp $ */
       2             : /*
       3             :  * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
       4             :  * Copyright (c) 2008 Hans-Joerg Hoexer <hshoexer@openbsd.org>
       5             :  * Copyright (c) 2008 Damien Miller <djm@mindrot.org>
       6             :  * Copyright (c) 2009 Joel Sing <jsing@openbsd.org>
       7             :  *
       8             :  * Permission to use, copy, modify, and distribute this software for any
       9             :  * purpose with or without fee is hereby granted, provided that the above
      10             :  * copyright notice and this permission notice appear in all copies.
      11             :  *
      12             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      13             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      14             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      15             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      16             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      17             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      18             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      19             :  */
      20             : 
      21             : #include "bio.h"
      22             : 
      23             : #include <sys/param.h>
      24             : #include <sys/systm.h>
      25             : #include <sys/buf.h>
      26             : #include <sys/device.h>
      27             : #include <sys/ioctl.h>
      28             : #include <sys/malloc.h>
      29             : #include <sys/pool.h>
      30             : #include <sys/kernel.h>
      31             : #include <sys/disk.h>
      32             : #include <sys/rwlock.h>
      33             : #include <sys/queue.h>
      34             : #include <sys/fcntl.h>
      35             : #include <sys/disklabel.h>
      36             : #include <sys/vnode.h>
      37             : #include <sys/mount.h>
      38             : #include <sys/sensors.h>
      39             : #include <sys/stat.h>
      40             : #include <sys/conf.h>
      41             : #include <sys/uio.h>
      42             : #include <sys/dkio.h>
      43             : 
      44             : #include <crypto/cryptodev.h>
      45             : #include <crypto/rijndael.h>
      46             : #include <crypto/md5.h>
      47             : #include <crypto/sha1.h>
      48             : #include <crypto/sha2.h>
      49             : #include <crypto/hmac.h>
      50             : 
      51             : #include <scsi/scsi_all.h>
      52             : #include <scsi/scsiconf.h>
      53             : #include <scsi/scsi_disk.h>
      54             : 
      55             : #include <dev/softraidvar.h>
      56             : 
      57             : /*
      58             :  * The per-I/O data that we need to preallocate. We cannot afford to allow I/O
      59             :  * to start failing when memory pressure kicks in. We can store this in the WU
      60             :  * because we assert that only one ccb per WU will ever be active.
      61             :  */
      62             : struct sr_crypto_wu {
      63             :         struct sr_workunit               cr_wu;         /* Must be first. */
      64             :         struct uio                       cr_uio;
      65             :         struct iovec                     cr_iov;
      66             :         struct cryptop                  *cr_crp;
      67             :         void                            *cr_dmabuf;
      68             : };
      69             : 
      70             : 
      71             : struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int);
      72             : int             sr_crypto_create_keys(struct sr_discipline *);
      73             : int             sr_crypto_get_kdf(struct bioc_createraid *,
      74             :                     struct sr_discipline *);
      75             : int             sr_crypto_decrypt(u_char *, u_char *, u_char *, size_t, int);
      76             : int             sr_crypto_encrypt(u_char *, u_char *, u_char *, size_t, int);
      77             : int             sr_crypto_decrypt_key(struct sr_discipline *);
      78             : int             sr_crypto_change_maskkey(struct sr_discipline *,
      79             :                     struct sr_crypto_kdfinfo *, struct sr_crypto_kdfinfo *);
      80             : int             sr_crypto_create(struct sr_discipline *,
      81             :                     struct bioc_createraid *, int, int64_t);
      82             : int             sr_crypto_assemble(struct sr_discipline *,
      83             :                     struct bioc_createraid *, int, void *);
      84             : int             sr_crypto_alloc_resources(struct sr_discipline *);
      85             : void            sr_crypto_free_resources(struct sr_discipline *);
      86             : int             sr_crypto_ioctl(struct sr_discipline *,
      87             :                     struct bioc_discipline *);
      88             : int             sr_crypto_meta_opt_handler(struct sr_discipline *,
      89             :                     struct sr_meta_opt_hdr *);
      90             : void            sr_crypto_write(struct cryptop *);
      91             : int             sr_crypto_rw(struct sr_workunit *);
      92             : int             sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *);
      93             : void            sr_crypto_done(struct sr_workunit *);
      94             : void            sr_crypto_read(struct cryptop *);
      95             : void            sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int,
      96             :                    u_int8_t *, int, u_char *);
      97             : void            sr_crypto_hotplug(struct sr_discipline *, struct disk *, int);
      98             : 
      99             : #ifdef SR_DEBUG0
     100             : void             sr_crypto_dumpkeys(struct sr_discipline *);
     101             : #endif
     102             : 
     103             : /* Discipline initialisation. */
     104             : void
     105           0 : sr_crypto_discipline_init(struct sr_discipline *sd)
     106             : {
     107             :         int i;
     108             : 
     109             :         /* Fill out discipline members. */
     110           0 :         sd->sd_type = SR_MD_CRYPTO;
     111           0 :         strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name));
     112           0 :         sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE;
     113           0 :         sd->sd_max_wu = SR_CRYPTO_NOWU;
     114             : 
     115           0 :         for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)
     116           0 :                 sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
     117             : 
     118             :         /* Setup discipline specific function pointers. */
     119           0 :         sd->sd_alloc_resources = sr_crypto_alloc_resources;
     120           0 :         sd->sd_assemble = sr_crypto_assemble;
     121           0 :         sd->sd_create = sr_crypto_create;
     122           0 :         sd->sd_free_resources = sr_crypto_free_resources;
     123           0 :         sd->sd_ioctl_handler = sr_crypto_ioctl;
     124           0 :         sd->sd_meta_opt_handler = sr_crypto_meta_opt_handler;
     125           0 :         sd->sd_scsi_rw = sr_crypto_rw;
     126           0 :         sd->sd_scsi_done = sr_crypto_done;
     127           0 : }
     128             : 
     129             : int
     130           0 : sr_crypto_create(struct sr_discipline *sd, struct bioc_createraid *bc,
     131             :     int no_chunk, int64_t coerced_size)
     132             : {
     133             :         struct sr_meta_opt_item *omi;
     134             :         int                     rv = EINVAL;
     135             : 
     136           0 :         if (no_chunk != 1) {
     137           0 :                 sr_error(sd->sd_sc, "%s requires exactly one chunk",
     138           0 :                     sd->sd_name);
     139           0 :                 goto done;
     140             :         }
     141             : 
     142           0 :         if (coerced_size > SR_CRYPTO_MAXSIZE) {
     143           0 :                 sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)",
     144           0 :                     sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE);
     145           0 :                 goto done;
     146             :         }
     147             : 
     148             :         /* Create crypto optional metadata. */
     149           0 :         omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF,
     150             :             M_WAITOK | M_ZERO);
     151           0 :         omi->omi_som = malloc(sizeof(struct sr_meta_crypto), M_DEVBUF,
     152             :             M_WAITOK | M_ZERO);
     153           0 :         omi->omi_som->som_type = SR_OPT_CRYPTO;
     154           0 :         omi->omi_som->som_length = sizeof(struct sr_meta_crypto);
     155           0 :         SLIST_INSERT_HEAD(&sd->sd_meta_opt, omi, omi_link);
     156           0 :         sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)omi->omi_som;
     157           0 :         sd->sd_meta->ssdi.ssd_opt_no++;
     158             : 
     159           0 :         sd->mds.mdd_crypto.key_disk = NULL;
     160             : 
     161           0 :         if (bc->bc_key_disk != NODEV) {
     162             : 
     163             :                 /* Create a key disk. */
     164           0 :                 if (sr_crypto_get_kdf(bc, sd))
     165             :                         goto done;
     166           0 :                 sd->mds.mdd_crypto.key_disk =
     167           0 :                     sr_crypto_create_key_disk(sd, bc->bc_key_disk);
     168           0 :                 if (sd->mds.mdd_crypto.key_disk == NULL)
     169             :                         goto done;
     170           0 :                 sd->sd_capabilities |= SR_CAP_AUTO_ASSEMBLE;
     171             : 
     172           0 :         } else if (bc->bc_opaque_flags & BIOC_SOOUT) {
     173             : 
     174             :                 /* No hint available yet. */
     175           0 :                 bc->bc_opaque_status = BIOC_SOINOUT_FAILED;
     176             :                 rv = EAGAIN;
     177           0 :                 goto done;
     178             : 
     179           0 :         } else if (sr_crypto_get_kdf(bc, sd))
     180             :                 goto done;
     181             : 
     182             :         /* Passphrase volumes cannot be automatically assembled. */
     183           0 :         if (!(bc->bc_flags & BIOC_SCNOAUTOASSEMBLE) && bc->bc_key_disk == NODEV)
     184             :                 goto done;
     185             : 
     186           0 :         sd->sd_meta->ssdi.ssd_size = coerced_size;
     187             : 
     188           0 :         sr_crypto_create_keys(sd);
     189             : 
     190           0 :         sd->sd_max_ccb_per_wu = no_chunk;
     191             : 
     192           0 :         rv = 0;
     193             : done:
     194           0 :         return (rv);
     195             : }
     196             : 
     197             : int
     198           0 : sr_crypto_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
     199             :     int no_chunk, void *data)
     200             : {
     201             :         int     rv = EINVAL;
     202             : 
     203           0 :         sd->mds.mdd_crypto.key_disk = NULL;
     204             : 
     205             :         /* Crypto optional metadata must already exist... */
     206           0 :         if (sd->mds.mdd_crypto.scr_meta == NULL)
     207             :                 goto done;
     208             : 
     209           0 :         if (data != NULL) {
     210             :                 /* Kernel already has mask key. */
     211           0 :                 memcpy(sd->mds.mdd_crypto.scr_maskkey, data,
     212             :                     sizeof(sd->mds.mdd_crypto.scr_maskkey));
     213           0 :         } else if (bc->bc_key_disk != NODEV) {
     214             :                 /* Read the mask key from the key disk. */
     215           0 :                 sd->mds.mdd_crypto.key_disk =
     216           0 :                     sr_crypto_read_key_disk(sd, bc->bc_key_disk);
     217           0 :                 if (sd->mds.mdd_crypto.key_disk == NULL)
     218             :                         goto done;
     219           0 :         } else if (bc->bc_opaque_flags & BIOC_SOOUT) {
     220             :                 /* provide userland with kdf hint */
     221           0 :                 if (bc->bc_opaque == NULL)
     222             :                         goto done;
     223             : 
     224           0 :                 if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) <
     225           0 :                     bc->bc_opaque_size)
     226             :                         goto done;
     227             : 
     228           0 :                 if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
     229             :                     bc->bc_opaque, bc->bc_opaque_size))
     230             :                         goto done;
     231             : 
     232             :                 /* we're done */
     233           0 :                 bc->bc_opaque_status = BIOC_SOINOUT_OK;
     234             :                 rv = EAGAIN;
     235           0 :                 goto done;
     236           0 :         } else if (bc->bc_opaque_flags & BIOC_SOIN) {
     237             :                 /* get kdf with maskkey from userland */
     238           0 :                 if (sr_crypto_get_kdf(bc, sd))
     239             :                         goto done;
     240             :         } else
     241             :                 goto done;
     242             : 
     243           0 :         sd->sd_max_ccb_per_wu = sd->sd_meta->ssdi.ssd_chunk_no;
     244             : 
     245           0 :         rv = 0;
     246             : done:
     247           0 :         return (rv);
     248             : }
     249             : 
     250             : struct sr_crypto_wu *
     251           0 : sr_crypto_prepare(struct sr_workunit *wu, int encrypt)
     252             : {
     253           0 :         struct scsi_xfer        *xs = wu->swu_xs;
     254           0 :         struct sr_discipline    *sd = wu->swu_dis;
     255             :         struct sr_crypto_wu     *crwu;
     256             :         struct cryptodesc       *crd;
     257             :         int                     flags, i, n;
     258             :         daddr_t                 blkno;
     259             :         u_int                   keyndx;
     260             : 
     261             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_prepare wu %p encrypt %d\n",
     262             :             DEVNAME(sd->sd_sc), wu, encrypt);
     263             : 
     264           0 :         crwu = (struct sr_crypto_wu *)wu;
     265           0 :         crwu->cr_uio.uio_iovcnt = 1;
     266           0 :         crwu->cr_uio.uio_iov->iov_len = xs->datalen;
     267           0 :         if (xs->flags & SCSI_DATA_OUT) {
     268           0 :                 crwu->cr_uio.uio_iov->iov_base = crwu->cr_dmabuf;
     269           0 :                 memcpy(crwu->cr_uio.uio_iov->iov_base, xs->data, xs->datalen);
     270           0 :         } else
     271           0 :                 crwu->cr_uio.uio_iov->iov_base = xs->data;
     272             : 
     273           0 :         blkno = wu->swu_blk_start;
     274           0 :         n = xs->datalen >> DEV_BSHIFT;
     275             : 
     276             :         /*
     277             :          * We preallocated enough crypto descs for up to MAXPHYS of I/O.
     278             :          * Since there may be less than that we need to tweak the amount
     279             :          * of crypto desc structures to be just long enough for our needs.
     280             :          */
     281           0 :         KASSERT(crwu->cr_crp->crp_ndescalloc >= n);
     282           0 :         crwu->cr_crp->crp_ndesc = n;
     283           0 :         flags = (encrypt ? CRD_F_ENCRYPT : 0) |
     284           0 :             CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
     285             : 
     286             :         /*
     287             :          * Select crypto session based on block number.
     288             :          *
     289             :          * XXX - this does not handle the case where the read/write spans
     290             :          * across a different key blocks (e.g. 0.5TB boundary). Currently
     291             :          * this is already broken by the use of scr_key[0] below.
     292             :          */
     293           0 :         keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT;
     294           0 :         crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx];
     295             : 
     296           0 :         crwu->cr_crp->crp_opaque = crwu;
     297           0 :         crwu->cr_crp->crp_ilen = xs->datalen;
     298           0 :         crwu->cr_crp->crp_alloctype = M_DEVBUF;
     299           0 :         crwu->cr_crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;
     300           0 :         crwu->cr_crp->crp_buf = &crwu->cr_uio;
     301           0 :         for (i = 0; i < crwu->cr_crp->crp_ndesc; i++, blkno++) {
     302           0 :                 crd = &crwu->cr_crp->crp_desc[i];
     303           0 :                 crd->crd_skip = i << DEV_BSHIFT;
     304           0 :                 crd->crd_len = DEV_BSIZE;
     305           0 :                 crd->crd_inject = 0;
     306           0 :                 crd->crd_flags = flags;
     307           0 :                 crd->crd_alg = sd->mds.mdd_crypto.scr_alg;
     308           0 :                 crd->crd_klen = sd->mds.mdd_crypto.scr_klen;
     309           0 :                 crd->crd_key = sd->mds.mdd_crypto.scr_key[0];
     310           0 :                 memcpy(crd->crd_iv, &blkno, sizeof(blkno));
     311             :         }
     312             : 
     313           0 :         return (crwu);
     314             : }
     315             : 
     316             : int
     317           0 : sr_crypto_get_kdf(struct bioc_createraid *bc, struct sr_discipline *sd)
     318             : {
     319             :         int                     rv = EINVAL;
     320             :         struct sr_crypto_kdfinfo *kdfinfo;
     321             : 
     322           0 :         if (!(bc->bc_opaque_flags & BIOC_SOIN))
     323           0 :                 return (rv);
     324           0 :         if (bc->bc_opaque == NULL)
     325           0 :                 return (rv);
     326           0 :         if (bc->bc_opaque_size != sizeof(*kdfinfo))
     327           0 :                 return (rv);
     328             : 
     329           0 :         kdfinfo = malloc(bc->bc_opaque_size, M_DEVBUF, M_WAITOK | M_ZERO);
     330           0 :         if (copyin(bc->bc_opaque, kdfinfo, bc->bc_opaque_size))
     331             :                 goto out;
     332             : 
     333           0 :         if (kdfinfo->len != bc->bc_opaque_size)
     334             :                 goto out;
     335             : 
     336             :         /* copy KDF hint to disk meta data */
     337           0 :         if (kdfinfo->flags & SR_CRYPTOKDF_HINT) {
     338           0 :                 if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) <
     339           0 :                     kdfinfo->genkdf.len)
     340             :                         goto out;
     341           0 :                 memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
     342             :                     &kdfinfo->genkdf, kdfinfo->genkdf.len);
     343           0 :         }
     344             : 
     345             :         /* copy mask key to run-time meta data */
     346           0 :         if ((kdfinfo->flags & SR_CRYPTOKDF_KEY)) {
     347             :                 if (sizeof(sd->mds.mdd_crypto.scr_maskkey) <
     348             :                     sizeof(kdfinfo->maskkey))
     349             :                         goto out;
     350           0 :                 memcpy(sd->mds.mdd_crypto.scr_maskkey, &kdfinfo->maskkey,
     351             :                     sizeof(kdfinfo->maskkey));
     352           0 :         }
     353             : 
     354           0 :         bc->bc_opaque_status = BIOC_SOINOUT_OK;
     355           0 :         rv = 0;
     356             : out:
     357           0 :         explicit_bzero(kdfinfo, bc->bc_opaque_size);
     358           0 :         free(kdfinfo, M_DEVBUF, bc->bc_opaque_size);
     359             : 
     360           0 :         return (rv);
     361           0 : }
     362             : 
     363             : int
     364           0 : sr_crypto_encrypt(u_char *p, u_char *c, u_char *key, size_t size, int alg)
     365             : {
     366           0 :         rijndael_ctx            ctx;
     367             :         int                     i, rv = 1;
     368             : 
     369           0 :         switch (alg) {
     370             :         case SR_CRYPTOM_AES_ECB_256:
     371           0 :                 if (rijndael_set_key_enc_only(&ctx, key, 256) != 0)
     372             :                         goto out;
     373           0 :                 for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN)
     374           0 :                         rijndael_encrypt(&ctx, &p[i], &c[i]);
     375             :                 rv = 0;
     376             :                 break;
     377             :         default:
     378             :                 DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n",
     379             :                     "softraid", alg);
     380             :                 rv = -1;
     381           0 :                 goto out;
     382           0 :         }
     383             : 
     384             : out:
     385           0 :         explicit_bzero(&ctx, sizeof(ctx));
     386           0 :         return (rv);
     387           0 : }
     388             : 
     389             : int
     390           0 : sr_crypto_decrypt(u_char *c, u_char *p, u_char *key, size_t size, int alg)
     391             : {
     392           0 :         rijndael_ctx            ctx;
     393             :         int                     i, rv = 1;
     394             : 
     395           0 :         switch (alg) {
     396             :         case SR_CRYPTOM_AES_ECB_256:
     397           0 :                 if (rijndael_set_key(&ctx, key, 256) != 0)
     398             :                         goto out;
     399           0 :                 for (i = 0; i < size; i += RIJNDAEL128_BLOCK_LEN)
     400           0 :                         rijndael_decrypt(&ctx, &c[i], &p[i]);
     401             :                 rv = 0;
     402             :                 break;
     403             :         default:
     404             :                 DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n",
     405             :                     "softraid", alg);
     406             :                 rv = -1;
     407           0 :                 goto out;
     408           0 :         }
     409             : 
     410             : out:
     411           0 :         explicit_bzero(&ctx, sizeof(ctx));
     412           0 :         return (rv);
     413           0 : }
     414             : 
     415             : void
     416           0 : sr_crypto_calculate_check_hmac_sha1(u_int8_t *maskkey, int maskkey_size,
     417             :     u_int8_t *key, int key_size, u_char *check_digest)
     418             : {
     419           0 :         u_char                  check_key[SHA1_DIGEST_LENGTH];
     420           0 :         HMAC_SHA1_CTX           hmacctx;
     421           0 :         SHA1_CTX                shactx;
     422             : 
     423           0 :         bzero(check_key, sizeof(check_key));
     424           0 :         bzero(&hmacctx, sizeof(hmacctx));
     425           0 :         bzero(&shactx, sizeof(shactx));
     426             : 
     427             :         /* k = SHA1(mask_key) */
     428           0 :         SHA1Init(&shactx);
     429           0 :         SHA1Update(&shactx, maskkey, maskkey_size);
     430           0 :         SHA1Final(check_key, &shactx);
     431             : 
     432             :         /* mac = HMAC_SHA1_k(unencrypted key) */
     433           0 :         HMAC_SHA1_Init(&hmacctx, check_key, sizeof(check_key));
     434           0 :         HMAC_SHA1_Update(&hmacctx, key, key_size);
     435           0 :         HMAC_SHA1_Final(check_digest, &hmacctx);
     436             : 
     437           0 :         explicit_bzero(check_key, sizeof(check_key));
     438           0 :         explicit_bzero(&hmacctx, sizeof(hmacctx));
     439           0 :         explicit_bzero(&shactx, sizeof(shactx));
     440           0 : }
     441             : 
     442             : int
     443           0 : sr_crypto_decrypt_key(struct sr_discipline *sd)
     444             : {
     445           0 :         u_char                  check_digest[SHA1_DIGEST_LENGTH];
     446             :         int                     rv = 1;
     447             : 
     448             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_decrypt_key\n", DEVNAME(sd->sd_sc));
     449             : 
     450           0 :         if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
     451             :                 goto out;
     452             : 
     453           0 :         if (sr_crypto_decrypt((u_char *)sd->mds.mdd_crypto.scr_meta->scm_key,
     454           0 :             (u_char *)sd->mds.mdd_crypto.scr_key,
     455           0 :             sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key),
     456           0 :             sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
     457             :                 goto out;
     458             : 
     459             : #ifdef SR_DEBUG0
     460             :         sr_crypto_dumpkeys(sd);
     461             : #endif
     462             : 
     463             :         /* Check that the key decrypted properly. */
     464           0 :         sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey,
     465             :             sizeof(sd->mds.mdd_crypto.scr_maskkey),
     466             :             (u_int8_t *)sd->mds.mdd_crypto.scr_key,
     467             :             sizeof(sd->mds.mdd_crypto.scr_key),
     468           0 :             check_digest);
     469           0 :         if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac,
     470           0 :             check_digest, sizeof(check_digest)) != 0) {
     471           0 :                 explicit_bzero(sd->mds.mdd_crypto.scr_key,
     472             :                     sizeof(sd->mds.mdd_crypto.scr_key));
     473           0 :                 goto out;
     474             :         }
     475             : 
     476           0 :         rv = 0; /* Success */
     477             : out:
     478             :         /* we don't need the mask key anymore */
     479           0 :         explicit_bzero(&sd->mds.mdd_crypto.scr_maskkey,
     480             :             sizeof(sd->mds.mdd_crypto.scr_maskkey));
     481             : 
     482           0 :         explicit_bzero(check_digest, sizeof(check_digest));
     483             : 
     484           0 :         return rv;
     485           0 : }
     486             : 
     487             : int
     488           0 : sr_crypto_create_keys(struct sr_discipline *sd)
     489             : {
     490             : 
     491             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_create_keys\n",
     492             :             DEVNAME(sd->sd_sc));
     493             : 
     494             :         if (AES_MAXKEYBYTES < sizeof(sd->mds.mdd_crypto.scr_maskkey))
     495             :                 return (1);
     496             : 
     497             :         /* XXX allow user to specify */
     498           0 :         sd->mds.mdd_crypto.scr_meta->scm_alg = SR_CRYPTOA_AES_XTS_256;
     499             : 
     500             :         /* generate crypto keys */
     501           0 :         arc4random_buf(sd->mds.mdd_crypto.scr_key,
     502             :             sizeof(sd->mds.mdd_crypto.scr_key));
     503             : 
     504             :         /* Mask the disk keys. */
     505           0 :         sd->mds.mdd_crypto.scr_meta->scm_mask_alg = SR_CRYPTOM_AES_ECB_256;
     506           0 :         sr_crypto_encrypt((u_char *)sd->mds.mdd_crypto.scr_key,
     507           0 :             (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key,
     508           0 :             sd->mds.mdd_crypto.scr_maskkey, sizeof(sd->mds.mdd_crypto.scr_key),
     509           0 :             sd->mds.mdd_crypto.scr_meta->scm_mask_alg);
     510             : 
     511             :         /* Prepare key decryption check code. */
     512           0 :         sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
     513           0 :         sr_crypto_calculate_check_hmac_sha1(sd->mds.mdd_crypto.scr_maskkey,
     514             :             sizeof(sd->mds.mdd_crypto.scr_maskkey),
     515             :             (u_int8_t *)sd->mds.mdd_crypto.scr_key,
     516             :             sizeof(sd->mds.mdd_crypto.scr_key),
     517           0 :             sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac);
     518             : 
     519             :         /* Erase the plaintext disk keys */
     520           0 :         explicit_bzero(sd->mds.mdd_crypto.scr_key,
     521             :             sizeof(sd->mds.mdd_crypto.scr_key));
     522             : 
     523             : #ifdef SR_DEBUG0
     524             :         sr_crypto_dumpkeys(sd);
     525             : #endif
     526             : 
     527           0 :         sd->mds.mdd_crypto.scr_meta->scm_flags = SR_CRYPTOF_KEY |
     528             :             SR_CRYPTOF_KDFHINT;
     529             : 
     530           0 :         return (0);
     531             : }
     532             : 
     533             : int
     534           0 : sr_crypto_change_maskkey(struct sr_discipline *sd,
     535             :   struct sr_crypto_kdfinfo *kdfinfo1, struct sr_crypto_kdfinfo *kdfinfo2)
     536             : {
     537           0 :         u_char                  check_digest[SHA1_DIGEST_LENGTH];
     538             :         u_char                  *c, *p = NULL;
     539             :         size_t                  ksz;
     540             :         int                     rv = 1;
     541             : 
     542             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_change_maskkey\n",
     543             :             DEVNAME(sd->sd_sc));
     544             : 
     545           0 :         if (sd->mds.mdd_crypto.scr_meta->scm_check_alg != SR_CRYPTOC_HMAC_SHA1)
     546             :                 goto out;
     547             : 
     548           0 :         c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key;
     549             :         ksz = sizeof(sd->mds.mdd_crypto.scr_key);
     550           0 :         p = malloc(ksz, M_DEVBUF, M_WAITOK | M_CANFAIL | M_ZERO);
     551           0 :         if (p == NULL)
     552             :                 goto out;
     553             : 
     554           0 :         if (sr_crypto_decrypt(c, p, kdfinfo1->maskkey, ksz,
     555           0 :             sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
     556             :                 goto out;
     557             : 
     558             : #ifdef SR_DEBUG0
     559             :         sr_crypto_dumpkeys(sd);
     560             : #endif
     561             : 
     562           0 :         sr_crypto_calculate_check_hmac_sha1(kdfinfo1->maskkey,
     563           0 :             sizeof(kdfinfo1->maskkey), p, ksz, check_digest);
     564           0 :         if (memcmp(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac,
     565           0 :             check_digest, sizeof(check_digest)) != 0) {
     566           0 :                 sr_error(sd->sd_sc, "incorrect key or passphrase");
     567             :                 rv = EPERM;
     568           0 :                 goto out;
     569             :         }
     570             : 
     571             :         /* Copy new KDF hint to metadata, if supplied. */
     572           0 :         if (kdfinfo2->flags & SR_CRYPTOKDF_HINT) {
     573           0 :                 if (kdfinfo2->genkdf.len >
     574             :                     sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint))
     575             :                         goto out;
     576           0 :                 explicit_bzero(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
     577             :                     sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint));
     578           0 :                 memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
     579             :                     &kdfinfo2->genkdf, kdfinfo2->genkdf.len);
     580           0 :         }
     581             : 
     582             :         /* Mask the disk keys. */
     583           0 :         c = (u_char *)sd->mds.mdd_crypto.scr_meta->scm_key;
     584           0 :         if (sr_crypto_encrypt(p, c, kdfinfo2->maskkey, ksz,
     585           0 :             sd->mds.mdd_crypto.scr_meta->scm_mask_alg) == -1)
     586             :                 goto out;
     587             : 
     588             :         /* Prepare key decryption check code. */
     589           0 :         sd->mds.mdd_crypto.scr_meta->scm_check_alg = SR_CRYPTOC_HMAC_SHA1;
     590           0 :         sr_crypto_calculate_check_hmac_sha1(kdfinfo2->maskkey,
     591           0 :             sizeof(kdfinfo2->maskkey), (u_int8_t *)sd->mds.mdd_crypto.scr_key,
     592             :             sizeof(sd->mds.mdd_crypto.scr_key), check_digest);
     593             : 
     594             :         /* Copy new encrypted key and HMAC to metadata. */
     595           0 :         memcpy(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, check_digest,
     596             :             sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac));
     597             : 
     598           0 :         rv = 0; /* Success */
     599             : 
     600             : out:
     601           0 :         if (p) {
     602           0 :                 explicit_bzero(p, ksz);
     603           0 :                 free(p, M_DEVBUF, ksz);
     604           0 :         }
     605             : 
     606           0 :         explicit_bzero(check_digest, sizeof(check_digest));
     607           0 :         explicit_bzero(&kdfinfo1->maskkey, sizeof(kdfinfo1->maskkey));
     608           0 :         explicit_bzero(&kdfinfo2->maskkey, sizeof(kdfinfo2->maskkey));
     609             : 
     610           0 :         return (rv);
     611           0 : }
     612             : 
     613             : struct sr_chunk *
     614           0 : sr_crypto_create_key_disk(struct sr_discipline *sd, dev_t dev)
     615             : {
     616           0 :         struct sr_softc         *sc = sd->sd_sc;
     617             :         struct sr_discipline    *fakesd = NULL;
     618             :         struct sr_metadata      *sm = NULL;
     619             :         struct sr_meta_chunk    *km;
     620             :         struct sr_meta_opt_item *omi = NULL;
     621             :         struct sr_meta_keydisk  *skm;
     622             :         struct sr_chunk         *key_disk = NULL;
     623           0 :         struct disklabel        label;
     624           0 :         struct vnode            *vn;
     625           0 :         char                    devname[32];
     626             :         int                     c, part, open = 0;
     627             : 
     628             :         /*
     629             :          * Create a metadata structure on the key disk and store
     630             :          * keying material in the optional metadata.
     631             :          */
     632             : 
     633           0 :         sr_meta_getdevname(sc, dev, devname, sizeof(devname));
     634             : 
     635             :         /* Make sure chunk is not already in use. */
     636           0 :         c = sr_chunk_in_use(sc, dev);
     637           0 :         if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) {
     638           0 :                 sr_error(sc, "%s is already in use", devname);
     639           0 :                 goto done;
     640             :         }
     641             : 
     642             :         /* Open device. */
     643           0 :         if (bdevvp(dev, &vn)) {
     644           0 :                 sr_error(sc, "cannot open key disk %s", devname);
     645           0 :                 goto done;
     646             :         }
     647           0 :         if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) {
     648             :                 DNPRINTF(SR_D_META,"%s: sr_crypto_create_key_disk cannot "
     649             :                     "open %s\n", DEVNAME(sc), devname);
     650           0 :                 vput(vn);
     651           0 :                 goto done;
     652             :         }
     653             :         open = 1; /* close dev on error */
     654             : 
     655             :         /* Get partition details. */
     656           0 :         part = DISKPART(dev);
     657           0 :         if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label,
     658           0 :             FREAD, NOCRED, curproc)) {
     659             :                 DNPRINTF(SR_D_META, "%s: sr_crypto_create_key_disk ioctl "
     660             :                     "failed\n", DEVNAME(sc));
     661             :                 goto done;
     662             :         }
     663           0 :         if (label.d_partitions[part].p_fstype != FS_RAID) {
     664           0 :                 sr_error(sc, "%s partition not of type RAID (%d)",
     665             :                     devname, label.d_partitions[part].p_fstype);
     666           0 :                 goto done;
     667             :         }
     668             : 
     669             :         /*
     670             :          * Create and populate chunk metadata.
     671             :          */
     672             : 
     673           0 :         key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO);
     674           0 :         km = &key_disk->src_meta;
     675             : 
     676           0 :         key_disk->src_dev_mm = dev;
     677           0 :         key_disk->src_vn = vn;
     678           0 :         strlcpy(key_disk->src_devname, devname, sizeof(km->scmi.scm_devname));
     679           0 :         key_disk->src_size = 0;
     680             : 
     681           0 :         km->scmi.scm_volid = sd->sd_meta->ssdi.ssd_level;
     682           0 :         km->scmi.scm_chunk_id = 0;
     683           0 :         km->scmi.scm_size = 0;
     684           0 :         km->scmi.scm_coerced_size = 0;
     685           0 :         strlcpy(km->scmi.scm_devname, devname, sizeof(km->scmi.scm_devname));
     686           0 :         memcpy(&km->scmi.scm_uuid, &sd->sd_meta->ssdi.ssd_uuid,
     687             :             sizeof(struct sr_uuid));
     688             : 
     689           0 :         sr_checksum(sc, km, &km->scm_checksum,
     690             :             sizeof(struct sr_meta_chunk_invariant));
     691             : 
     692           0 :         km->scm_status = BIOC_SDONLINE;
     693             : 
     694             :         /*
     695             :          * Create and populate our own discipline and metadata.
     696             :          */
     697             : 
     698           0 :         sm = malloc(sizeof(struct sr_metadata), M_DEVBUF, M_WAITOK | M_ZERO);
     699           0 :         sm->ssdi.ssd_magic = SR_MAGIC;
     700           0 :         sm->ssdi.ssd_version = SR_META_VERSION;
     701           0 :         sm->ssd_ondisk = 0;
     702           0 :         sm->ssdi.ssd_vol_flags = 0;
     703           0 :         memcpy(&sm->ssdi.ssd_uuid, &sd->sd_meta->ssdi.ssd_uuid,
     704             :             sizeof(struct sr_uuid));
     705           0 :         sm->ssdi.ssd_chunk_no = 1;
     706           0 :         sm->ssdi.ssd_volid = SR_KEYDISK_VOLID;
     707           0 :         sm->ssdi.ssd_level = SR_KEYDISK_LEVEL;
     708           0 :         sm->ssdi.ssd_size = 0;
     709           0 :         strlcpy(sm->ssdi.ssd_vendor, "OPENBSD", sizeof(sm->ssdi.ssd_vendor));
     710           0 :         snprintf(sm->ssdi.ssd_product, sizeof(sm->ssdi.ssd_product),
     711             :             "SR %s", "KEYDISK");
     712           0 :         snprintf(sm->ssdi.ssd_revision, sizeof(sm->ssdi.ssd_revision),
     713             :             "%03d", SR_META_VERSION);
     714             : 
     715           0 :         fakesd = malloc(sizeof(struct sr_discipline), M_DEVBUF,
     716             :             M_WAITOK | M_ZERO);
     717           0 :         fakesd->sd_sc = sd->sd_sc;
     718           0 :         fakesd->sd_meta = sm;
     719           0 :         fakesd->sd_meta_type = SR_META_F_NATIVE;
     720           0 :         fakesd->sd_vol_status = BIOC_SVONLINE;
     721           0 :         strlcpy(fakesd->sd_name, "KEYDISK", sizeof(fakesd->sd_name));
     722           0 :         SLIST_INIT(&fakesd->sd_meta_opt);
     723             : 
     724             :         /* Add chunk to volume. */
     725           0 :         fakesd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *), M_DEVBUF,
     726             :             M_WAITOK | M_ZERO);
     727           0 :         fakesd->sd_vol.sv_chunks[0] = key_disk;
     728           0 :         SLIST_INIT(&fakesd->sd_vol.sv_chunk_list);
     729           0 :         SLIST_INSERT_HEAD(&fakesd->sd_vol.sv_chunk_list, key_disk, src_link);
     730             : 
     731             :         /* Generate mask key. */
     732           0 :         arc4random_buf(sd->mds.mdd_crypto.scr_maskkey,
     733             :             sizeof(sd->mds.mdd_crypto.scr_maskkey));
     734             : 
     735             :         /* Copy mask key to optional metadata area. */
     736           0 :         omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF,
     737             :             M_WAITOK | M_ZERO);
     738           0 :         omi->omi_som = malloc(sizeof(struct sr_meta_keydisk), M_DEVBUF,
     739             :             M_WAITOK | M_ZERO);
     740           0 :         omi->omi_som->som_type = SR_OPT_KEYDISK;
     741           0 :         omi->omi_som->som_length = sizeof(struct sr_meta_keydisk);
     742           0 :         skm = (struct sr_meta_keydisk *)omi->omi_som;
     743           0 :         memcpy(&skm->skm_maskkey, sd->mds.mdd_crypto.scr_maskkey,
     744             :             sizeof(skm->skm_maskkey));
     745           0 :         SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link);
     746           0 :         fakesd->sd_meta->ssdi.ssd_opt_no++;
     747             : 
     748             :         /* Save metadata. */
     749           0 :         if (sr_meta_save(fakesd, SR_META_DIRTY)) {
     750           0 :                 sr_error(sc, "could not save metadata to %s", devname);
     751             :                 goto fail;
     752             :         }
     753             : 
     754             :         goto done;
     755             : 
     756             : fail:
     757           0 :         free(key_disk, M_DEVBUF, sizeof(struct sr_chunk));
     758           0 :         key_disk = NULL;
     759             : 
     760             : done:
     761           0 :         free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item));
     762           0 :         if (fakesd && fakesd->sd_vol.sv_chunks)
     763           0 :                 free(fakesd->sd_vol.sv_chunks, M_DEVBUF,
     764             :                     sizeof(struct sr_chunk *));
     765           0 :         free(fakesd, M_DEVBUF, sizeof(struct sr_discipline));
     766           0 :         free(sm, M_DEVBUF, sizeof(struct sr_metadata));
     767           0 :         if (open) {
     768           0 :                 VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc);
     769           0 :                 vput(vn);
     770           0 :         }
     771             : 
     772           0 :         return key_disk;
     773           0 : }
     774             : 
     775             : struct sr_chunk *
     776           0 : sr_crypto_read_key_disk(struct sr_discipline *sd, dev_t dev)
     777             : {
     778           0 :         struct sr_softc         *sc = sd->sd_sc;
     779             :         struct sr_metadata      *sm = NULL;
     780             :         struct sr_meta_opt_item *omi, *omi_next;
     781             :         struct sr_meta_opt_hdr  *omh;
     782             :         struct sr_meta_keydisk  *skm;
     783           0 :         struct sr_meta_opt_head som;
     784             :         struct sr_chunk         *key_disk = NULL;
     785           0 :         struct disklabel        label;
     786           0 :         struct vnode            *vn = NULL;
     787           0 :         char                    devname[32];
     788             :         int                     c, part, open = 0;
     789             : 
     790             :         /*
     791             :          * Load a key disk and load keying material into memory.
     792             :          */
     793             : 
     794           0 :         SLIST_INIT(&som);
     795             : 
     796           0 :         sr_meta_getdevname(sc, dev, devname, sizeof(devname));
     797             : 
     798             :         /* Make sure chunk is not already in use. */
     799           0 :         c = sr_chunk_in_use(sc, dev);
     800           0 :         if (c != BIOC_SDINVALID && c != BIOC_SDOFFLINE) {
     801           0 :                 sr_error(sc, "%s is already in use", devname);
     802           0 :                 goto done;
     803             :         }
     804             : 
     805             :         /* Open device. */
     806           0 :         if (bdevvp(dev, &vn)) {
     807           0 :                 sr_error(sc, "cannot open key disk %s", devname);
     808           0 :                 goto done;
     809             :         }
     810           0 :         if (VOP_OPEN(vn, FREAD, NOCRED, curproc)) {
     811             :                 DNPRINTF(SR_D_META,"%s: sr_crypto_read_key_disk cannot "
     812             :                     "open %s\n", DEVNAME(sc), devname);
     813           0 :                 vput(vn);
     814           0 :                 goto done;
     815             :         }
     816             :         open = 1; /* close dev on error */
     817             : 
     818             :         /* Get partition details. */
     819           0 :         part = DISKPART(dev);
     820           0 :         if (VOP_IOCTL(vn, DIOCGDINFO, (caddr_t)&label, FREAD,
     821           0 :             NOCRED, curproc)) {
     822             :                 DNPRINTF(SR_D_META, "%s: sr_crypto_read_key_disk ioctl "
     823             :                     "failed\n", DEVNAME(sc));
     824             :                 goto done;
     825             :         }
     826           0 :         if (label.d_partitions[part].p_fstype != FS_RAID) {
     827           0 :                 sr_error(sc, "%s partition not of type RAID (%d)",
     828             :                     devname, label.d_partitions[part].p_fstype);
     829           0 :                 goto done;
     830             :         }
     831             : 
     832             :         /*
     833             :          * Read and validate key disk metadata.
     834             :          */
     835           0 :         sm = malloc(SR_META_SIZE * DEV_BSIZE, M_DEVBUF, M_WAITOK | M_ZERO);
     836           0 :         if (sr_meta_native_read(sd, dev, sm, NULL)) {
     837           0 :                 sr_error(sc, "native bootprobe could not read native metadata");
     838           0 :                 goto done;
     839             :         }
     840             : 
     841           0 :         if (sr_meta_validate(sd, dev, sm, NULL)) {
     842             :                 DNPRINTF(SR_D_META, "%s: invalid metadata\n",
     843             :                     DEVNAME(sc));
     844             :                 goto done;
     845             :         }
     846             : 
     847             :         /* Make sure this is a key disk. */
     848           0 :         if (sm->ssdi.ssd_level != SR_KEYDISK_LEVEL) {
     849           0 :                 sr_error(sc, "%s is not a key disk", devname);
     850           0 :                 goto done;
     851             :         }
     852             : 
     853             :         /* Construct key disk chunk. */
     854           0 :         key_disk = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK | M_ZERO);
     855           0 :         key_disk->src_dev_mm = dev;
     856           0 :         key_disk->src_vn = vn;
     857           0 :         key_disk->src_size = 0;
     858             : 
     859           0 :         memcpy(&key_disk->src_meta, (struct sr_meta_chunk *)(sm + 1),
     860             :             sizeof(key_disk->src_meta));
     861             : 
     862             :         /* Read mask key from optional metadata. */
     863           0 :         sr_meta_opt_load(sc, sm, &som);
     864           0 :         SLIST_FOREACH(omi, &som, omi_link) {
     865           0 :                 omh = omi->omi_som;
     866           0 :                 if (omh->som_type == SR_OPT_KEYDISK) {
     867           0 :                         skm = (struct sr_meta_keydisk *)omh;
     868           0 :                         memcpy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey,
     869             :                             sizeof(sd->mds.mdd_crypto.scr_maskkey));
     870           0 :                 } else if (omh->som_type == SR_OPT_CRYPTO) {
     871             :                         /* Original keydisk format with key in crypto area. */
     872           0 :                         memcpy(sd->mds.mdd_crypto.scr_maskkey,
     873             :                             omh + sizeof(struct sr_meta_opt_hdr),
     874             :                             sizeof(sd->mds.mdd_crypto.scr_maskkey));
     875           0 :                 }
     876             :         }
     877             : 
     878           0 :         open = 0;
     879             : 
     880             : done:
     881           0 :         for (omi = SLIST_FIRST(&som); omi != NULL; omi = omi_next) {
     882           0 :                 omi_next = SLIST_NEXT(omi, omi_link);
     883           0 :                 free(omi->omi_som, M_DEVBUF, 0);
     884           0 :                 free(omi, M_DEVBUF, 0);
     885             :         }
     886             : 
     887           0 :         free(sm, M_DEVBUF, SR_META_SIZE * DEV_BSIZE);
     888             : 
     889           0 :         if (vn && open) {
     890           0 :                 VOP_CLOSE(vn, FREAD, NOCRED, curproc);
     891           0 :                 vput(vn);
     892           0 :         }
     893             : 
     894           0 :         return key_disk;
     895           0 : }
     896             : 
     897             : static void
     898           0 : sr_crypto_free_sessions(struct sr_discipline *sd)
     899             : {
     900             :         u_int                   i;
     901             : 
     902           0 :         for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
     903           0 :                 if (sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1) {
     904           0 :                         crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]);
     905           0 :                         sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
     906           0 :                 }
     907             :         }
     908           0 : }
     909             : 
     910             : int
     911           0 : sr_crypto_alloc_resources(struct sr_discipline *sd)
     912             : {
     913             :         struct sr_workunit      *wu;
     914             :         struct sr_crypto_wu     *crwu;
     915           0 :         struct cryptoini        cri;
     916             :         u_int                   num_keys, i;
     917             : 
     918             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n",
     919             :             DEVNAME(sd->sd_sc));
     920             : 
     921           0 :         sd->mds.mdd_crypto.scr_alg = CRYPTO_AES_XTS;
     922           0 :         switch (sd->mds.mdd_crypto.scr_meta->scm_alg) {
     923             :         case SR_CRYPTOA_AES_XTS_128:
     924           0 :                 sd->mds.mdd_crypto.scr_klen = 256;
     925           0 :                 break;
     926             :         case SR_CRYPTOA_AES_XTS_256:
     927           0 :                 sd->mds.mdd_crypto.scr_klen = 512;
     928           0 :                 break;
     929             :         default:
     930           0 :                 sr_error(sd->sd_sc, "unknown crypto algorithm");
     931           0 :                 return (EINVAL);
     932             :         }
     933             : 
     934           0 :         for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)
     935           0 :                 sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;
     936             : 
     937           0 :         if (sr_wu_alloc(sd, sizeof(struct sr_crypto_wu))) {
     938           0 :                 sr_error(sd->sd_sc, "unable to allocate work units");
     939           0 :                 return (ENOMEM);
     940             :         }
     941           0 :         if (sr_ccb_alloc(sd)) {
     942           0 :                 sr_error(sd->sd_sc, "unable to allocate CCBs");
     943           0 :                 return (ENOMEM);
     944             :         }
     945           0 :         if (sr_crypto_decrypt_key(sd)) {
     946           0 :                 sr_error(sd->sd_sc, "incorrect key or passphrase");
     947           0 :                 return (EPERM);
     948             :         }
     949             : 
     950             :         /*
     951             :          * For each work unit allocate the uio, iovec and crypto structures.
     952             :          * These have to be allocated now because during runtime we cannot
     953             :          * fail an allocation without failing the I/O (which can cause real
     954             :          * problems).
     955             :          */
     956           0 :         TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) {
     957           0 :                 crwu = (struct sr_crypto_wu *)wu;
     958           0 :                 crwu->cr_uio.uio_iov = &crwu->cr_iov;
     959           0 :                 crwu->cr_dmabuf = dma_alloc(MAXPHYS, PR_WAITOK);
     960           0 :                 crwu->cr_crp = crypto_getreq(MAXPHYS >> DEV_BSHIFT);
     961           0 :                 if (crwu->cr_crp == NULL)
     962           0 :                         return (ENOMEM);
     963             :         }
     964             : 
     965           0 :         memset(&cri, 0, sizeof(cri));
     966           0 :         cri.cri_alg = sd->mds.mdd_crypto.scr_alg;
     967           0 :         cri.cri_klen = sd->mds.mdd_crypto.scr_klen;
     968             : 
     969             :         /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */
     970           0 :         num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >>
     971           0 :             SR_CRYPTO_KEY_BLKSHIFT) + 1;
     972           0 :         if (num_keys > SR_CRYPTO_MAXKEYS)
     973           0 :                 return (EFBIG);
     974           0 :         for (i = 0; i < num_keys; i++) {
     975           0 :                 cri.cri_key = sd->mds.mdd_crypto.scr_key[i];
     976           0 :                 if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i],
     977           0 :                     &cri, 0) != 0) {
     978           0 :                         sr_crypto_free_sessions(sd);
     979           0 :                         return (EINVAL);
     980             :                 }
     981             :         }
     982             : 
     983           0 :         sr_hotplug_register(sd, sr_crypto_hotplug);
     984             : 
     985           0 :         return (0);
     986           0 : }
     987             : 
     988             : void
     989           0 : sr_crypto_free_resources(struct sr_discipline *sd)
     990             : {
     991             :         struct sr_workunit      *wu;
     992             :         struct sr_crypto_wu     *crwu;
     993             : 
     994             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n",
     995             :             DEVNAME(sd->sd_sc));
     996             : 
     997           0 :         if (sd->mds.mdd_crypto.key_disk != NULL) {
     998           0 :                 explicit_bzero(sd->mds.mdd_crypto.key_disk,
     999             :                     sizeof(*sd->mds.mdd_crypto.key_disk));
    1000           0 :                 free(sd->mds.mdd_crypto.key_disk, M_DEVBUF,
    1001             :                     sizeof(*sd->mds.mdd_crypto.key_disk));
    1002           0 :         }
    1003             : 
    1004           0 :         sr_hotplug_unregister(sd, sr_crypto_hotplug);
    1005             : 
    1006           0 :         sr_crypto_free_sessions(sd);
    1007             : 
    1008           0 :         TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) {
    1009           0 :                 crwu = (struct sr_crypto_wu *)wu;
    1010           0 :                 if (crwu->cr_dmabuf)
    1011           0 :                         dma_free(crwu->cr_dmabuf, MAXPHYS);
    1012           0 :                 if (crwu->cr_crp)
    1013           0 :                         crypto_freereq(crwu->cr_crp);
    1014             :         }
    1015             : 
    1016           0 :         sr_wu_free(sd);
    1017           0 :         sr_ccb_free(sd);
    1018           0 : }
    1019             : 
    1020             : int
    1021           0 : sr_crypto_ioctl(struct sr_discipline *sd, struct bioc_discipline *bd)
    1022             : {
    1023           0 :         struct sr_crypto_kdfpair kdfpair;
    1024           0 :         struct sr_crypto_kdfinfo kdfinfo1, kdfinfo2;
    1025             :         int                     size, rv = 1;
    1026             : 
    1027             :         DNPRINTF(SR_D_IOCTL, "%s: sr_crypto_ioctl %u\n",
    1028             :             DEVNAME(sd->sd_sc), bd->bd_cmd);
    1029             : 
    1030           0 :         switch (bd->bd_cmd) {
    1031             :         case SR_IOCTL_GET_KDFHINT:
    1032             : 
    1033             :                 /* Get KDF hint for userland. */
    1034             :                 size = sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint);
    1035           0 :                 if (bd->bd_data == NULL || bd->bd_size > size)
    1036             :                         goto bad;
    1037           0 :                 if (copyout(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,
    1038           0 :                     bd->bd_data, bd->bd_size))
    1039             :                         goto bad;
    1040             : 
    1041             :                 rv = 0;
    1042             : 
    1043           0 :                 break;
    1044             : 
    1045             :         case SR_IOCTL_CHANGE_PASSPHRASE:
    1046             : 
    1047             :                 /* Attempt to change passphrase. */
    1048             : 
    1049             :                 size = sizeof(kdfpair);
    1050           0 :                 if (bd->bd_data == NULL || bd->bd_size > size)
    1051             :                         goto bad;
    1052           0 :                 if (copyin(bd->bd_data, &kdfpair, size))
    1053             :                         goto bad;
    1054             : 
    1055             :                 size = sizeof(kdfinfo1);
    1056           0 :                 if (kdfpair.kdfinfo1 == NULL || kdfpair.kdfsize1 > size)
    1057             :                         goto bad;
    1058           0 :                 if (copyin(kdfpair.kdfinfo1, &kdfinfo1, size))
    1059             :                         goto bad;
    1060             : 
    1061             :                 size = sizeof(kdfinfo2);
    1062           0 :                 if (kdfpair.kdfinfo2 == NULL || kdfpair.kdfsize2 > size)
    1063             :                         goto bad;
    1064           0 :                 if (copyin(kdfpair.kdfinfo2, &kdfinfo2, size))
    1065             :                         goto bad;
    1066             : 
    1067           0 :                 if (sr_crypto_change_maskkey(sd, &kdfinfo1, &kdfinfo2))
    1068             :                         goto bad;
    1069             : 
    1070             :                 /* Save metadata to disk. */
    1071           0 :                 rv = sr_meta_save(sd, SR_META_DIRTY);
    1072             : 
    1073           0 :                 break;
    1074             :         }
    1075             : 
    1076             : bad:
    1077           0 :         explicit_bzero(&kdfpair, sizeof(kdfpair));
    1078           0 :         explicit_bzero(&kdfinfo1, sizeof(kdfinfo1));
    1079           0 :         explicit_bzero(&kdfinfo2, sizeof(kdfinfo2));
    1080             : 
    1081           0 :         return (rv);
    1082           0 : }
    1083             : 
    1084             : int
    1085           0 : sr_crypto_meta_opt_handler(struct sr_discipline *sd, struct sr_meta_opt_hdr *om)
    1086             : {
    1087             :         int rv = EINVAL;
    1088             : 
    1089           0 :         if (om->som_type == SR_OPT_CRYPTO) {
    1090           0 :                 sd->mds.mdd_crypto.scr_meta = (struct sr_meta_crypto *)om;
    1091             :                 rv = 0;
    1092           0 :         }
    1093             : 
    1094           0 :         return (rv);
    1095             : }
    1096             : 
    1097             : int
    1098           0 : sr_crypto_rw(struct sr_workunit *wu)
    1099             : {
    1100             :         struct sr_crypto_wu     *crwu;
    1101           0 :         daddr_t                 blkno;
    1102             :         int                     rv = 0;
    1103             : 
    1104             :         DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu %p\n",
    1105             :             DEVNAME(wu->swu_dis->sd_sc), wu);
    1106             : 
    1107           0 :         if (sr_validate_io(wu, &blkno, "sr_crypto_rw"))
    1108           0 :                 return (1);
    1109             : 
    1110           0 :         if (wu->swu_xs->flags & SCSI_DATA_OUT) {
    1111           0 :                 crwu = sr_crypto_prepare(wu, 1);
    1112           0 :                 crwu->cr_crp->crp_callback = sr_crypto_write;
    1113           0 :                 rv = crypto_dispatch(crwu->cr_crp);
    1114           0 :                 if (rv == 0)
    1115           0 :                         rv = crwu->cr_crp->crp_etype;
    1116             :         } else
    1117           0 :                 rv = sr_crypto_dev_rw(wu, NULL);
    1118             : 
    1119           0 :         return (rv);
    1120           0 : }
    1121             : 
    1122             : void
    1123           0 : sr_crypto_write(struct cryptop *crp)
    1124             : {
    1125           0 :         struct sr_crypto_wu     *crwu = crp->crp_opaque;
    1126           0 :         struct sr_workunit      *wu = &crwu->cr_wu;
    1127             :         int                     s;
    1128             : 
    1129             :         DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %p xs: %p\n",
    1130             :             DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs);
    1131             : 
    1132           0 :         if (crp->crp_etype) {
    1133             :                 /* fail io */
    1134           0 :                 wu->swu_xs->error = XS_DRIVER_STUFFUP;
    1135           0 :                 s = splbio();
    1136           0 :                 sr_scsi_done(wu->swu_dis, wu->swu_xs);
    1137           0 :                 splx(s);
    1138           0 :         }
    1139             : 
    1140           0 :         sr_crypto_dev_rw(wu, crwu);
    1141           0 : }
    1142             : 
    1143             : int
    1144           0 : sr_crypto_dev_rw(struct sr_workunit *wu, struct sr_crypto_wu *crwu)
    1145             : {
    1146           0 :         struct sr_discipline    *sd = wu->swu_dis;
    1147           0 :         struct scsi_xfer        *xs = wu->swu_xs;
    1148             :         struct sr_ccb           *ccb;
    1149             :         struct uio              *uio;
    1150             :         daddr_t                 blkno;
    1151             : 
    1152           0 :         blkno = wu->swu_blk_start;
    1153             : 
    1154           0 :         ccb = sr_ccb_rw(sd, 0, blkno, xs->datalen, xs->data, xs->flags, 0);
    1155           0 :         if (!ccb) {
    1156             :                 /* should never happen but handle more gracefully */
    1157           0 :                 printf("%s: %s: too many ccbs queued\n",
    1158           0 :                     DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname);
    1159             :                 goto bad;
    1160             :         }
    1161           0 :         if (!ISSET(xs->flags, SCSI_DATA_IN)) {
    1162           0 :                 uio = crwu->cr_crp->crp_buf;
    1163           0 :                 ccb->ccb_buf.b_data = uio->uio_iov->iov_base;
    1164           0 :                 ccb->ccb_opaque = crwu;
    1165           0 :         }
    1166           0 :         sr_wu_enqueue_ccb(wu, ccb);
    1167           0 :         sr_schedule_wu(wu);
    1168             : 
    1169           0 :         return (0);
    1170             : 
    1171             : bad:
    1172             :         /* wu is unwound by sr_wu_put */
    1173           0 :         if (crwu)
    1174           0 :                 crwu->cr_crp->crp_etype = EINVAL;
    1175           0 :         return (1);
    1176           0 : }
    1177             : 
    1178             : void
    1179           0 : sr_crypto_done(struct sr_workunit *wu)
    1180             : {
    1181           0 :         struct scsi_xfer        *xs = wu->swu_xs;
    1182             :         struct sr_crypto_wu     *crwu;
    1183             :         int                     s;
    1184             : 
    1185             :         /* If this was a successful read, initiate decryption of the data. */
    1186           0 :         if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) {
    1187           0 :                 crwu = sr_crypto_prepare(wu, 0);
    1188           0 :                 crwu->cr_crp->crp_callback = sr_crypto_read;
    1189             :                 DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n",
    1190             :                     DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp);
    1191           0 :                 crypto_dispatch(crwu->cr_crp);
    1192           0 :                 return;
    1193             :         }
    1194             : 
    1195           0 :         s = splbio();
    1196           0 :         sr_scsi_done(wu->swu_dis, wu->swu_xs);
    1197           0 :         splx(s);
    1198           0 : }
    1199             : 
    1200             : void
    1201           0 : sr_crypto_read(struct cryptop *crp)
    1202             : {
    1203           0 :         struct sr_crypto_wu     *crwu = crp->crp_opaque;
    1204           0 :         struct sr_workunit      *wu = &crwu->cr_wu;
    1205             :         int                     s;
    1206             : 
    1207             :         DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %p xs: %p\n",
    1208             :             DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs);
    1209             : 
    1210           0 :         if (crp->crp_etype)
    1211           0 :                 wu->swu_xs->error = XS_DRIVER_STUFFUP;
    1212             : 
    1213           0 :         s = splbio();
    1214           0 :         sr_scsi_done(wu->swu_dis, wu->swu_xs);
    1215           0 :         splx(s);
    1216           0 : }
    1217             : 
    1218             : void
    1219           0 : sr_crypto_hotplug(struct sr_discipline *sd, struct disk *diskp, int action)
    1220             : {
    1221             :         DNPRINTF(SR_D_MISC, "%s: sr_crypto_hotplug: %s %d\n",
    1222             :             DEVNAME(sd->sd_sc), diskp->dk_name, action);
    1223           0 : }
    1224             : 
    1225             : #ifdef SR_DEBUG0
    1226             : void
    1227             : sr_crypto_dumpkeys(struct sr_discipline *sd)
    1228             : {
    1229             :         int                     i, j;
    1230             : 
    1231             :         printf("sr_crypto_dumpkeys:\n");
    1232             :         for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
    1233             :                 printf("\tscm_key[%d]: 0x", i);
    1234             :                 for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) {
    1235             :                         printf("%02x",
    1236             :                             sd->mds.mdd_crypto.scr_meta->scm_key[i][j]);
    1237             :                 }
    1238             :                 printf("\n");
    1239             :         }
    1240             :         printf("sr_crypto_dumpkeys: runtime data keys:\n");
    1241             :         for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {
    1242             :                 printf("\tscr_key[%d]: 0x", i);
    1243             :                 for (j = 0; j < SR_CRYPTO_KEYBYTES; j++) {
    1244             :                         printf("%02x",
    1245             :                             sd->mds.mdd_crypto.scr_key[i][j]);
    1246             :                 }
    1247             :                 printf("\n");
    1248             :         }
    1249             : }
    1250             : #endif  /* SR_DEBUG */

Generated by: LCOV version 1.13