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