cgd.c revision 1.108.2.4 1 /* $NetBSD: cgd.c,v 1.108.2.4 2016/07/20 06:51:13 pgoyette Exp $ */
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>
33 __KERNEL_RCSID(0, "$NetBSD: cgd.c,v 1.108.2.4 2016/07/20 06:51:13 pgoyette Exp $");
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>
41 #include <sys/bufq.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
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>
50 #include <sys/namei.h> /* for pathbuf */
51 #include <sys/vnode.h>
52 #include <sys/conf.h>
53 #include <sys/syslog.h>
54 #include <sys/localcount.h>
55
56 #include <dev/dkvar.h>
57 #include <dev/cgdvar.h>
58
59 #include <miscfs/specfs/specdev.h> /* for v_rdev */
60
61 #include "ioconf.h"
62
63 /* Entry Point Functions */
64
65 static dev_type_open(cgdopen);
66 static dev_type_close(cgdclose);
67 static dev_type_read(cgdread);
68 static dev_type_write(cgdwrite);
69 static dev_type_ioctl(cgdioctl);
70 static dev_type_strategy(cgdstrategy);
71 static dev_type_dump(cgddump);
72 static dev_type_size(cgdsize);
73
74 const struct bdevsw cgd_bdevsw = {
75 LOCALCOUNT_INITIALIZER
76 .d_open = cgdopen,
77 .d_close = cgdclose,
78 .d_strategy = cgdstrategy,
79 .d_ioctl = cgdioctl,
80 .d_dump = cgddump,
81 .d_psize = cgdsize,
82 .d_discard = nodiscard,
83 .d_flag = D_DISK
84 };
85
86 const struct cdevsw cgd_cdevsw = {
87 LOCALCOUNT_INITIALIZER
88 .d_open = cgdopen,
89 .d_close = cgdclose,
90 .d_read = cgdread,
91 .d_write = cgdwrite,
92 .d_ioctl = cgdioctl,
93 .d_stop = nostop,
94 .d_tty = notty,
95 .d_poll = nopoll,
96 .d_mmap = nommap,
97 .d_kqfilter = nokqfilter,
98 .d_discard = nodiscard,
99 .d_flag = D_DISK
100 };
101
102 static int cgd_match(device_t, cfdata_t, void *);
103 static void cgd_attach(device_t, device_t, void *);
104 static int cgd_detach(device_t, int);
105 static struct cgd_softc *cgd_spawn(int);
106 static int cgd_destroy(device_t);
107
108 /* Internal Functions */
109
110 static int cgd_diskstart(device_t, struct buf *);
111 static void cgdiodone(struct buf *);
112 static int cgd_dumpblocks(device_t, void *, daddr_t, int);
113
114 static int cgd_ioctl_set(struct cgd_softc *, void *, struct lwp *);
115 static int cgd_ioctl_clr(struct cgd_softc *, struct lwp *);
116 static int cgd_ioctl_get(dev_t, void *, struct lwp *);
117 static int cgdinit(struct cgd_softc *, const char *, struct vnode *,
118 struct lwp *);
119 static void cgd_cipher(struct cgd_softc *, void *, void *,
120 size_t, daddr_t, size_t, int);
121
122 static struct dkdriver cgddkdriver = {
123 .d_minphys = minphys,
124 .d_open = cgdopen,
125 .d_close = cgdclose,
126 .d_strategy = cgdstrategy,
127 .d_iosize = NULL,
128 .d_diskstart = cgd_diskstart,
129 .d_dumpblocks = cgd_dumpblocks,
130 .d_lastclose = NULL
131 };
132
133 CFATTACH_DECL3_NEW(cgd, sizeof(struct cgd_softc),
134 cgd_match, cgd_attach, cgd_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
135 extern struct cfdriver cgd_cd;
136
137 /* DIAGNOSTIC and DEBUG definitions */
138
139 #if defined(CGDDEBUG) && !defined(DEBUG)
140 #define DEBUG
141 #endif
142
143 #ifdef DEBUG
144 int cgddebug = 0;
145
146 #define CGDB_FOLLOW 0x1
147 #define CGDB_IO 0x2
148 #define CGDB_CRYPTO 0x4
149
150 #define IFDEBUG(x,y) if (cgddebug & (x)) y
151 #define DPRINTF(x,y) IFDEBUG(x, printf y)
152 #define DPRINTF_FOLLOW(y) DPRINTF(CGDB_FOLLOW, y)
153
154 static void hexprint(const char *, void *, int);
155
156 #else
157 #define IFDEBUG(x,y)
158 #define DPRINTF(x,y)
159 #define DPRINTF_FOLLOW(y)
160 #endif
161
162 #ifdef DIAGNOSTIC
163 #define DIAGPANIC(x) panic x
164 #define DIAGCONDPANIC(x,y) if (x) panic y
165 #else
166 #define DIAGPANIC(x)
167 #define DIAGCONDPANIC(x,y)
168 #endif
169
170 /* Global variables */
171
172 /* Utility Functions */
173
174 #define CGDUNIT(x) DISKUNIT(x)
175 #define GETCGD_SOFTC(_cs, x) if (!((_cs) = getcgd_softc(x))) return ENXIO
176
177 /* The code */
178
179 static void
180 cgd_release(dev_t dev)
181 {
182 int unit = CGDUNIT(dev);
183 device_t self;
184
185 self = device_lookup_acquire(&cgd_cd, unit);
186 if (self != NULL)
187 device_release(self);
188 }
189
190 static struct cgd_softc *
191 getcgd_softc(dev_t dev)
192 {
193 int unit = CGDUNIT(dev);
194 struct cgd_softc *sc;
195
196 DPRINTF_FOLLOW(("getcgd_softc(0x%"PRIx64"): unit = %d\n", dev, unit));
197
198 sc = device_lookup_private(&cgd_cd, unit);
199 if (sc == NULL)
200 sc = cgd_spawn(unit);
201 return sc;
202 }
203
204 static int
205 cgd_match(device_t self, cfdata_t cfdata, void *aux)
206 {
207
208 return 1;
209 }
210
211 static void
212 cgd_attach(device_t parent, device_t self, void *aux)
213 {
214 struct cgd_softc *sc = device_private(self);
215
216 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_BIO);
217 dk_init(&sc->sc_dksc, self, DKTYPE_CGD);
218 disk_init(&sc->sc_dksc.sc_dkdev, sc->sc_dksc.sc_xname, &cgddkdriver);
219
220 if (!pmf_device_register(self, NULL, NULL))
221 aprint_error_dev(self,
222 "unable to register power management hooks\n");
223 }
224
225
226 static int
227 cgd_detach(device_t self, int flags)
228 {
229 int ret;
230 const int pmask = 1 << RAW_PART;
231 struct cgd_softc *sc = device_private(self);
232 struct dk_softc *dksc = &sc->sc_dksc;
233
234 if (DK_BUSY(dksc, pmask))
235 return EBUSY;
236
237 if (DK_ATTACHED(dksc) &&
238 (ret = cgd_ioctl_clr(sc, curlwp)) != 0)
239 return ret;
240
241 disk_destroy(&dksc->sc_dkdev);
242 mutex_destroy(&sc->sc_lock);
243
244 return 0;
245 }
246
247 void
248 cgdattach(int num)
249 {
250 int error;
251
252 error = config_cfattach_attach(cgd_cd.cd_name, &cgd_ca);
253 if (error != 0)
254 aprint_error("%s: unable to register cfattach\n",
255 cgd_cd.cd_name);
256 }
257
258 static struct cgd_softc *
259 cgd_spawn(int unit)
260 {
261 device_t self;
262 cfdata_t cf;
263
264 cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK);
265 cf->cf_name = cgd_cd.cd_name;
266 cf->cf_atname = cgd_cd.cd_name;
267 cf->cf_unit = unit;
268 cf->cf_fstate = FSTATE_STAR;
269
270 if (config_attach_pseudo(cf) == NULL)
271 return NULL;
272
273 self = device_lookup_acquire(&cgd_cd, unit);
274 if (self == NULL)
275 return NULL;
276 else
277 /*
278 * Note that we return with a reference to the device!
279 */
280 return device_private(self);
281 }
282
283 static int
284 cgd_destroy(device_t dev)
285 {
286 int error;
287 cfdata_t cf;
288
289 cf = device_cfdata(dev);
290 error = config_detach(dev, DETACH_QUIET);
291 if (error)
292 return error;
293 free(cf, M_DEVBUF);
294 return 0;
295 }
296
297 static int
298 cgdopen(dev_t dev, int flags, int fmt, struct lwp *l)
299 {
300 struct cgd_softc *cs;
301
302 DPRINTF_FOLLOW(("cgdopen(0x%"PRIx64", %d)\n", dev, flags));
303 GETCGD_SOFTC(cs, dev);
304 return dk_open(&cs->sc_dksc, dev, flags, fmt, l);
305 }
306
307 static int
308 cgdclose(dev_t dev, int flags, int fmt, struct lwp *l)
309 {
310 int error;
311 struct cgd_softc *cs;
312 struct dk_softc *dksc;
313
314 DPRINTF_FOLLOW(("cgdclose(0x%"PRIx64", %d)\n", dev, flags));
315 GETCGD_SOFTC(cs, dev);
316 dksc = &cs->sc_dksc;
317 if ((error = dk_close(dksc, dev, flags, fmt, l)) != 0)
318 return error;
319
320 if (!DK_ATTACHED(dksc)) {
321 if ((error = cgd_destroy(cs->sc_dksc.sc_dev)) != 0) {
322 aprint_error_dev(dksc->sc_dev,
323 "unable to detach instance\n");
324 return error;
325 }
326 }
327 return 0;
328 }
329
330 static void
331 cgdstrategy(struct buf *bp)
332 {
333 struct cgd_softc *cs = getcgd_softc(bp->b_dev);
334 struct dk_softc *dksc = &cs->sc_dksc;
335 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
336
337 DPRINTF_FOLLOW(("cgdstrategy(%p): b_bcount = %ld\n", bp,
338 (long)bp->b_bcount));
339
340 /*
341 * Reject unaligned writes. We can encrypt and decrypt only
342 * complete disk sectors, and we let the ciphers require their
343 * buffers to be aligned to 32-bit boundaries.
344 */
345 if (bp->b_blkno < 0 ||
346 (bp->b_bcount % dg->dg_secsize) != 0 ||
347 ((uintptr_t)bp->b_data & 3) != 0) {
348 bp->b_error = EINVAL;
349 bp->b_resid = bp->b_bcount;
350 biodone(bp);
351 cgd_release(bp->b_dev);
352 return;
353 }
354
355 /* XXXrcd: Should we test for (cs != NULL)? */
356 dk_strategy(&cs->sc_dksc, bp);
357 cgd_release(bp->b_dev);
358 return;
359 }
360
361 static int
362 cgdsize(dev_t dev)
363 {
364 int retval;
365 struct cgd_softc *cs = getcgd_softc(dev);
366
367 DPRINTF_FOLLOW(("cgdsize(0x%"PRIx64")\n", dev));
368 if (!cs)
369 retval = -1;
370 else
371 retval = dk_size(&cs->sc_dksc, dev);
372
373 cgd_release(dev);
374 return retval;
375 }
376
377 /*
378 * cgd_{get,put}data are functions that deal with getting a buffer
379 * for the new encrypted data. We have a buffer per device so that
380 * we can ensure that we can always have a transaction in flight.
381 * We use this buffer first so that we have one less piece of
382 * malloc'ed data at any given point.
383 */
384
385 static void *
386 cgd_getdata(struct dk_softc *dksc, unsigned long size)
387 {
388 struct cgd_softc *cs = (struct cgd_softc *)dksc;
389 void * data = NULL;
390
391 mutex_enter(&cs->sc_lock);
392 if (cs->sc_data_used == 0) {
393 cs->sc_data_used = 1;
394 data = cs->sc_data;
395 }
396 mutex_exit(&cs->sc_lock);
397
398 if (data)
399 return data;
400
401 return malloc(size, M_DEVBUF, M_NOWAIT);
402 }
403
404 static void
405 cgd_putdata(struct dk_softc *dksc, void *data)
406 {
407 struct cgd_softc *cs = (struct cgd_softc *)dksc;
408
409 if (data == cs->sc_data) {
410 mutex_enter(&cs->sc_lock);
411 cs->sc_data_used = 0;
412 mutex_exit(&cs->sc_lock);
413 } else {
414 free(data, M_DEVBUF);
415 }
416 }
417
418 static int
419 cgd_diskstart(device_t dev, struct buf *bp)
420 {
421 struct cgd_softc *cs = device_private(dev);
422 struct dk_softc *dksc = &cs->sc_dksc;
423 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
424 struct buf *nbp;
425 void * addr;
426 void * newaddr;
427 daddr_t bn;
428 struct vnode *vp;
429
430 DPRINTF_FOLLOW(("cgd_diskstart(%p, %p)\n", dksc, bp));
431
432 bn = bp->b_rawblkno;
433
434 /*
435 * We attempt to allocate all of our resources up front, so that
436 * we can fail quickly if they are unavailable.
437 */
438 nbp = getiobuf(cs->sc_tvn, false);
439 if (nbp == NULL)
440 return EAGAIN;
441
442 /*
443 * If we are writing, then we need to encrypt the outgoing
444 * block into a new block of memory.
445 */
446 newaddr = addr = bp->b_data;
447 if ((bp->b_flags & B_READ) == 0) {
448 newaddr = cgd_getdata(dksc, bp->b_bcount);
449 if (!newaddr) {
450 putiobuf(nbp);
451 return EAGAIN;
452 }
453 cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
454 dg->dg_secsize, CGD_CIPHER_ENCRYPT);
455 }
456
457 nbp->b_data = newaddr;
458 nbp->b_flags = bp->b_flags;
459 nbp->b_oflags = bp->b_oflags;
460 nbp->b_cflags = bp->b_cflags;
461 nbp->b_iodone = cgdiodone;
462 nbp->b_proc = bp->b_proc;
463 nbp->b_blkno = btodb(bn * dg->dg_secsize);
464 nbp->b_bcount = bp->b_bcount;
465 nbp->b_private = bp;
466
467 BIO_COPYPRIO(nbp, bp);
468
469 if ((nbp->b_flags & B_READ) == 0) {
470 vp = nbp->b_vp;
471 mutex_enter(vp->v_interlock);
472 vp->v_numoutput++;
473 mutex_exit(vp->v_interlock);
474 }
475 VOP_STRATEGY(cs->sc_tvn, nbp);
476
477 return 0;
478 }
479
480 static void
481 cgdiodone(struct buf *nbp)
482 {
483 dev_t dev;
484 struct buf *obp = nbp->b_private;
485 struct cgd_softc *cs = getcgd_softc(obp->b_dev);
486 struct dk_softc *dksc = &cs->sc_dksc;
487 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
488 daddr_t bn;
489
490 KDASSERT(cs);
491
492 DPRINTF_FOLLOW(("cgdiodone(%p)\n", nbp));
493 DPRINTF(CGDB_IO, ("cgdiodone: bp %p bcount %d resid %d\n",
494 obp, obp->b_bcount, obp->b_resid));
495 DPRINTF(CGDB_IO, (" dev 0x%"PRIx64", nbp %p bn %" PRId64
496 " addr %p bcnt %d\n", nbp->b_dev, nbp, nbp->b_blkno, nbp->b_data,
497 nbp->b_bcount));
498 if (nbp->b_error != 0) {
499 obp->b_error = nbp->b_error;
500 DPRINTF(CGDB_IO, ("%s: error %d\n", dksc->sc_xname,
501 obp->b_error));
502 }
503
504 /* Perform the decryption if we are reading.
505 *
506 * Note: use the blocknumber from nbp, since it is what
507 * we used to encrypt the blocks.
508 */
509
510 if (nbp->b_flags & B_READ) {
511 bn = dbtob(nbp->b_blkno) / dg->dg_secsize;
512 cgd_cipher(cs, obp->b_data, obp->b_data, obp->b_bcount,
513 bn, dg->dg_secsize, CGD_CIPHER_DECRYPT);
514 }
515
516 /* If we allocated memory, free it now... */
517 if (nbp->b_data != obp->b_data)
518 cgd_putdata(dksc, nbp->b_data);
519
520 putiobuf(nbp);
521
522 /* Request is complete for whatever reason */
523 obp->b_resid = 0;
524 if (obp->b_error != 0)
525 obp->b_resid = obp->b_bcount;
526
527 /*
528 * copy the dev_t, finish the disk operation, and release the
529 * reference we're holding on to (from cgd_getsoftc() earlier)
530 */
531 dev = obp->b_dev;
532 dk_done(dksc, obp);
533 cgd_release(dev);
534
535 dk_start(dksc, NULL);
536 }
537
538 static int
539 cgd_dumpblocks(device_t dev, void *va, daddr_t blkno, int nblk)
540 {
541 struct cgd_softc *sc = device_private(dev);
542 struct dk_softc *dksc = &sc->sc_dksc;
543 struct disk_geom *dg = &dksc->sc_dkdev.dk_geom;
544 size_t nbytes, blksize;
545 void *buf;
546 int error;
547
548 /*
549 * dk_dump gives us units of disklabel sectors. Everything
550 * else in cgd uses units of diskgeom sectors. These had
551 * better agree; otherwise we need to figure out how to convert
552 * between them.
553 */
554 KASSERTMSG((dg->dg_secsize == dksc->sc_dkdev.dk_label->d_secsize),
555 "diskgeom secsize %"PRIu32" != disklabel secsize %"PRIu32,
556 dg->dg_secsize, dksc->sc_dkdev.dk_label->d_secsize);
557 blksize = dg->dg_secsize;
558
559 /*
560 * Compute the number of bytes in this request, which dk_dump
561 * has `helpfully' converted to a number of blocks for us.
562 */
563 nbytes = nblk*blksize;
564
565 /* Try to acquire a buffer to store the ciphertext. */
566 buf = cgd_getdata(dksc, nbytes);
567 if (buf == NULL)
568 /* Out of memory: give up. */
569 return ENOMEM;
570
571 /* Encrypt the caller's data into the temporary buffer. */
572 cgd_cipher(sc, buf, va, nbytes, blkno, blksize, CGD_CIPHER_ENCRYPT);
573
574 /* Pass it on to the underlying disk device. */
575 error = bdev_dump(sc->sc_tdev, blkno, buf, nbytes);
576
577 /* Release the buffer. */
578 cgd_putdata(dksc, buf);
579
580 /* Return any error from the underlying disk device. */
581 return error;
582 }
583
584 /* XXX: we should probably put these into dksubr.c, mostly */
585 static int
586 cgdread(dev_t dev, struct uio *uio, int flags)
587 {
588 struct cgd_softc *cs;
589 struct dk_softc *dksc;
590
591 DPRINTF_FOLLOW(("cgdread(0x%llx, %p, %d)\n",
592 (unsigned long long)dev, uio, flags));
593 GETCGD_SOFTC(cs, dev);
594 dksc = &cs->sc_dksc;
595 if (!DK_ATTACHED(dksc))
596 return ENXIO;
597 return physio(cgdstrategy, NULL, dev, B_READ, minphys, uio);
598 }
599
600 /* XXX: we should probably put these into dksubr.c, mostly */
601 static int
602 cgdwrite(dev_t dev, struct uio *uio, int flags)
603 {
604 struct cgd_softc *cs;
605 struct dk_softc *dksc;
606
607 DPRINTF_FOLLOW(("cgdwrite(0x%"PRIx64", %p, %d)\n", dev, uio, flags));
608 GETCGD_SOFTC(cs, dev);
609 dksc = &cs->sc_dksc;
610 if (!DK_ATTACHED(dksc))
611 return ENXIO;
612 return physio(cgdstrategy, NULL, dev, B_WRITE, minphys, uio);
613 }
614
615 static int
616 cgdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
617 {
618 struct cgd_softc *cs;
619 struct dk_softc *dksc;
620 int part = DISKPART(dev);
621 int pmask = 1 << part;
622
623 DPRINTF_FOLLOW(("cgdioctl(0x%"PRIx64", %ld, %p, %d, %p)\n",
624 dev, cmd, data, flag, l));
625
626 switch (cmd) {
627 case CGDIOCGET:
628 return cgd_ioctl_get(dev, data, l);
629 case CGDIOCSET:
630 case CGDIOCCLR:
631 if ((flag & FWRITE) == 0)
632 return EBADF;
633 /* FALLTHROUGH */
634 default:
635 GETCGD_SOFTC(cs, dev);
636 dksc = &cs->sc_dksc;
637 break;
638 }
639
640 switch (cmd) {
641 case CGDIOCSET:
642 if (DK_ATTACHED(dksc))
643 return EBUSY;
644 return cgd_ioctl_set(cs, data, l);
645 case CGDIOCCLR:
646 if (DK_BUSY(&cs->sc_dksc, pmask))
647 return EBUSY;
648 return cgd_ioctl_clr(cs, l);
649 case DIOCCACHESYNC:
650 /*
651 * XXX Do we really need to care about having a writable
652 * file descriptor here?
653 */
654 if ((flag & FWRITE) == 0)
655 return (EBADF);
656
657 /*
658 * We pass this call down to the underlying disk.
659 */
660 return VOP_IOCTL(cs->sc_tvn, cmd, data, flag, l->l_cred);
661 case DIOCGSTRATEGY:
662 case DIOCSSTRATEGY:
663 if (!DK_ATTACHED(dksc))
664 return ENOENT;
665 /*FALLTHROUGH*/
666 default:
667 return dk_ioctl(dksc, dev, cmd, data, flag, l);
668 case CGDIOCGET:
669 KASSERT(0);
670 return EINVAL;
671 }
672 }
673
674 static int
675 cgddump(dev_t dev, daddr_t blkno, void *va, size_t size)
676 {
677 struct cgd_softc *cs;
678
679 DPRINTF_FOLLOW(("cgddump(0x%"PRIx64", %" PRId64 ", %p, %lu)\n",
680 dev, blkno, va, (unsigned long)size));
681 GETCGD_SOFTC(cs, dev);
682 return dk_dump(&cs->sc_dksc, dev, blkno, va, size);
683 }
684
685 /*
686 * XXXrcd:
687 * for now we hardcode the maximum key length.
688 */
689 #define MAX_KEYSIZE 1024
690
691 static const struct {
692 const char *n;
693 int v;
694 int d;
695 } encblkno[] = {
696 { "encblkno", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
697 { "encblkno8", CGD_CIPHER_CBC_ENCBLKNO8, 1 },
698 { "encblkno1", CGD_CIPHER_CBC_ENCBLKNO1, 8 },
699 };
700
701 /* ARGSUSED */
702 static int
703 cgd_ioctl_set(struct cgd_softc *cs, void *data, struct lwp *l)
704 {
705 struct cgd_ioctl *ci = data;
706 struct vnode *vp;
707 int ret;
708 size_t i;
709 size_t keybytes; /* key length in bytes */
710 const char *cp;
711 struct pathbuf *pb;
712 char *inbuf;
713 struct dk_softc *dksc = &cs->sc_dksc;
714
715 cp = ci->ci_disk;
716
717 ret = pathbuf_copyin(ci->ci_disk, &pb);
718 if (ret != 0) {
719 return ret;
720 }
721 ret = dk_lookup(pb, l, &vp);
722 pathbuf_destroy(pb);
723 if (ret != 0) {
724 return ret;
725 }
726
727 inbuf = malloc(MAX_KEYSIZE, M_TEMP, M_WAITOK);
728
729 if ((ret = cgdinit(cs, cp, vp, l)) != 0)
730 goto bail;
731
732 (void)memset(inbuf, 0, MAX_KEYSIZE);
733 ret = copyinstr(ci->ci_alg, inbuf, 256, NULL);
734 if (ret)
735 goto bail;
736 cs->sc_cfuncs = cryptfuncs_find(inbuf);
737 if (!cs->sc_cfuncs) {
738 ret = EINVAL;
739 goto bail;
740 }
741
742 (void)memset(inbuf, 0, MAX_KEYSIZE);
743 ret = copyinstr(ci->ci_ivmethod, inbuf, MAX_KEYSIZE, NULL);
744 if (ret)
745 goto bail;
746
747 for (i = 0; i < __arraycount(encblkno); i++)
748 if (strcmp(encblkno[i].n, inbuf) == 0)
749 break;
750
751 if (i == __arraycount(encblkno)) {
752 ret = EINVAL;
753 goto bail;
754 }
755
756 keybytes = ci->ci_keylen / 8 + 1;
757 if (keybytes > MAX_KEYSIZE) {
758 ret = EINVAL;
759 goto bail;
760 }
761
762 (void)memset(inbuf, 0, MAX_KEYSIZE);
763 ret = copyin(ci->ci_key, inbuf, keybytes);
764 if (ret)
765 goto bail;
766
767 cs->sc_cdata.cf_blocksize = ci->ci_blocksize;
768 cs->sc_cdata.cf_mode = encblkno[i].v;
769 cs->sc_cdata.cf_keylen = ci->ci_keylen;
770 cs->sc_cdata.cf_priv = cs->sc_cfuncs->cf_init(ci->ci_keylen, inbuf,
771 &cs->sc_cdata.cf_blocksize);
772 if (cs->sc_cdata.cf_blocksize > CGD_MAXBLOCKSIZE) {
773 log(LOG_WARNING, "cgd: Disallowed cipher with blocksize %zu > %u\n",
774 cs->sc_cdata.cf_blocksize, CGD_MAXBLOCKSIZE);
775 cs->sc_cdata.cf_priv = NULL;
776 }
777
778 /*
779 * The blocksize is supposed to be in bytes. Unfortunately originally
780 * it was expressed in bits. For compatibility we maintain encblkno
781 * and encblkno8.
782 */
783 cs->sc_cdata.cf_blocksize /= encblkno[i].d;
784 (void)explicit_memset(inbuf, 0, MAX_KEYSIZE);
785 if (!cs->sc_cdata.cf_priv) {
786 ret = EINVAL; /* XXX is this the right error? */
787 goto bail;
788 }
789 free(inbuf, M_TEMP);
790
791 bufq_alloc(&dksc->sc_bufq, "fcfs", 0);
792
793 cs->sc_data = malloc(MAXPHYS, M_DEVBUF, M_WAITOK);
794 cs->sc_data_used = 0;
795
796 /* Attach the disk. */
797 dk_attach(dksc);
798 disk_attach(&dksc->sc_dkdev);
799
800 disk_set_info(dksc->sc_dev, &dksc->sc_dkdev, NULL);
801
802 /* Discover wedges on this disk. */
803 dkwedge_discover(&dksc->sc_dkdev);
804
805 return 0;
806
807 bail:
808 free(inbuf, M_TEMP);
809 (void)vn_close(vp, FREAD|FWRITE, l->l_cred);
810 return ret;
811 }
812
813 /* ARGSUSED */
814 static int
815 cgd_ioctl_clr(struct cgd_softc *cs, struct lwp *l)
816 {
817 struct dk_softc *dksc = &cs->sc_dksc;
818
819 if (!DK_ATTACHED(dksc))
820 return ENXIO;
821
822 /* Delete all of our wedges. */
823 dkwedge_delall(&dksc->sc_dkdev);
824
825 /* Kill off any queued buffers. */
826 dk_drain(dksc);
827 bufq_free(dksc->sc_bufq);
828
829 (void)vn_close(cs->sc_tvn, FREAD|FWRITE, l->l_cred);
830 cs->sc_cfuncs->cf_destroy(cs->sc_cdata.cf_priv);
831 free(cs->sc_tpath, M_DEVBUF);
832 free(cs->sc_data, M_DEVBUF);
833 cs->sc_data_used = 0;
834 dk_detach(dksc);
835 disk_detach(&dksc->sc_dkdev);
836
837 return 0;
838 }
839
840 static int
841 cgd_ioctl_get(dev_t dev, void *data, struct lwp *l)
842 {
843 struct cgd_softc *cs = getcgd_softc(dev);
844 struct cgd_user *cgu;
845 int unit;
846 struct dk_softc *dksc = &cs->sc_dksc;
847
848 unit = CGDUNIT(dev);
849 cgu = (struct cgd_user *)data;
850
851 DPRINTF_FOLLOW(("cgd_ioctl_get(0x%"PRIx64", %d, %p, %p)\n",
852 dev, unit, data, l));
853
854 if (cgu->cgu_unit == -1)
855 cgu->cgu_unit = unit;
856
857 if (cgu->cgu_unit < 0) {
858 cgd_release(dev);
859 return EINVAL; /* XXX: should this be ENXIO? */
860 }
861
862 cs = device_lookup_private(&cgd_cd, unit);
863 if (cs == NULL || !DK_ATTACHED(dksc)) {
864 cgu->cgu_dev = 0;
865 cgu->cgu_alg[0] = '\0';
866 cgu->cgu_blocksize = 0;
867 cgu->cgu_mode = 0;
868 cgu->cgu_keylen = 0;
869 }
870 else {
871 cgu->cgu_dev = cs->sc_tdev;
872 strlcpy(cgu->cgu_alg, cs->sc_cfuncs->cf_name,
873 sizeof(cgu->cgu_alg));
874 cgu->cgu_blocksize = cs->sc_cdata.cf_blocksize;
875 cgu->cgu_mode = cs->sc_cdata.cf_mode;
876 cgu->cgu_keylen = cs->sc_cdata.cf_keylen;
877 }
878 cgd_release(dev);
879 return 0;
880 }
881
882 static int
883 cgdinit(struct cgd_softc *cs, const char *cpath, struct vnode *vp,
884 struct lwp *l)
885 {
886 struct disk_geom *dg;
887 int ret;
888 char *tmppath;
889 uint64_t psize;
890 unsigned secsize;
891 struct dk_softc *dksc = &cs->sc_dksc;
892
893 cs->sc_tvn = vp;
894 cs->sc_tpath = NULL;
895
896 tmppath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
897 ret = copyinstr(cpath, tmppath, MAXPATHLEN, &cs->sc_tpathlen);
898 if (ret)
899 goto bail;
900 cs->sc_tpath = malloc(cs->sc_tpathlen, M_DEVBUF, M_WAITOK);
901 memcpy(cs->sc_tpath, tmppath, cs->sc_tpathlen);
902
903 cs->sc_tdev = vp->v_rdev;
904
905 if ((ret = getdisksize(vp, &psize, &secsize)) != 0)
906 goto bail;
907
908 if (psize == 0) {
909 ret = ENODEV;
910 goto bail;
911 }
912
913 /*
914 * XXX here we should probe the underlying device. If we
915 * are accessing a partition of type RAW_PART, then
916 * we should populate our initial geometry with the
917 * geometry that we discover from the device.
918 */
919 dg = &dksc->sc_dkdev.dk_geom;
920 memset(dg, 0, sizeof(*dg));
921 dg->dg_secperunit = psize;
922 dg->dg_secsize = secsize;
923 dg->dg_ntracks = 1;
924 dg->dg_nsectors = 1024 * 1024 / dg->dg_secsize;
925 dg->dg_ncylinders = dg->dg_secperunit / dg->dg_nsectors;
926
927 bail:
928 free(tmppath, M_TEMP);
929 if (ret && cs->sc_tpath)
930 free(cs->sc_tpath, M_DEVBUF);
931 return ret;
932 }
933
934 /*
935 * Our generic cipher entry point. This takes care of the
936 * IV mode and passes off the work to the specific cipher.
937 * We implement here the IV method ``encrypted block
938 * number''.
939 *
940 * For the encryption case, we accomplish this by setting
941 * up a struct uio where the first iovec of the source is
942 * the blocknumber and the first iovec of the dest is a
943 * sink. We then call the cipher with an IV of zero, and
944 * the right thing happens.
945 *
946 * For the decryption case, we use the same basic mechanism
947 * for symmetry, but we encrypt the block number in the
948 * first iovec.
949 *
950 * We mainly do this to avoid requiring the definition of
951 * an ECB mode.
952 *
953 * XXXrcd: for now we rely on our own crypto framework defined
954 * in dev/cgd_crypto.c. This will change when we
955 * get a generic kernel crypto framework.
956 */
957
958 static void
959 blkno2blkno_buf(char *sbuf, daddr_t blkno)
960 {
961 int i;
962
963 /* Set up the blkno in blkno_buf, here we do not care much
964 * about the final layout of the information as long as we
965 * can guarantee that each sector will have a different IV
966 * and that the endianness of the machine will not affect
967 * the representation that we have chosen.
968 *
969 * We choose this representation, because it does not rely
970 * on the size of buf (which is the blocksize of the cipher),
971 * but allows daddr_t to grow without breaking existing
972 * disks.
973 *
974 * Note that blkno2blkno_buf does not take a size as input,
975 * and hence must be called on a pre-zeroed buffer of length
976 * greater than or equal to sizeof(daddr_t).
977 */
978 for (i=0; i < sizeof(daddr_t); i++) {
979 *sbuf++ = blkno & 0xff;
980 blkno >>= 8;
981 }
982 }
983
984 static void
985 cgd_cipher(struct cgd_softc *cs, void *dstv, void *srcv,
986 size_t len, daddr_t blkno, size_t secsize, int dir)
987 {
988 char *dst = dstv;
989 char *src = srcv;
990 cfunc_cipher *cipher = cs->sc_cfuncs->cf_cipher;
991 struct uio dstuio;
992 struct uio srcuio;
993 struct iovec dstiov[2];
994 struct iovec srciov[2];
995 size_t blocksize = cs->sc_cdata.cf_blocksize;
996 size_t todo;
997 char sink[CGD_MAXBLOCKSIZE];
998 char zero_iv[CGD_MAXBLOCKSIZE];
999 char blkno_buf[CGD_MAXBLOCKSIZE];
1000
1001 DPRINTF_FOLLOW(("cgd_cipher() dir=%d\n", dir));
1002
1003 DIAGCONDPANIC(len % blocksize != 0,
1004 ("cgd_cipher: len %% blocksize != 0"));
1005
1006 /* ensure that sizeof(daddr_t) <= blocksize (for encblkno IVing) */
1007 DIAGCONDPANIC(sizeof(daddr_t) > blocksize,
1008 ("cgd_cipher: sizeof(daddr_t) > blocksize"));
1009
1010 memset(zero_iv, 0x0, blocksize);
1011
1012 dstuio.uio_iov = dstiov;
1013 dstuio.uio_iovcnt = 2;
1014
1015 srcuio.uio_iov = srciov;
1016 srcuio.uio_iovcnt = 2;
1017
1018 dstiov[0].iov_base = sink;
1019 dstiov[0].iov_len = blocksize;
1020 srciov[0].iov_base = blkno_buf;
1021 srciov[0].iov_len = blocksize;
1022
1023 for (; len > 0; len -= todo) {
1024 todo = MIN(len, secsize);
1025
1026 dstiov[1].iov_base = dst;
1027 srciov[1].iov_base = src;
1028 dstiov[1].iov_len = todo;
1029 srciov[1].iov_len = todo;
1030
1031 memset(blkno_buf, 0x0, blocksize);
1032 blkno2blkno_buf(blkno_buf, blkno);
1033 if (dir == CGD_CIPHER_DECRYPT) {
1034 dstuio.uio_iovcnt = 1;
1035 srcuio.uio_iovcnt = 1;
1036 IFDEBUG(CGDB_CRYPTO, hexprint("step 0: blkno_buf",
1037 blkno_buf, blocksize));
1038 cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio,
1039 zero_iv, CGD_CIPHER_ENCRYPT);
1040 memcpy(blkno_buf, sink, blocksize);
1041 dstuio.uio_iovcnt = 2;
1042 srcuio.uio_iovcnt = 2;
1043 }
1044
1045 IFDEBUG(CGDB_CRYPTO, hexprint("step 1: blkno_buf",
1046 blkno_buf, blocksize));
1047 cipher(cs->sc_cdata.cf_priv, &dstuio, &srcuio, zero_iv, dir);
1048 IFDEBUG(CGDB_CRYPTO, hexprint("step 2: sink",
1049 sink, blocksize));
1050
1051 dst += todo;
1052 src += todo;
1053 blkno++;
1054 }
1055 }
1056
1057 #ifdef DEBUG
1058 static void
1059 hexprint(const char *start, void *buf, int len)
1060 {
1061 char *c = buf;
1062
1063 DIAGCONDPANIC(len < 0, ("hexprint: called with len < 0"));
1064 printf("%s: len=%06d 0x", start, len);
1065 while (len--)
1066 printf("%02x", (unsigned char) *c++);
1067 }
1068 #endif
1069
1070 MODULE(MODULE_CLASS_DRIVER, cgd, "dk_subr");
1071
1072 #ifdef _MODULE
1073 #include "ioconf.c"
1074 #endif
1075
1076 static int
1077 cgd_modcmd(modcmd_t cmd, void *arg)
1078 {
1079 int error = 0;
1080
1081 #ifdef _MODULE
1082 devmajor_t bmajor = -1, cmajor = -1;
1083 #endif
1084
1085 switch (cmd) {
1086 case MODULE_CMD_INIT:
1087 #ifdef _MODULE
1088 /*
1089 * Insert the driver into the autoconf database
1090 */
1091 error = config_init_component(cfdriver_ioconf_cgd,
1092 cfattach_ioconf_cgd, cfdata_ioconf_cgd);
1093 if (error) {
1094 aprint_error("%s: unable to init component"
1095 ", error %d", cgd_cd.cd_name, error);
1096 break;
1097 }
1098
1099 /*
1100 * Attach the {b,c}devsw's
1101 */
1102 error = devsw_attach("cgd", &cgd_bdevsw, &bmajor,
1103 &cgd_cdevsw, &cmajor);
1104
1105 /*
1106 * If devsw_attach fails, remove from autoconf database
1107 */
1108 if (error) {
1109 config_fini_component(cfdriver_ioconf_cgd,
1110 cfattach_ioconf_cgd, cfdata_ioconf_cgd);
1111 aprint_error("%s: unable to attach devsw"
1112 ", error %d", cgd_cd.cd_name, error);
1113 }
1114 #endif
1115 break;
1116
1117 case MODULE_CMD_FINI:
1118 #ifdef _MODULE
1119 /*
1120 * Remove {b,c}devsw's
1121 */
1122 devsw_detach(&cgd_bdevsw, &cgd_cdevsw);
1123
1124 /*
1125 * Now remove device from autoconf database
1126 */
1127 error = config_fini_component(cfdriver_ioconf_cgd,
1128 cfattach_ioconf_cgd, cfdata_ioconf_cgd);
1129
1130 /*
1131 * If removal fails, re-attach our {b,c}devsw's
1132 */
1133 if (error) {
1134 aprint_error("%s: failed to remove from autoconf"
1135 ", error %d", cgd_cd.cd_name, error);
1136 devsw_attach("cgd", &cgd_bdevsw, &bmajor,
1137 &cgd_cdevsw, &cmajor);
1138 }
1139 #endif
1140 break;
1141
1142 case MODULE_CMD_STAT:
1143 return ENOTTY;
1144
1145 default:
1146 return ENOTTY;
1147 }
1148
1149 return error;
1150 }
1151