Path: blob/main/contrib/libdiff/test/expect021.diff
35083 views
--- test021.left.txt1+++ test021.right.txt2@@ -1,4 +1,4 @@3-/* $OpenBSD: softraid_crypto.c,v 1.91 2013/03/31 15:44:52 jsing Exp $ */4+/* $OpenBSD: softraid_crypto.c,v 1.139 2020/07/13 00:06:22 kn Exp $ */5/*6* Copyright (c) 2007 Marco Peereboom <[email protected]>7* Copyright (c) 2008 Hans-Joerg Hoexer <[email protected]>8@@ -25,7 +25,6 @@9#include <sys/buf.h>10#include <sys/device.h>11#include <sys/ioctl.h>12-#include <sys/proc.h>13#include <sys/malloc.h>14#include <sys/pool.h>15#include <sys/kernel.h>16@@ -34,6 +33,7 @@17#include <sys/queue.h>18#include <sys/fcntl.h>19#include <sys/disklabel.h>20+#include <sys/vnode.h>21#include <sys/mount.h>22#include <sys/sensors.h>23#include <sys/stat.h>24@@ -42,7 +42,6 @@25#include <sys/dkio.h>2627#include <crypto/cryptodev.h>28-#include <crypto/cryptosoft.h>29#include <crypto/rijndael.h>30#include <crypto/md5.h>31#include <crypto/sha1.h>32@@ -54,7 +53,6 @@33#include <scsi/scsi_disk.h>3435#include <dev/softraidvar.h>36-#include <dev/rndvar.h>3738/*39* The per-I/O data that we need to preallocate. We cannot afford to allow I/O40@@ -62,18 +60,15 @@41* because we assert that only one ccb per WU will ever be active.42*/43struct sr_crypto_wu {44- TAILQ_ENTRY(sr_crypto_wu) cr_link;45+ struct sr_workunit cr_wu; /* Must be first. */46struct uio cr_uio;47struct iovec cr_iov;48struct cryptop *cr_crp;49- struct cryptodesc *cr_descs;50- struct sr_workunit *cr_wu;51void *cr_dmabuf;52};535455-struct sr_crypto_wu *sr_crypto_wu_get(struct sr_workunit *, int);56-void sr_crypto_wu_put(struct sr_crypto_wu *);57+struct sr_crypto_wu *sr_crypto_prepare(struct sr_workunit *, int);58int sr_crypto_create_keys(struct sr_discipline *);59int sr_crypto_get_kdf(struct bioc_createraid *,60struct sr_discipline *);61@@ -92,12 +87,11 @@62struct bioc_discipline *);63int sr_crypto_meta_opt_handler(struct sr_discipline *,64struct sr_meta_opt_hdr *);65-int sr_crypto_write(struct cryptop *);66+void sr_crypto_write(struct cryptop *);67int sr_crypto_rw(struct sr_workunit *);68-int sr_crypto_rw2(struct sr_workunit *, struct sr_crypto_wu *);69+int sr_crypto_dev_rw(struct sr_workunit *, struct sr_crypto_wu *);70void sr_crypto_done(struct sr_workunit *);71-int sr_crypto_read(struct cryptop *);72-void sr_crypto_finish_io(struct sr_workunit *);73+void sr_crypto_read(struct cryptop *);74void sr_crypto_calculate_check_hmac_sha1(u_int8_t *, int,75u_int8_t *, int, u_char *);76void sr_crypto_hotplug(struct sr_discipline *, struct disk *, int);77@@ -113,6 +107,7 @@78int i;7980/* Fill out discipline members. */81+ sd->sd_wu_size = sizeof(struct sr_crypto_wu);82sd->sd_type = SR_MD_CRYPTO;83strlcpy(sd->sd_name, "CRYPTO", sizeof(sd->sd_name));84sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE;85@@ -143,8 +138,14 @@86sr_error(sd->sd_sc, "%s requires exactly one chunk",87sd->sd_name);88goto done;89- }90+ }9192+ if (coerced_size > SR_CRYPTO_MAXSIZE) {93+ sr_error(sd->sd_sc, "%s exceeds maximum size (%lli > %llu)",94+ sd->sd_name, coerced_size, SR_CRYPTO_MAXSIZE);95+ goto done;96+ }97+98/* Create crypto optional metadata. */99omi = malloc(sizeof(struct sr_meta_opt_item), M_DEVBUF,100M_WAITOK | M_ZERO);101@@ -208,7 +209,7 @@102103if (data != NULL) {104/* Kernel already has mask key. */105- bcopy(data, sd->mds.mdd_crypto.scr_maskkey,106+ memcpy(sd->mds.mdd_crypto.scr_maskkey, data,107sizeof(sd->mds.mdd_crypto.scr_maskkey));108} else if (bc->bc_key_disk != NODEV) {109/* Read the mask key from the key disk. */110@@ -248,117 +249,69 @@111}112113struct sr_crypto_wu *114-sr_crypto_wu_get(struct sr_workunit *wu, int encrypt)115+sr_crypto_prepare(struct sr_workunit *wu, int encrypt)116{117struct scsi_xfer *xs = wu->swu_xs;118struct sr_discipline *sd = wu->swu_dis;119struct sr_crypto_wu *crwu;120struct cryptodesc *crd;121int flags, i, n;122- daddr64_t blk = 0;123+ daddr_t blkno;124u_int keyndx;125126- DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_get wu: %p encrypt: %d\n",127+ DNPRINTF(SR_D_DIS, "%s: sr_crypto_prepare wu %p encrypt %d\n",128DEVNAME(sd->sd_sc), wu, encrypt);129130- mtx_enter(&sd->mds.mdd_crypto.scr_mutex);131- if ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL)132- TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link);133- mtx_leave(&sd->mds.mdd_crypto.scr_mutex);134- if (crwu == NULL)135- panic("sr_crypto_wu_get: out of wus");136-137+ crwu = (struct sr_crypto_wu *)wu;138crwu->cr_uio.uio_iovcnt = 1;139crwu->cr_uio.uio_iov->iov_len = xs->datalen;140if (xs->flags & SCSI_DATA_OUT) {141crwu->cr_uio.uio_iov->iov_base = crwu->cr_dmabuf;142- bcopy(xs->data, crwu->cr_uio.uio_iov->iov_base, xs->datalen);143+ memcpy(crwu->cr_uio.uio_iov->iov_base, xs->data, xs->datalen);144} else145crwu->cr_uio.uio_iov->iov_base = xs->data;146147- if (xs->cmdlen == 10)148- blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);149- else if (xs->cmdlen == 16)150- blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr);151- else if (xs->cmdlen == 6)152- blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);153-154+ blkno = wu->swu_blk_start;155n = xs->datalen >> DEV_BSHIFT;156157/*158* We preallocated enough crypto descs for up to MAXPHYS of I/O.159- * Since there may be less than that we need to tweak the linked list160+ * Since there may be less than that we need to tweak the amount161* of crypto desc structures to be just long enough for our needs.162*/163- crd = crwu->cr_descs;164- for (i = 0; i < ((MAXPHYS >> DEV_BSHIFT) - n); i++) {165- crd = crd->crd_next;166- KASSERT(crd);167- }168- crwu->cr_crp->crp_desc = crd;169+ KASSERT(crwu->cr_crp->crp_ndescalloc >= n);170+ crwu->cr_crp->crp_ndesc = n;171flags = (encrypt ? CRD_F_ENCRYPT : 0) |172CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;173174- /* Select crypto session based on block number */175- keyndx = blk >> SR_CRYPTO_KEY_BLKSHIFT;176- if (keyndx >= SR_CRYPTO_MAXKEYS)177- goto unwind;178+ /*179+ * Select crypto session based on block number.180+ *181+ * XXX - this does not handle the case where the read/write spans182+ * across a different key blocks (e.g. 0.5TB boundary). Currently183+ * this is already broken by the use of scr_key[0] below.184+ */185+ keyndx = blkno >> SR_CRYPTO_KEY_BLKSHIFT;186crwu->cr_crp->crp_sid = sd->mds.mdd_crypto.scr_sid[keyndx];187- if (crwu->cr_crp->crp_sid == (u_int64_t)-1)188- goto unwind;189190+ crwu->cr_crp->crp_opaque = crwu;191crwu->cr_crp->crp_ilen = xs->datalen;192crwu->cr_crp->crp_alloctype = M_DEVBUF;193+ crwu->cr_crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_NOQUEUE;194crwu->cr_crp->crp_buf = &crwu->cr_uio;195- for (i = 0, crd = crwu->cr_crp->crp_desc; crd;196- i++, blk++, crd = crd->crd_next) {197+ for (i = 0; i < crwu->cr_crp->crp_ndesc; i++, blkno++) {198+ crd = &crwu->cr_crp->crp_desc[i];199crd->crd_skip = i << DEV_BSHIFT;200crd->crd_len = DEV_BSIZE;201crd->crd_inject = 0;202crd->crd_flags = flags;203- crd->crd_alg = CRYPTO_AES_XTS;204-205- switch (sd->mds.mdd_crypto.scr_meta->scm_alg) {206- case SR_CRYPTOA_AES_XTS_128:207- crd->crd_klen = 256;208- break;209- case SR_CRYPTOA_AES_XTS_256:210- crd->crd_klen = 512;211- break;212- default:213- goto unwind;214- }215+ crd->crd_alg = sd->mds.mdd_crypto.scr_alg;216+ crd->crd_klen = sd->mds.mdd_crypto.scr_klen;217crd->crd_key = sd->mds.mdd_crypto.scr_key[0];218- bcopy(&blk, crd->crd_iv, sizeof(blk));219+ memcpy(crd->crd_iv, &blkno, sizeof(blkno));220}221- crwu->cr_wu = wu;222- crwu->cr_crp->crp_opaque = crwu;223224return (crwu);225-226-unwind:227- /* steal the descriptors back from the cryptop */228- crwu->cr_crp->crp_desc = NULL;229-230- return (NULL);231-}232-233-void234-sr_crypto_wu_put(struct sr_crypto_wu *crwu)235-{236- struct cryptop *crp = crwu->cr_crp;237- struct sr_workunit *wu = crwu->cr_wu;238- struct sr_discipline *sd = wu->swu_dis;239-240- DNPRINTF(SR_D_DIS, "%s: sr_crypto_wu_put crwu: %p\n",241- DEVNAME(wu->swu_dis->sd_sc), crwu);242-243- /* steal the descriptors back from the cryptop */244- crp->crp_desc = NULL;245-246- mtx_enter(&sd->mds.mdd_crypto.scr_mutex);247- TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link);248- mtx_leave(&sd->mds.mdd_crypto.scr_mutex);249}250251int252@@ -386,9 +339,8 @@253if (sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint) <254kdfinfo->genkdf.len)255goto out;256- bcopy(&kdfinfo->genkdf,257- sd->mds.mdd_crypto.scr_meta->scm_kdfhint,258- kdfinfo->genkdf.len);259+ memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,260+ &kdfinfo->genkdf, kdfinfo->genkdf.len);261}262263/* copy mask key to run-time meta data */264@@ -396,7 +348,7 @@265if (sizeof(sd->mds.mdd_crypto.scr_maskkey) <266sizeof(kdfinfo->maskkey))267goto out;268- bcopy(&kdfinfo->maskkey, sd->mds.mdd_crypto.scr_maskkey,269+ memcpy(sd->mds.mdd_crypto.scr_maskkey, &kdfinfo->maskkey,270sizeof(kdfinfo->maskkey));271}272273@@ -404,7 +356,7 @@274rv = 0;275out:276explicit_bzero(kdfinfo, bc->bc_opaque_size);277- free(kdfinfo, M_DEVBUF);278+ free(kdfinfo, M_DEVBUF, bc->bc_opaque_size);279280return (rv);281}282@@ -424,7 +376,7 @@283rv = 0;284break;285default:286- DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n",287+ DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n",288"softraid", alg);289rv = -1;290goto out;291@@ -450,7 +402,7 @@292rv = 0;293break;294default:295- DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %u\n",296+ DNPRINTF(SR_D_DIS, "%s: unsupported encryption algorithm %d\n",297"softraid", alg);298rv = -1;299goto out;300@@ -615,6 +567,17 @@301sr_error(sd->sd_sc, "incorrect key or passphrase");302rv = EPERM;303goto out;304+ }305+306+ /* Copy new KDF hint to metadata, if supplied. */307+ if (kdfinfo2->flags & SR_CRYPTOKDF_HINT) {308+ if (kdfinfo2->genkdf.len >309+ sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint))310+ goto out;311+ explicit_bzero(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,312+ sizeof(sd->mds.mdd_crypto.scr_meta->scm_kdfhint));313+ memcpy(sd->mds.mdd_crypto.scr_meta->scm_kdfhint,314+ &kdfinfo2->genkdf, kdfinfo2->genkdf.len);315}316317/* Mask the disk keys. */318@@ -630,7 +593,7 @@319sizeof(sd->mds.mdd_crypto.scr_key), check_digest);320321/* Copy new encrypted key and HMAC to metadata. */322- bcopy(check_digest, sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac,323+ memcpy(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac, check_digest,324sizeof(sd->mds.mdd_crypto.scr_meta->chk_hmac_sha1.sch_mac));325326rv = 0; /* Success */327@@ -638,7 +601,7 @@328out:329if (p) {330explicit_bzero(p, ksz);331- free(p, M_DEVBUF);332+ free(p, M_DEVBUF, ksz);333}334335explicit_bzero(check_digest, sizeof(check_digest));336@@ -686,7 +649,7 @@337DNPRINTF(SR_D_META,"%s: sr_crypto_create_key_disk cannot "338"open %s\n", DEVNAME(sc), devname);339vput(vn);340- goto fail;341+ goto done;342}343open = 1; /* close dev on error */344345@@ -696,19 +659,12 @@346FREAD, NOCRED, curproc)) {347DNPRINTF(SR_D_META, "%s: sr_crypto_create_key_disk ioctl "348"failed\n", DEVNAME(sc));349- VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc);350- vput(vn);351- goto fail;352+ goto done;353}354- if (label.d_secsize != DEV_BSIZE) {355- sr_error(sc, "%s has unsupported sector size (%d)",356- devname, label.d_secsize);357- goto fail;358- }359if (label.d_partitions[part].p_fstype != FS_RAID) {360- sr_error(sc, "%s partition not of type RAID (%d)\n",361+ sr_error(sc, "%s partition not of type RAID (%d)",362devname, label.d_partitions[part].p_fstype);363- goto fail;364+ goto done;365}366367/*368@@ -728,7 +684,7 @@369km->scmi.scm_size = 0;370km->scmi.scm_coerced_size = 0;371strlcpy(km->scmi.scm_devname, devname, sizeof(km->scmi.scm_devname));372- bcopy(&sd->sd_meta->ssdi.ssd_uuid, &km->scmi.scm_uuid,373+ memcpy(&km->scmi.scm_uuid, &sd->sd_meta->ssdi.ssd_uuid,374sizeof(struct sr_uuid));375376sr_checksum(sc, km, &km->scm_checksum,377@@ -745,7 +701,7 @@378sm->ssdi.ssd_version = SR_META_VERSION;379sm->ssd_ondisk = 0;380sm->ssdi.ssd_vol_flags = 0;381- bcopy(&sd->sd_meta->ssdi.ssd_uuid, &sm->ssdi.ssd_uuid,382+ memcpy(&sm->ssdi.ssd_uuid, &sd->sd_meta->ssdi.ssd_uuid,383sizeof(struct sr_uuid));384sm->ssdi.ssd_chunk_no = 1;385sm->ssdi.ssd_volid = SR_KEYDISK_VOLID;386@@ -785,7 +741,7 @@387omi->omi_som->som_type = SR_OPT_KEYDISK;388omi->omi_som->som_length = sizeof(struct sr_meta_keydisk);389skm = (struct sr_meta_keydisk *)omi->omi_som;390- bcopy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey,391+ memcpy(&skm->skm_maskkey, sd->mds.mdd_crypto.scr_maskkey,392sizeof(skm->skm_maskkey));393SLIST_INSERT_HEAD(&fakesd->sd_meta_opt, omi, omi_link);394fakesd->sd_meta->ssdi.ssd_opt_no++;395@@ -799,19 +755,16 @@396goto done;397398fail:399- if (key_disk)400- free(key_disk, M_DEVBUF);401+ free(key_disk, M_DEVBUF, sizeof(struct sr_chunk));402key_disk = NULL;403404done:405- if (omi)406- free(omi, M_DEVBUF);407+ free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item));408if (fakesd && fakesd->sd_vol.sv_chunks)409- free(fakesd->sd_vol.sv_chunks, M_DEVBUF);410- if (fakesd)411- free(fakesd, M_DEVBUF);412- if (sm)413- free(sm, M_DEVBUF);414+ free(fakesd->sd_vol.sv_chunks, M_DEVBUF,415+ sizeof(struct sr_chunk *));416+ free(fakesd, M_DEVBUF, sizeof(struct sr_discipline));417+ free(sm, M_DEVBUF, sizeof(struct sr_metadata));418if (open) {419VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc);420vput(vn);421@@ -855,7 +808,7 @@422sr_error(sc, "cannot open key disk %s", devname);423goto done;424}425- if (VOP_OPEN(vn, FREAD | FWRITE, NOCRED, curproc)) {426+ if (VOP_OPEN(vn, FREAD, NOCRED, curproc)) {427DNPRINTF(SR_D_META,"%s: sr_crypto_read_key_disk cannot "428"open %s\n", DEVNAME(sc), devname);429vput(vn);430@@ -869,17 +822,10 @@431NOCRED, curproc)) {432DNPRINTF(SR_D_META, "%s: sr_crypto_read_key_disk ioctl "433"failed\n", DEVNAME(sc));434- VOP_CLOSE(vn, FREAD | FWRITE, NOCRED, curproc);435- vput(vn);436goto done;437}438- if (label.d_secsize != DEV_BSIZE) {439- sr_error(sc, "%s has unsupported sector size (%d)",440- devname, label.d_secsize);441- goto done;442- }443if (label.d_partitions[part].p_fstype != FS_RAID) {444- sr_error(sc, "%s partition not of type RAID (%d)\n",445+ sr_error(sc, "%s partition not of type RAID (%d)",446devname, label.d_partitions[part].p_fstype);447goto done;448}449@@ -887,7 +833,7 @@450/*451* Read and validate key disk metadata.452*/453- sm = malloc(SR_META_SIZE * 512, M_DEVBUF, M_WAITOK | M_ZERO);454+ sm = malloc(SR_META_SIZE * DEV_BSIZE, M_DEVBUF, M_WAITOK | M_ZERO);455if (sr_meta_native_read(sd, dev, sm, NULL)) {456sr_error(sc, "native bootprobe could not read native metadata");457goto done;458@@ -911,7 +857,7 @@459key_disk->src_vn = vn;460key_disk->src_size = 0;461462- bcopy((struct sr_meta_chunk *)(sm + 1), &key_disk->src_meta,463+ memcpy(&key_disk->src_meta, (struct sr_meta_chunk *)(sm + 1),464sizeof(key_disk->src_meta));465466/* Read mask key from optional metadata. */467@@ -920,13 +866,12 @@468omh = omi->omi_som;469if (omh->som_type == SR_OPT_KEYDISK) {470skm = (struct sr_meta_keydisk *)omh;471- bcopy(&skm->skm_maskkey,472- sd->mds.mdd_crypto.scr_maskkey,473+ memcpy(sd->mds.mdd_crypto.scr_maskkey, &skm->skm_maskkey,474sizeof(sd->mds.mdd_crypto.scr_maskkey));475} else if (omh->som_type == SR_OPT_CRYPTO) {476/* Original keydisk format with key in crypto area. */477- bcopy(omh + sizeof(struct sr_meta_opt_hdr),478- sd->mds.mdd_crypto.scr_maskkey,479+ memcpy(sd->mds.mdd_crypto.scr_maskkey,480+ omh + sizeof(struct sr_meta_opt_hdr),481sizeof(sd->mds.mdd_crypto.scr_maskkey));482}483}484@@ -934,15 +879,13 @@485open = 0;486487done:488- for (omi = SLIST_FIRST(&som); omi != SLIST_END(&som); omi = omi_next) {489+ for (omi = SLIST_FIRST(&som); omi != NULL; omi = omi_next) {490omi_next = SLIST_NEXT(omi, omi_link);491- if (omi->omi_som)492- free(omi->omi_som, M_DEVBUF);493- free(omi, M_DEVBUF);494+ free(omi->omi_som, M_DEVBUF, 0);495+ free(omi, M_DEVBUF, sizeof(struct sr_meta_opt_item));496}497498- if (sm)499- free(sm, M_DEVBUF);500+ free(sm, M_DEVBUF, SR_META_SIZE * DEV_BSIZE);501502if (vn && open) {503VOP_CLOSE(vn, FREAD, NOCRED, curproc);504@@ -950,18 +893,45 @@505}506507return key_disk;508+}509+510+static void511+sr_crypto_free_sessions(struct sr_discipline *sd)512+{513+ u_int i;514+515+ for (i = 0; i < SR_CRYPTO_MAXKEYS; i++) {516+ if (sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1) {517+ crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]);518+ sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;519+ }520+ }521}522523int524sr_crypto_alloc_resources(struct sr_discipline *sd)525{526- struct cryptoini cri;527+ struct sr_workunit *wu;528struct sr_crypto_wu *crwu;529+ struct cryptoini cri;530u_int num_keys, i;531532DNPRINTF(SR_D_DIS, "%s: sr_crypto_alloc_resources\n",533DEVNAME(sd->sd_sc));534535+ sd->mds.mdd_crypto.scr_alg = CRYPTO_AES_XTS;536+ switch (sd->mds.mdd_crypto.scr_meta->scm_alg) {537+ case SR_CRYPTOA_AES_XTS_128:538+ sd->mds.mdd_crypto.scr_klen = 256;539+ break;540+ case SR_CRYPTOA_AES_XTS_256:541+ sd->mds.mdd_crypto.scr_klen = 512;542+ break;543+ default:544+ sr_error(sd->sd_sc, "unknown crypto algorithm");545+ return (EINVAL);546+ }547+548for (i = 0; i < SR_CRYPTO_MAXKEYS; i++)549sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;550551@@ -979,61 +949,34 @@552}553554/*555- * For each wu allocate the uio, iovec and crypto structures.556- * these have to be allocated now because during runtime we can't557- * fail an allocation without failing the io (which can cause real558+ * For each work unit allocate the uio, iovec and crypto structures.559+ * These have to be allocated now because during runtime we cannot560+ * fail an allocation without failing the I/O (which can cause real561* problems).562*/563- mtx_init(&sd->mds.mdd_crypto.scr_mutex, IPL_BIO);564- TAILQ_INIT(&sd->mds.mdd_crypto.scr_wus);565- for (i = 0; i < sd->sd_max_wu; i++) {566- crwu = malloc(sizeof(*crwu), M_DEVBUF,567- M_WAITOK | M_ZERO | M_CANFAIL);568- if (crwu == NULL)569- return (ENOMEM);570- /* put it on the list now so if we fail it'll be freed */571- mtx_enter(&sd->mds.mdd_crypto.scr_mutex);572- TAILQ_INSERT_TAIL(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link);573- mtx_leave(&sd->mds.mdd_crypto.scr_mutex);574-575+ TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) {576+ crwu = (struct sr_crypto_wu *)wu;577crwu->cr_uio.uio_iov = &crwu->cr_iov;578crwu->cr_dmabuf = dma_alloc(MAXPHYS, PR_WAITOK);579crwu->cr_crp = crypto_getreq(MAXPHYS >> DEV_BSHIFT);580if (crwu->cr_crp == NULL)581return (ENOMEM);582- /* steal the list of cryptodescs */583- crwu->cr_descs = crwu->cr_crp->crp_desc;584- crwu->cr_crp->crp_desc = NULL;585}586587- bzero(&cri, sizeof(cri));588- cri.cri_alg = CRYPTO_AES_XTS;589- switch (sd->mds.mdd_crypto.scr_meta->scm_alg) {590- case SR_CRYPTOA_AES_XTS_128:591- cri.cri_klen = 256;592- break;593- case SR_CRYPTOA_AES_XTS_256:594- cri.cri_klen = 512;595- break;596- default:597- return (EINVAL);598- }599+ memset(&cri, 0, sizeof(cri));600+ cri.cri_alg = sd->mds.mdd_crypto.scr_alg;601+ cri.cri_klen = sd->mds.mdd_crypto.scr_klen;602603- /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks */604- num_keys = sd->sd_meta->ssdi.ssd_size >> SR_CRYPTO_KEY_BLKSHIFT;605- if (num_keys >= SR_CRYPTO_MAXKEYS)606+ /* Allocate a session for every 2^SR_CRYPTO_KEY_BLKSHIFT blocks. */607+ num_keys = ((sd->sd_meta->ssdi.ssd_size - 1) >>608+ SR_CRYPTO_KEY_BLKSHIFT) + 1;609+ if (num_keys > SR_CRYPTO_MAXKEYS)610return (EFBIG);611- for (i = 0; i <= num_keys; i++) {612+ for (i = 0; i < num_keys; i++) {613cri.cri_key = sd->mds.mdd_crypto.scr_key[i];614if (crypto_newsession(&sd->mds.mdd_crypto.scr_sid[i],615&cri, 0) != 0) {616- for (i = 0;617- sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1;618- i++) {619- crypto_freesession(620- sd->mds.mdd_crypto.scr_sid[i]);621- sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;622- }623+ sr_crypto_free_sessions(sd);624return (EINVAL);625}626}627@@ -1046,39 +989,30 @@628void629sr_crypto_free_resources(struct sr_discipline *sd)630{631+ struct sr_workunit *wu;632struct sr_crypto_wu *crwu;633- u_int i;634635DNPRINTF(SR_D_DIS, "%s: sr_crypto_free_resources\n",636DEVNAME(sd->sd_sc));637638if (sd->mds.mdd_crypto.key_disk != NULL) {639- explicit_bzero(sd->mds.mdd_crypto.key_disk, sizeof640- sd->mds.mdd_crypto.key_disk);641- free(sd->mds.mdd_crypto.key_disk, M_DEVBUF);642+ explicit_bzero(sd->mds.mdd_crypto.key_disk,643+ sizeof(*sd->mds.mdd_crypto.key_disk));644+ free(sd->mds.mdd_crypto.key_disk, M_DEVBUF,645+ sizeof(*sd->mds.mdd_crypto.key_disk));646}647648sr_hotplug_unregister(sd, sr_crypto_hotplug);649650- for (i = 0; sd->mds.mdd_crypto.scr_sid[i] != (u_int64_t)-1; i++) {651- crypto_freesession(sd->mds.mdd_crypto.scr_sid[i]);652- sd->mds.mdd_crypto.scr_sid[i] = (u_int64_t)-1;653- }654+ sr_crypto_free_sessions(sd);655656- mtx_enter(&sd->mds.mdd_crypto.scr_mutex);657- while ((crwu = TAILQ_FIRST(&sd->mds.mdd_crypto.scr_wus)) != NULL) {658- TAILQ_REMOVE(&sd->mds.mdd_crypto.scr_wus, crwu, cr_link);659-660- if (crwu->cr_dmabuf != NULL)661+ TAILQ_FOREACH(wu, &sd->sd_wu, swu_next) {662+ crwu = (struct sr_crypto_wu *)wu;663+ if (crwu->cr_dmabuf)664dma_free(crwu->cr_dmabuf, MAXPHYS);665- if (crwu->cr_crp) {666- /* twiddle cryptoreq back */667- crwu->cr_crp->crp_desc = crwu->cr_descs;668+ if (crwu->cr_crp)669crypto_freereq(crwu->cr_crp);670- }671- free(crwu, M_DEVBUF);672}673- mtx_leave(&sd->mds.mdd_crypto.scr_mutex);674675sr_wu_free(sd);676sr_ccb_free(sd);677@@ -1165,65 +1099,60 @@678sr_crypto_rw(struct sr_workunit *wu)679{680struct sr_crypto_wu *crwu;681- int s, rv = 0;682+ daddr_t blkno;683+ int rv = 0;684685- DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu: %p\n",686+ DNPRINTF(SR_D_DIS, "%s: sr_crypto_rw wu %p\n",687DEVNAME(wu->swu_dis->sd_sc), wu);688689- if (wu->swu_xs->flags & SCSI_DATA_OUT) {690- crwu = sr_crypto_wu_get(wu, 1);691- if (crwu == NULL)692- return (1);693+ if (sr_validate_io(wu, &blkno, "sr_crypto_rw"))694+ return (1);695+696+ if (wu->swu_xs->flags & SCSI_DATA_OUT) {697+ crwu = sr_crypto_prepare(wu, 1);698crwu->cr_crp->crp_callback = sr_crypto_write;699- s = splvm();700- if (crypto_invoke(crwu->cr_crp))701- rv = 1;702- else703+ rv = crypto_dispatch(crwu->cr_crp);704+ if (rv == 0)705rv = crwu->cr_crp->crp_etype;706- splx(s);707} else708- rv = sr_crypto_rw2(wu, NULL);709+ rv = sr_crypto_dev_rw(wu, NULL);710711return (rv);712}713714-int715+void716sr_crypto_write(struct cryptop *crp)717{718struct sr_crypto_wu *crwu = crp->crp_opaque;719- struct sr_workunit *wu = crwu->cr_wu;720+ struct sr_workunit *wu = &crwu->cr_wu;721int s;722723- DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %x xs: %x\n",724+ DNPRINTF(SR_D_INTR, "%s: sr_crypto_write: wu %p xs: %p\n",725DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs);726727if (crp->crp_etype) {728/* fail io */729wu->swu_xs->error = XS_DRIVER_STUFFUP;730s = splbio();731- sr_crypto_finish_io(wu);732+ sr_scsi_done(wu->swu_dis, wu->swu_xs);733splx(s);734}735736- return (sr_crypto_rw2(wu, crwu));737+ sr_crypto_dev_rw(wu, crwu);738}739740int741-sr_crypto_rw2(struct sr_workunit *wu, struct sr_crypto_wu *crwu)742+sr_crypto_dev_rw(struct sr_workunit *wu, struct sr_crypto_wu *crwu)743{744struct sr_discipline *sd = wu->swu_dis;745struct scsi_xfer *xs = wu->swu_xs;746struct sr_ccb *ccb;747struct uio *uio;748- int s;749- daddr64_t blk;750+ daddr_t blkno;751752- if (sr_validate_io(wu, &blk, "sr_crypto_rw2"))753- goto bad;754+ blkno = wu->swu_blk_start;755756- blk += sd->sd_meta->ssd_data_offset;757-758- ccb = sr_ccb_rw(sd, 0, blk, xs->datalen, xs->data, xs->flags, 0);759+ ccb = sr_ccb_rw(sd, 0, blkno, xs->datalen, xs->data, xs->flags, 0);760if (!ccb) {761/* should never happen but handle more gracefully */762printf("%s: %s: too many ccbs queued\n",763@@ -1236,17 +1165,10 @@764ccb->ccb_opaque = crwu;765}766sr_wu_enqueue_ccb(wu, ccb);767+ sr_schedule_wu(wu);768769- s = splbio();770-771- if (sr_check_io_collision(wu))772- goto queued;773-774- sr_raid_startwu(wu);775-776-queued:777- splx(s);778return (0);779+780bad:781/* wu is unwound by sr_wu_put */782if (crwu)783@@ -1259,77 +1181,39 @@784{785struct scsi_xfer *xs = wu->swu_xs;786struct sr_crypto_wu *crwu;787- struct sr_ccb *ccb;788int s;789790/* If this was a successful read, initiate decryption of the data. */791if (ISSET(xs->flags, SCSI_DATA_IN) && xs->error == XS_NOERROR) {792- /* only fails on implementation error */793- crwu = sr_crypto_wu_get(wu, 0);794- if (crwu == NULL)795- panic("sr_crypto_intr: no wu");796+ crwu = sr_crypto_prepare(wu, 0);797crwu->cr_crp->crp_callback = sr_crypto_read;798- ccb = TAILQ_FIRST(&wu->swu_ccb);799- if (ccb == NULL)800- panic("sr_crypto_done: no ccbs on workunit");801- ccb->ccb_opaque = crwu;802- DNPRINTF(SR_D_INTR, "%s: sr_crypto_intr: crypto_invoke %p\n",803+ DNPRINTF(SR_D_INTR, "%s: sr_crypto_done: crypto_dispatch %p\n",804DEVNAME(wu->swu_dis->sd_sc), crwu->cr_crp);805- s = splvm();806- crypto_invoke(crwu->cr_crp);807- splx(s);808+ crypto_dispatch(crwu->cr_crp);809return;810}811812s = splbio();813- sr_crypto_finish_io(wu);814+ sr_scsi_done(wu->swu_dis, wu->swu_xs);815splx(s);816}817818void819-sr_crypto_finish_io(struct sr_workunit *wu)820-{821- struct sr_discipline *sd = wu->swu_dis;822- struct scsi_xfer *xs = wu->swu_xs;823- struct sr_ccb *ccb;824-#ifdef SR_DEBUG825- struct sr_softc *sc = sd->sd_sc;826-#endif /* SR_DEBUG */827-828- splassert(IPL_BIO);829-830- DNPRINTF(SR_D_INTR, "%s: sr_crypto_finish_io: wu %x xs: %x\n",831- DEVNAME(sc), wu, xs);832-833- if (wu->swu_cb_active == 1)834- panic("%s: sr_crypto_finish_io", DEVNAME(sd->sd_sc));835- TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) {836- if (ccb->ccb_opaque == NULL)837- continue;838- sr_crypto_wu_put(ccb->ccb_opaque);839- }840-841- sr_scsi_done(sd, xs);842-}843-844-int845sr_crypto_read(struct cryptop *crp)846{847struct sr_crypto_wu *crwu = crp->crp_opaque;848- struct sr_workunit *wu = crwu->cr_wu;849+ struct sr_workunit *wu = &crwu->cr_wu;850int s;851852- DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %x xs: %x\n",853+ DNPRINTF(SR_D_INTR, "%s: sr_crypto_read: wu %p xs: %p\n",854DEVNAME(wu->swu_dis->sd_sc), wu, wu->swu_xs);855856if (crp->crp_etype)857wu->swu_xs->error = XS_DRIVER_STUFFUP;858859s = splbio();860- sr_crypto_finish_io(wu);861+ sr_scsi_done(wu->swu_dis, wu->swu_xs);862splx(s);863-864- return (0);865}866867void868869870