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