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