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