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