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