Annotation of src/sys/dev/cgd.c, Revision 1.76.12.1
1.76.12.1! snj 1: /* $NetBSD: cgd.c,v 1.76 2011/11/13 23:03:24 christos Exp $ */
1.1 elric 2:
3: /*-
4: * Copyright (c) 2002 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Roland C. Dowdeswell.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
32: #include <sys/cdefs.h>
1.76.12.1! snj 33: __KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.76 2011/11/13 23:03:24 christos Exp $");
1.1 elric 34:
35: #include <sys/types.h>
36: #include <sys/param.h>
37: #include <sys/systm.h>
38: #include <sys/proc.h>
39: #include <sys/errno.h>
40: #include <sys/buf.h>
1.21 yamt 41: #include <sys/bufq.h>
1.1 elric 42: #include <sys/malloc.h>
1.74 jruoho 43: #include <sys/module.h>
1.1 elric 44: #include <sys/pool.h>
45: #include <sys/ioctl.h>
46: #include <sys/device.h>
47: #include <sys/disk.h>
48: #include <sys/disklabel.h>
49: #include <sys/fcntl.h>
1.71 dholland 50: #include <sys/namei.h> /* for pathbuf */
1.1 elric 51: #include <sys/vnode.h>
52: #include <sys/conf.h>
1.62 christos 53: #include <sys/syslog.h>
1.1 elric 54:
55: #include <dev/dkvar.h>
56: #include <dev/cgdvar.h>
57:
58: /* Entry Point Functions */
59:
60: void cgdattach(int);
61:
1.18 thorpej 62: static dev_type_open(cgdopen);
63: static dev_type_close(cgdclose);
64: static dev_type_read(cgdread);
65: static dev_type_write(cgdwrite);
66: static dev_type_ioctl(cgdioctl);
67: static dev_type_strategy(cgdstrategy);
68: static dev_type_dump(cgddump);
69: static dev_type_size(cgdsize);
1.1 elric 70:
71: const struct bdevsw cgd_bdevsw = {
72: cgdopen, cgdclose, cgdstrategy, cgdioctl,
73: cgddump, cgdsize, D_DISK
74: };
75:
76: const struct cdevsw cgd_cdevsw = {
77: cgdopen, cgdclose, cgdread, cgdwrite, cgdioctl,
1.4 jdolecek 78: nostop, notty, nopoll, nommap, nokqfilter, D_DISK
1.1 elric 79: };
80:
1.65 dyoung 81: static int cgd_match(device_t, cfdata_t, void *);
82: static void cgd_attach(device_t, device_t, void *);
83: static int cgd_detach(device_t, int);
84: static struct cgd_softc *cgd_spawn(int);
85: static int cgd_destroy(device_t);
86:
1.1 elric 87: /* Internal Functions */
88:
1.16 elric 89: static int cgdstart(struct dk_softc *, struct buf *);
1.1 elric 90: static void cgdiodone(struct buf *);
91:
1.32 christos 92: static int cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
1.65 dyoung 93: static int cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
1.27 drochner 94: static int cgdinit(struct cgd_softc *, const char *, struct vnode *,
1.32 christos 95: struct lwp *);
1.44 christos 96: static void cgd_cipher(struct cgd_softc *, void *, void *,
1.1 elric 97: size_t, daddr_t, size_t, int);
98:
99: /* Pseudo-disk Interface */
100:
101: static struct dk_intf the_dkintf = {
102: DTYPE_CGD,
103: "cgd",
104: cgdopen,
105: cgdclose,
106: cgdstrategy,
107: cgdstart,
108: };
109: static struct dk_intf *di = &the_dkintf;
110:
1.29 yamt 111: static struct dkdriver cgddkdriver = {
112: .d_strategy = cgdstrategy,
113: .d_minphys = minphys,
114: };
115:
1.65 dyoung 116: CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
117: cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
118: extern struct cfdriver cgd_cd;
119:
1.1 elric 120: /* DIAGNOSTIC and DEBUG definitions */
121:
122: #if defined(CGDDEBUG) && !defined(DEBUG)
123: #define DEBUG
124: #endif
125:
126: #ifdef DEBUG
127: int cgddebug = 0;
128:
129: #define CGDB_FOLLOW 0x1
130: #define CGDB_IO 0x2
131: #define CGDB_CRYPTO 0x4
132:
133: #define IFDEBUG(x,y) if (cgddebug & (x)) y
134: #define DPRINTF(x,y) IFDEBUG(x, printf y)
135: #define DPRINTF_FOLLOW(y) DPRINTF(CGDB_FOLLOW, y)
136:
1.26 drochner 137: static void hexprint(const char *, void *, int);
1.1 elric 138:
139: #else
140: #define IFDEBUG(x,y)
141: #define DPRINTF(x,y)
142: #define DPRINTF_FOLLOW(y)
143: #endif
144:
145: #ifdef DIAGNOSTIC
1.22 perry 146: #define DIAGPANIC(x) panic x
1.1 elric 147: #define DIAGCONDPANIC(x,y) if (x) panic y
148: #else
149: #define DIAGPANIC(x)
150: #define DIAGCONDPANIC(x,y)
151: #endif
152:
153: /* Global variables */
154:
155: /* Utility Functions */
156:
157: #define CGDUNIT(x) DISKUNIT(x)
158: #define GETCGD_SOFTC(_cs, x) if (!((_cs) = getcgd_softc(x))) return ENXIO
159:
1.65 dyoung 160: /* The code */
161:
1.1 elric 162: static struct cgd_softc *
163: getcgd_softc(dev_t dev)
164: {
165: int unit = CGDUNIT(dev);
1.65 dyoung 166: struct cgd_softc *sc;
1.1 elric 167:
1.56 cegger 168: DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
1.65 dyoung 169:
170: sc = device_lookup_private(&cgd_cd, unit);
171: if (sc == NULL)
172: sc = cgd_spawn(unit);
173: return sc;
1.1 elric 174: }
175:
1.65 dyoung 176: static int
177: cgd_match(device_t self, cfdata_t cfdata, void *aux)
178: {
179:
180: return 1;
181: }
1.1 elric 182:
183: static void
1.65 dyoung 184: cgd_attach(device_t parent, device_t self, void *aux)
1.1 elric 185: {
1.65 dyoung 186: struct cgd_softc *sc = device_private(self);
1.1 elric 187:
1.65 dyoung 188: sc->sc_dev = self;
189: simple_lock_init(&sc->sc_slock);
190: dk_sc_init(&sc->sc_dksc, sc, device_xname(sc->sc_dev));
191: disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
1.70 joerg 192:
193: if (!pmf_device_register(self, NULL, NULL))
194: aprint_error_dev(self, "unable to register power management hooks\n");
1.65 dyoung 195: }
196:
197:
198: static int
199: cgd_detach(device_t self, int flags)
200: {
1.67 dyoung 201: int ret;
202: const int pmask = 1 << RAW_PART;
1.65 dyoung 203: struct cgd_softc *sc = device_private(self);
1.67 dyoung 204: struct dk_softc *dksc = &sc->sc_dksc;
205:
206: if (DK_BUSY(dksc, pmask))
207: return EBUSY;
1.65 dyoung 208:
1.67 dyoung 209: if ((dksc->sc_flags & DKF_INITED) != 0 &&
210: (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
211: return ret;
1.65 dyoung 212:
1.67 dyoung 213: disk_destroy(&dksc->sc_dkdev);
1.65 dyoung 214:
1.67 dyoung 215: return 0;
1.1 elric 216: }
217:
218: void
219: cgdattach(int num)
220: {
1.65 dyoung 221: int error;
222:
223: error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
224: if (error != 0)
225: aprint_error("%s: unable to register cfattach\n",
226: cgd_cd.cd_name);
227: }
228:
229: static struct cgd_softc *
230: cgd_spawn(int unit)
231: {
232: cfdata_t cf;
233:
234: cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
235: cf->cf_name = cgd_cd.cd_name;
236: cf->cf_atname = cgd_cd.cd_name;
237: cf->cf_unit = unit;
238: cf->cf_fstate = FSTATE_STAR;
239:
240: return device_private(config_attach_pseudo(cf));
241: }
242:
243: static int
244: cgd_destroy(device_t dev)
245: {
246: int error;
247: cfdata_t cf;
1.1 elric 248:
1.65 dyoung 249: cf = device_cfdata(dev);
250: error = config_detach(dev, DETACH_QUIET);
251: if (error)
252: return error;
253: free(cf, M_DEVBUF);
254: return 0;
1.1 elric 255: }
256:
1.18 thorpej 257: static int
1.32 christos 258: cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
1.1 elric 259: {
260: struct cgd_softc *cs;
261:
1.56 cegger 262: DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
1.1 elric 263: GETCGD_SOFTC(cs, dev);
1.32 christos 264: return dk_open(di, &cs->sc_dksc, dev, flags, fmt, l);
1.1 elric 265: }
266:
1.18 thorpej 267: static int
1.32 christos 268: cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
1.1 elric 269: {
1.65 dyoung 270: int error;
1.1 elric 271: struct cgd_softc *cs;
1.65 dyoung 272: struct dk_softc *dksc;
1.1 elric 273:
1.56 cegger 274: DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
1.1 elric 275: GETCGD_SOFTC(cs, dev);
1.65 dyoung 276: dksc = &cs->sc_dksc;
277: if ((error = dk_close(di, dksc, dev, flags, fmt, l)) != 0)
278: return error;
279:
280: if ((dksc->sc_flags & DKF_INITED) == 0) {
281: if ((error = cgd_destroy(cs->sc_dev)) != 0) {
282: aprint_error_dev(cs->sc_dev,
283: "unable to detach instance\n");
284: return error;
285: }
286: }
287: return 0;
1.1 elric 288: }
289:
1.18 thorpej 290: static void
1.1 elric 291: cgdstrategy(struct buf *bp)
292: {
293: struct cgd_softc *cs = getcgd_softc(bp->b_dev);
294:
295: DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
296: (long)bp->b_bcount));
1.72 riastrad 297:
298: /*
299: * Reject unaligned writes. We can encrypt and decrypt only
300: * complete disk sectors, and we let the ciphers require their
301: * buffers to be aligned to 32-bit boundaries.
302: */
303: if (bp->b_blkno < 0 ||
304: (bp->b_bcount % DEV_BSIZE) != 0 ||
305: ((uintptr_t)bp->b_data & 3) != 0) {
306: bp->b_error = EINVAL;
307: bp->b_resid = bp->b_bcount;
308: biodone(bp);
309: return;
310: }
311:
1.1 elric 312: /* XXXrcd: Should we test for (cs != NULL)? */
313: dk_strategy(di, &cs->sc_dksc, bp);
314: return;
315: }
316:
1.18 thorpej 317: static int
1.1 elric 318: cgdsize(dev_t dev)
319: {
320: struct cgd_softc *cs = getcgd_softc(dev);
321:
1.56 cegger 322: DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
1.1 elric 323: if (!cs)
324: return -1;
325: return dk_size(di, &cs->sc_dksc, dev);
326: }
327:
1.16 elric 328: /*
329: * cgd_{get,put}data are functions that deal with getting a buffer
330: * for the new encrypted data. We have a buffer per device so that
331: * we can ensure that we can always have a transaction in flight.
332: * We use this buffer first so that we have one less piece of
333: * malloc'ed data at any given point.
334: */
335:
336: static void *
337: cgd_getdata(struct dk_softc *dksc, unsigned long size)
338: {
339: struct cgd_softc *cs =dksc->sc_osc;
1.44 christos 340: void * data = NULL;
1.16 elric 341:
342: simple_lock(&cs->sc_slock);
343: if (cs->sc_data_used == 0) {
344: cs->sc_data_used = 1;
345: data = cs->sc_data;
346: }
347: simple_unlock(&cs->sc_slock);
348:
349: if (data)
350: return data;
351:
352: return malloc(size, M_DEVBUF, M_NOWAIT);
353: }
354:
1.1 elric 355: static void
1.44 christos 356: cgd_putdata(struct dk_softc *dksc, void *data)
1.16 elric 357: {
358: struct cgd_softc *cs =dksc->sc_osc;
359:
360: if (data == cs->sc_data) {
361: simple_lock(&cs->sc_slock);
362: cs->sc_data_used = 0;
363: simple_unlock(&cs->sc_slock);
364: } else {
365: free(data, M_DEVBUF);
366: }
367: }
368:
369: static int
1.1 elric 370: cgdstart(struct dk_softc *dksc, struct buf *bp)
371: {
372: struct cgd_softc *cs = dksc->sc_osc;
1.17 dbj 373: struct buf *nbp;
1.44 christos 374: void * addr;
375: void * newaddr;
1.1 elric 376: daddr_t bn;
1.49 ad 377: struct vnode *vp;
1.1 elric 378:
379: DPRINTF_FOLLOW(("cgdstart(%p, %p)\n", dksc, bp));
380: disk_busy(&dksc->sc_dkdev); /* XXX: put in dksubr.c */
381:
1.31 yamt 382: bn = bp->b_rawblkno;
1.1 elric 383:
384: /*
1.16 elric 385: * We attempt to allocate all of our resources up front, so that
386: * we can fail quickly if they are unavailable.
387: */
1.22 perry 388:
1.49 ad 389: nbp = getiobuf(cs->sc_tvn, false);
1.17 dbj 390: if (nbp == NULL) {
1.16 elric 391: disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
392: return -1;
393: }
394:
395: /*
1.1 elric 396: * If we are writing, then we need to encrypt the outgoing
1.16 elric 397: * block into a new block of memory. If we fail, then we
398: * return an error and let the dksubr framework deal with it.
1.1 elric 399: */
400: newaddr = addr = bp->b_data;
401: if ((bp->b_flags & B_READ) == 0) {
1.16 elric 402: newaddr = cgd_getdata(dksc, bp->b_bcount);
403: if (!newaddr) {
1.33 yamt 404: putiobuf(nbp);
1.16 elric 405: disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
406: return -1;
407: }
1.1 elric 408: cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
409: DEV_BSIZE, CGD_CIPHER_ENCRYPT);
410: }
411:
1.17 dbj 412: nbp->b_data = newaddr;
1.49 ad 413: nbp->b_flags = bp->b_flags;
414: nbp->b_oflags = bp->b_oflags;
415: nbp->b_cflags = bp->b_cflags;
1.17 dbj 416: nbp->b_iodone = cgdiodone;
417: nbp->b_proc = bp->b_proc;
418: nbp->b_blkno = bn;
419: nbp->b_bcount = bp->b_bcount;
420: nbp->b_private = bp;
421:
422: BIO_COPYPRIO(nbp, bp);
423:
424: if ((nbp->b_flags & B_READ) == 0) {
1.49 ad 425: vp = nbp->b_vp;
1.73 rmind 426: mutex_enter(vp->v_interlock);
1.49 ad 427: vp->v_numoutput++;
1.73 rmind 428: mutex_exit(vp->v_interlock);
1.17 dbj 429: }
430: VOP_STRATEGY(cs->sc_tvn, nbp);
1.16 elric 431: return 0;
1.1 elric 432: }
433:
1.18 thorpej 434: static void
1.17 dbj 435: cgdiodone(struct buf *nbp)
1.1 elric 436: {
1.17 dbj 437: struct buf *obp = nbp->b_private;
438: struct cgd_softc *cs = getcgd_softc(obp->b_dev);
1.1 elric 439: struct dk_softc *dksc = &cs->sc_dksc;
1.69 bouyer 440: int s;
1.22 perry 441:
1.17 dbj 442: KDASSERT(cs);
1.1 elric 443:
1.17 dbj 444: DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
1.20 yamt 445: DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
1.1 elric 446: obp, obp->b_bcount, obp->b_resid));
1.56 cegger 447: DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64 " addr %p bcnt %d\n",
1.17 dbj 448: nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
449: nbp->b_bcount));
1.46 ad 450: if (nbp->b_error != 0) {
451: obp->b_error = nbp->b_error;
1.62 christos 452: DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
453: obp->b_error));
1.1 elric 454: }
455:
1.16 elric 456: /* Perform the decryption if we are reading.
1.1 elric 457: *
458: * Note: use the blocknumber from nbp, since it is what
459: * we used to encrypt the blocks.
460: */
461:
1.16 elric 462: if (nbp->b_flags & B_READ)
1.1 elric 463: cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount,
464: nbp->b_blkno, DEV_BSIZE, CGD_CIPHER_DECRYPT);
465:
1.16 elric 466: /* If we allocated memory, free it now... */
1.1 elric 467: if (nbp->b_data != obp->b_data)
1.16 elric 468: cgd_putdata(dksc, nbp->b_data);
1.1 elric 469:
1.33 yamt 470: putiobuf(nbp);
1.1 elric 471:
472: /* Request is complete for whatever reason */
473: obp->b_resid = 0;
1.46 ad 474: if (obp->b_error != 0)
1.1 elric 475: obp->b_resid = obp->b_bcount;
1.69 bouyer 476: s = splbio();
1.5 mrg 477: disk_unbusy(&dksc->sc_dkdev, obp->b_bcount - obp->b_resid,
478: (obp->b_flags & B_READ));
1.1 elric 479: biodone(obp);
1.16 elric 480: dk_iodone(di, dksc);
1.69 bouyer 481: splx(s);
1.1 elric 482: }
483:
484: /* XXX: we should probably put these into dksubr.c, mostly */
1.18 thorpej 485: static int
1.40 christos 486: cgdread(dev_t dev, struct uio *uio, int flags)
1.1 elric 487: {
488: struct cgd_softc *cs;
489: struct dk_softc *dksc;
490:
1.56 cegger 491: DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
492: (unsigned long long)dev, uio, flags));
1.1 elric 493: GETCGD_SOFTC(cs, dev);
494: dksc = &cs->sc_dksc;
495: if ((dksc->sc_flags & DKF_INITED) == 0)
496: return ENXIO;
497: return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
498: }
499:
500: /* XXX: we should probably put these into dksubr.c, mostly */
1.18 thorpej 501: static int
1.40 christos 502: cgdwrite(dev_t dev, struct uio *uio, int flags)
1.1 elric 503: {
504: struct cgd_softc *cs;
505: struct dk_softc *dksc;
506:
1.56 cegger 507: DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
1.1 elric 508: GETCGD_SOFTC(cs, dev);
509: dksc = &cs->sc_dksc;
510: if ((dksc->sc_flags & DKF_INITED) == 0)
511: return ENXIO;
512: return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
513: }
514:
1.18 thorpej 515: static int
1.44 christos 516: cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
1.1 elric 517: {
518: struct cgd_softc *cs;
519: struct dk_softc *dksc;
1.29 yamt 520: struct disk *dk;
1.1 elric 521: int part = DISKPART(dev);
522: int pmask = 1 << part;
523:
1.56 cegger 524: DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
1.32 christos 525: dev, cmd, data, flag, l));
1.1 elric 526: GETCGD_SOFTC(cs, dev);
527: dksc = &cs->sc_dksc;
1.29 yamt 528: dk = &dksc->sc_dkdev;
1.1 elric 529: switch (cmd) {
530: case CGDIOCSET:
531: case CGDIOCCLR:
532: if ((flag & FWRITE) == 0)
533: return EBADF;
534: }
535:
536: switch (cmd) {
537: case CGDIOCSET:
538: if (dksc->sc_flags & DKF_INITED)
1.68 dyoung 539: return EBUSY;
540: return cgd_ioctl_set(cs, data, l);
1.1 elric 541: case CGDIOCCLR:
1.65 dyoung 542: if (DK_BUSY(&cs->sc_dksc, pmask))
1.68 dyoung 543: return EBUSY;
544: return cgd_ioctl_clr(cs, l);
1.57 apb 545: case DIOCCACHESYNC:
546: /*
547: * XXX Do we really need to care about having a writable
548: * file descriptor here?
549: */
550: if ((flag & FWRITE) == 0)
551: return (EBADF);
1.76.12.1! snj 552: if ((dksc->sc_flags & DKF_INITED) == 0)
! 553: return ENXIO;
1.57 apb 554:
555: /*
556: * We pass this call down to the underlying disk.
557: */
1.68 dyoung 558: return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred);
1.1 elric 559: default:
1.76.12.1! snj 560: if ((dksc->sc_flags & DKF_INITED) == 0)
! 561: return ENXIO;
1.68 dyoung 562: return dk_ioctl(di, dksc, dev, cmd, data, flag, l);
1.1 elric 563: }
564: }
565:
1.18 thorpej 566: static int
1.44 christos 567: cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
1.1 elric 568: {
569: struct cgd_softc *cs;
570:
1.56 cegger 571: DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
572: dev, blkno, va, (unsigned long)size));
1.1 elric 573: GETCGD_SOFTC(cs, dev);
574: return dk_dump(di, &cs->sc_dksc, dev, blkno, va, size);
575: }
576:
577: /*
578: * XXXrcd:
579: * for now we hardcode the maximum key length.
580: */
581: #define MAX_KEYSIZE 1024
582:
1.53 christos 583: static const struct {
584: const char *n;
585: int v;
586: int d;
587: } encblkno[] = {
588: { "encblkno", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
589: { "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
590: { "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
591: };
592:
1.1 elric 593: /* ARGSUSED */
594: static int
1.32 christos 595: cgd_ioctl_set(struct cgd_softc *cs, void *data, struct lwp *l)
1.1 elric 596: {
597: struct cgd_ioctl *ci = data;
598: struct vnode *vp;
599: int ret;
1.53 christos 600: size_t i;
1.43 cbiere 601: size_t keybytes; /* key length in bytes */
1.27 drochner 602: const char *cp;
1.71 dholland 603: struct pathbuf *pb;
1.36 christos 604: char *inbuf;
1.1 elric 605:
606: cp = ci->ci_disk;
1.71 dholland 607:
608: ret = pathbuf_copyin(ci->ci_disk, &pb);
609: if (ret != 0) {
610: return ret;
611: }
612: ret = dk_lookup(pb, l, &vp);
613: pathbuf_destroy(pb);
614: if (ret != 0) {
1.1 elric 615: return ret;
1.71 dholland 616: }
1.1 elric 617:
1.36 christos 618: inbuf = malloc(MAX_KEYSIZE, M_TEMP, M_WAITOK);
619:
1.32 christos 620: if ((ret = cgdinit(cs, cp, vp, l)) != 0)
1.1 elric 621: goto bail;
622:
1.36 christos 623: (void)memset(inbuf, 0, MAX_KEYSIZE);
1.1 elric 624: ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
625: if (ret)
626: goto bail;
627: cs->sc_cfuncs = cryptfuncs_find(inbuf);
628: if (!cs->sc_cfuncs) {
629: ret = EINVAL;
630: goto bail;
631: }
632:
1.43 cbiere 633: (void)memset(inbuf, 0, MAX_KEYSIZE);
1.36 christos 634: ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
1.1 elric 635: if (ret)
636: goto bail;
1.53 christos 637:
638: for (i = 0; i < __arraycount(encblkno); i++)
639: if (strcmp(encblkno[i].n, inbuf) == 0)
640: break;
641:
642: if (i == __arraycount(encblkno)) {
1.1 elric 643: ret = EINVAL;
644: goto bail;
645: }
646:
1.15 dan 647: keybytes = ci->ci_keylen / 8 + 1;
648: if (keybytes > MAX_KEYSIZE) {
1.1 elric 649: ret = EINVAL;
650: goto bail;
651: }
1.53 christos 652:
1.36 christos 653: (void)memset(inbuf, 0, MAX_KEYSIZE);
1.15 dan 654: ret = copyin(ci->ci_key, inbuf, keybytes);
1.1 elric 655: if (ret)
656: goto bail;
657:
658: cs->sc_cdata.cf_blocksize = ci->ci_blocksize;
1.53 christos 659: cs->sc_cdata.cf_mode = encblkno[i].v;
1.1 elric 660: cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
661: &cs->sc_cdata.cf_blocksize);
1.62 christos 662: if (cs->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
663: log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
1.63 christos 664: cs->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
1.62 christos 665: cs->sc_cdata.cf_priv = NULL;
666: }
667:
1.53 christos 668: /*
669: * The blocksize is supposed to be in bytes. Unfortunately originally
670: * it was expressed in bits. For compatibility we maintain encblkno
671: * and encblkno8.
672: */
673: cs->sc_cdata.cf_blocksize /= encblkno[i].d;
1.36 christos 674: (void)memset(inbuf, 0, MAX_KEYSIZE);
1.1 elric 675: if (!cs->sc_cdata.cf_priv) {
676: ret = EINVAL; /* XXX is this the right error? */
677: goto bail;
678: }
1.36 christos 679: free(inbuf, M_TEMP);
1.1 elric 680:
1.30 yamt 681: bufq_alloc(&cs->sc_dksc.sc_bufq, "fcfs", 0);
1.16 elric 682:
683: cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK);
684: cs->sc_data_used = 0;
685:
1.1 elric 686: cs->sc_dksc.sc_flags |= DKF_INITED;
687:
688: /* Attach the disk. */
1.47 ad 689: disk_attach(&cs->sc_dksc.sc_dkdev);
1.1 elric 690:
691: /* Try and read the disklabel. */
1.65 dyoung 692: dk_getdisklabel(di, &cs->sc_dksc, 0 /* XXX ? (cause of PR 41704) */);
1.1 elric 693:
1.29 yamt 694: /* Discover wedges on this disk. */
695: dkwedge_discover(&cs->sc_dksc.sc_dkdev);
696:
1.1 elric 697: return 0;
698:
699: bail:
1.36 christos 700: free(inbuf, M_TEMP);
1.51 ad 701: (void)vn_close(vp, FREAD|FWRITE, l->l_cred);
1.1 elric 702: return ret;
703: }
704:
705: /* ARGSUSED */
706: static int
1.65 dyoung 707: cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
1.1 elric 708: {
1.16 elric 709: int s;
1.65 dyoung 710: struct dk_softc *dksc;
711:
712: dksc = &cs->sc_dksc;
713:
714: if ((dksc->sc_flags & DKF_INITED) == 0)
715: return ENXIO;
1.16 elric 716:
1.29 yamt 717: /* Delete all of our wedges. */
718: dkwedge_delall(&cs->sc_dksc.sc_dkdev);
719:
1.16 elric 720: /* Kill off any queued buffers. */
721: s = splbio();
1.30 yamt 722: bufq_drain(cs->sc_dksc.sc_bufq);
1.16 elric 723: splx(s);
1.30 yamt 724: bufq_free(cs->sc_dksc.sc_bufq);
1.1 elric 725:
1.51 ad 726: (void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
1.1 elric 727: cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
728: free(cs->sc_tpath, M_DEVBUF);
1.16 elric 729: free(cs->sc_data, M_DEVBUF);
730: cs->sc_data_used = 0;
1.1 elric 731: cs->sc_dksc.sc_flags &= ~DKF_INITED;
1.47 ad 732: disk_detach(&cs->sc_dksc.sc_dkdev);
1.1 elric 733:
734: return 0;
735: }
736:
737: static int
1.27 drochner 738: cgdinit(struct cgd_softc *cs, const char *cpath, struct vnode *vp,
1.32 christos 739: struct lwp *l)
1.1 elric 740: {
741: struct dk_geom *pdg;
742: struct vattr va;
743: int ret;
1.36 christos 744: char *tmppath;
1.76 christos 745: uint64_t psize;
746: unsigned secsize;
1.1 elric 747:
748: cs->sc_dksc.sc_size = 0;
749: cs->sc_tvn = vp;
1.36 christos 750: cs->sc_tpath = NULL;
1.1 elric 751:
1.36 christos 752: tmppath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
1.1 elric 753: ret = copyinstr(cpath, tmppath, MAXPATHLEN, &cs->sc_tpathlen);
754: if (ret)
755: goto bail;
756: cs->sc_tpath = malloc(cs->sc_tpathlen, M_DEVBUF, M_WAITOK);
757: memcpy(cs->sc_tpath, tmppath, cs->sc_tpathlen);
758:
1.75 hannken 759: vn_lock(vp, LK_SHARED | LK_RETRY);
760: ret = VOP_GETATTR(vp, &va, l->l_cred);
761: VOP_UNLOCK(vp);
762: if (ret != 0)
1.1 elric 763: goto bail;
764:
765: cs->sc_tdev = va.va_rdev;
766:
1.76 christos 767: if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
1.1 elric 768: goto bail;
769:
1.76 christos 770: if (psize == 0) {
1.1 elric 771: ret = ENODEV;
772: goto bail;
773: }
774:
1.76 christos 775: cs->sc_dksc.sc_size = psize;
1.1 elric 776:
777: /*
778: * XXX here we should probe the underlying device. If we
779: * are accessing a partition of type RAW_PART, then
780: * we should populate our initial geometry with the
781: * geometry that we discover from the device.
782: */
783: pdg = &cs->sc_dksc.sc_geom;
784: pdg->pdg_secsize = DEV_BSIZE;
785: pdg->pdg_ntracks = 1;
786: pdg->pdg_nsectors = 1024 * (1024 / pdg->pdg_secsize);
787: pdg->pdg_ncylinders = cs->sc_dksc.sc_size / pdg->pdg_nsectors;
788:
789: bail:
1.36 christos 790: free(tmppath, M_TEMP);
1.1 elric 791: if (ret && cs->sc_tpath)
792: free(cs->sc_tpath, M_DEVBUF);
793: return ret;
794: }
795:
796: /*
797: * Our generic cipher entry point. This takes care of the
798: * IV mode and passes off the work to the specific cipher.
799: * We implement here the IV method ``encrypted block
800: * number''.
1.22 perry 801: *
1.1 elric 802: * For the encryption case, we accomplish this by setting
803: * up a struct uio where the first iovec of the source is
804: * the blocknumber and the first iovec of the dest is a
805: * sink. We then call the cipher with an IV of zero, and
806: * the right thing happens.
1.22 perry 807: *
1.1 elric 808: * For the decryption case, we use the same basic mechanism
809: * for symmetry, but we encrypt the block number in the
810: * first iovec.
811: *
812: * We mainly do this to avoid requiring the definition of
813: * an ECB mode.
814: *
815: * XXXrcd: for now we rely on our own crypto framework defined
816: * in dev/cgd_crypto.c. This will change when we
817: * get a generic kernel crypto framework.
818: */
819:
820: static void
1.25 xtraeme 821: blkno2blkno_buf(char *sbuf, daddr_t blkno)
1.1 elric 822: {
823: int i;
824:
825: /* Set up the blkno in blkno_buf, here we do not care much
826: * about the final layout of the information as long as we
827: * can guarantee that each sector will have a different IV
828: * and that the endianness of the machine will not affect
829: * the representation that we have chosen.
830: *
831: * We choose this representation, because it does not rely
832: * on the size of buf (which is the blocksize of the cipher),
833: * but allows daddr_t to grow without breaking existing
834: * disks.
835: *
836: * Note that blkno2blkno_buf does not take a size as input,
837: * and hence must be called on a pre-zeroed buffer of length
838: * greater than or equal to sizeof(daddr_t).
839: */
840: for (i=0; i < sizeof(daddr_t); i++) {
1.25 xtraeme 841: *sbuf++ = blkno & 0xff;
1.1 elric 842: blkno >>= 8;
843: }
844: }
845:
846: static void
1.44 christos 847: cgd_cipher(struct cgd_softc *cs, void *dstv, void *srcv,
848: size_t len, daddr_t blkno, size_t secsize, int dir)
1.1 elric 849: {
1.44 christos 850: char *dst = dstv;
851: char *src = srcv;
1.1 elric 852: cfunc_cipher *cipher = cs->sc_cfuncs->cf_cipher;
853: struct uio dstuio;
854: struct uio srcuio;
855: struct iovec dstiov[2];
856: struct iovec srciov[2];
1.42 christos 857: size_t blocksize = cs->sc_cdata.cf_blocksize;
1.62 christos 858: char sink[CGD_MAXBLOCKSIZE];
859: char zero_iv[CGD_MAXBLOCKSIZE];
860: char blkno_buf[CGD_MAXBLOCKSIZE];
1.1 elric 861:
862: DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
863:
1.22 perry 864: DIAGCONDPANIC(len % blocksize != 0,
1.1 elric 865: ("cgd_cipher: len %% blocksize != 0"));
866:
867: /* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
868: DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
869: ("cgd_cipher: sizeof(daddr_t) > blocksize"));
870:
1.64 christos 871: memset(zero_iv, 0x0, blocksize);
1.1 elric 872:
873: dstuio.uio_iov = dstiov;
874: dstuio.uio_iovcnt = 2;
875:
876: srcuio.uio_iov = srciov;
877: srcuio.uio_iovcnt = 2;
878:
879: dstiov[0].iov_base = sink;
880: dstiov[0].iov_len = blocksize;
881: srciov[0].iov_base = blkno_buf;
882: srciov[0].iov_len = blocksize;
883: dstiov[1].iov_len = secsize;
884: srciov[1].iov_len = secsize;
885:
886: for (; len > 0; len -= secsize) {
887: dstiov[1].iov_base = dst;
888: srciov[1].iov_base = src;
889:
1.64 christos 890: memset(blkno_buf, 0x0, blocksize);
1.1 elric 891: blkno2blkno_buf(blkno_buf, blkno);
892: if (dir == CGD_CIPHER_DECRYPT) {
893: dstuio.uio_iovcnt = 1;
894: srcuio.uio_iovcnt = 1;
895: IFDEBUG(CGDB_CRYPTO, hexprint("step 0: blkno_buf",
1.64 christos 896: blkno_buf, blocksize));
1.1 elric 897: cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio,
898: zero_iv, CGD_CIPHER_ENCRYPT);
899: memcpy(blkno_buf, sink, blocksize);
900: dstuio.uio_iovcnt = 2;
901: srcuio.uio_iovcnt = 2;
902: }
903:
904: IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
1.64 christos 905: blkno_buf, blocksize));
1.1 elric 906: cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio, zero_iv, dir);
907: IFDEBUG(CGDB_CRYPTO, hexprint("step 2: sink",
1.64 christos 908: sink, blocksize));
1.1 elric 909:
910: dst += secsize;
911: src += secsize;
912: blkno++;
913: }
914: }
915:
916: #ifdef DEBUG
917: static void
1.26 drochner 918: hexprint(const char *start, void *buf, int len)
1.1 elric 919: {
920: char *c = buf;
921:
922: DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
923: printf("%s: len=%06d 0x", start, len);
924: while (len--)
1.43 cbiere 925: printf("%02x", (unsigned char) *c++);
1.1 elric 926: }
927: #endif
1.58 haad 928:
1.74 jruoho 929: MODULE(MODULE_CLASS_DRIVER, cgd, NULL);
930:
1.58 haad 931: #ifdef _MODULE
1.66 dyoung 932: CFDRIVER_DECL(cgd, DV_DISK, NULL);
1.74 jruoho 933: #endif
1.58 haad 934:
935: static int
936: cgd_modcmd(modcmd_t cmd, void *arg)
937: {
1.74 jruoho 938: int bmajor, cmajor, error = 0;
939:
940: bmajor = cmajor = -1;
941:
1.58 haad 942: switch (cmd) {
943: case MODULE_CMD_INIT:
1.74 jruoho 944: #ifdef _MODULE
1.66 dyoung 945: error = config_cfdriver_attach(&cgd_cd);
946: if (error)
947: break;
948:
949: error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
950: if (error) {
951: config_cfdriver_detach(&cgd_cd);
952: aprint_error("%s: unable to register cfattach\n",
953: cgd_cd.cd_name);
954: break;
955: }
1.74 jruoho 956:
1.66 dyoung 957: error = devsw_attach("cgd", &cgd_bdevsw, &bmajor,
1.58 haad 958: &cgd_cdevsw, &cmajor);
1.66 dyoung 959: if (error) {
960: config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
961: config_cfdriver_detach(&cgd_cd);
962: break;
963: }
1.74 jruoho 964: #endif
1.58 haad 965: break;
966:
967: case MODULE_CMD_FINI:
1.74 jruoho 968: #ifdef _MODULE
1.66 dyoung 969: error = config_cfattach_detach(cgd_cd.cd_name, &cgd_ca);
970: if (error)
971: break;
972: config_cfdriver_detach(&cgd_cd);
973: devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
1.74 jruoho 974: #endif
1.58 haad 975: break;
976:
977: case MODULE_CMD_STAT:
978: return ENOTTY;
979:
980: default:
981: return ENOTTY;
982: }
983:
984: return error;
985: }
CVSweb <webmaster@jp.NetBSD.org>