1 /*- 2 * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <sys/lock.h> 35 #include <sys/mutex.h> 36 #include <sys/bio.h> 37 #include <sys/sysctl.h> 38 #include <sys/malloc.h> 39 #include <sys/kthread.h> 40 #include <sys/proc.h> 41 #include <sys/sched.h> 42 #include <sys/uio.h> 43 44 #include <vm/uma.h> 45 46 #include <geom/geom.h> 47 #include <geom/eli/g_eli.h> 48 49 50 MALLOC_DECLARE(M_ELI); 51 52 53 static void 54 g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp) 55 { 56 struct g_eli_metadata md; 57 struct g_provider *pp; 58 const char *name; 59 u_char *key, mkey[G_ELI_DATAIVKEYLEN]; 60 int *nargs, *detach, *readonly; 61 int keysize, error; 62 u_int nkey; 63 64 g_topology_assert(); 65 66 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 67 if (nargs == NULL) { 68 gctl_error(req, "No '%s' argument.", "nargs"); 69 return; 70 } 71 if (*nargs != 1) { 72 gctl_error(req, "Invalid number of arguments."); 73 return; 74 } 75 76 detach = gctl_get_paraml(req, "detach", sizeof(*detach)); 77 if (detach == NULL) { 78 gctl_error(req, "No '%s' argument.", "detach"); 79 return; 80 } 81 82 readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly)); 83 if (readonly == NULL) { 84 gctl_error(req, "No '%s' argument.", "readonly"); 85 return; 86 } 87 88 name = gctl_get_asciiparam(req, "arg0"); 89 if (name == NULL) { 90 gctl_error(req, "No 'arg%u' argument.", 0); 91 return; 92 } 93 if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 94 name += strlen("/dev/"); 95 pp = g_provider_by_name(name); 96 if (pp == NULL) { 97 gctl_error(req, "Provider %s is invalid.", name); 98 return; 99 } 100 error = g_eli_read_metadata(mp, pp, &md); 101 if (error != 0) { 102 gctl_error(req, "Cannot read metadata from %s (error=%d).", 103 name, error); 104 return; 105 } 106 if (md.md_keys == 0x00) { 107 bzero(&md, sizeof(md)); 108 gctl_error(req, "No valid keys on %s.", pp->name); 109 return; 110 } 111 112 key = gctl_get_param(req, "key", &keysize); 113 if (key == NULL || keysize != G_ELI_USERKEYLEN) { 114 bzero(&md, sizeof(md)); 115 gctl_error(req, "No '%s' argument.", "key"); 116 return; 117 } 118 119 error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); 120 bzero(key, keysize); 121 if (error == -1) { 122 bzero(&md, sizeof(md)); 123 gctl_error(req, "Wrong key for %s.", pp->name); 124 return; 125 } else if (error > 0) { 126 bzero(&md, sizeof(md)); 127 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", 128 pp->name, error); 129 return; 130 } 131 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); 132 133 if (*detach && *readonly) { 134 bzero(&md, sizeof(md)); 135 gctl_error(req, "Options -d and -r are mutually exclusive."); 136 return; 137 } 138 if (*detach) 139 md.md_flags |= G_ELI_FLAG_WO_DETACH; 140 if (*readonly) 141 md.md_flags |= G_ELI_FLAG_RO; 142 g_eli_create(req, mp, pp, &md, mkey, nkey); 143 bzero(mkey, sizeof(mkey)); 144 bzero(&md, sizeof(md)); 145 } 146 147 static struct g_eli_softc * 148 g_eli_find_device(struct g_class *mp, const char *prov) 149 { 150 struct g_eli_softc *sc; 151 struct g_geom *gp; 152 struct g_provider *pp; 153 struct g_consumer *cp; 154 155 if (strncmp(prov, "/dev/", strlen("/dev/")) == 0) 156 prov += strlen("/dev/"); 157 LIST_FOREACH(gp, &mp->geom, geom) { 158 sc = gp->softc; 159 if (sc == NULL) 160 continue; 161 pp = LIST_FIRST(&gp->provider); 162 if (pp != NULL && strcmp(pp->name, prov) == 0) 163 return (sc); 164 cp = LIST_FIRST(&gp->consumer); 165 if (cp != NULL && cp->provider != NULL && 166 strcmp(cp->provider->name, prov) == 0) { 167 return (sc); 168 } 169 } 170 return (NULL); 171 } 172 173 static void 174 g_eli_ctl_detach(struct gctl_req *req, struct g_class *mp) 175 { 176 struct g_eli_softc *sc; 177 int *force, *last, *nargs, error; 178 const char *prov; 179 char param[16]; 180 int i; 181 182 g_topology_assert(); 183 184 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 185 if (nargs == NULL) { 186 gctl_error(req, "No '%s' argument.", "nargs"); 187 return; 188 } 189 if (*nargs <= 0) { 190 gctl_error(req, "Missing device(s)."); 191 return; 192 } 193 force = gctl_get_paraml(req, "force", sizeof(*force)); 194 if (force == NULL) { 195 gctl_error(req, "No '%s' argument.", "force"); 196 return; 197 } 198 last = gctl_get_paraml(req, "last", sizeof(*last)); 199 if (last == NULL) { 200 gctl_error(req, "No '%s' argument.", "last"); 201 return; 202 } 203 204 for (i = 0; i < *nargs; i++) { 205 snprintf(param, sizeof(param), "arg%d", i); 206 prov = gctl_get_asciiparam(req, param); 207 if (prov == NULL) { 208 gctl_error(req, "No 'arg%d' argument.", i); 209 return; 210 } 211 sc = g_eli_find_device(mp, prov); 212 if (sc == NULL) { 213 gctl_error(req, "No such device: %s.", prov); 214 return; 215 } 216 if (*last) { 217 sc->sc_flags |= G_ELI_FLAG_RW_DETACH; 218 sc->sc_geom->access = g_eli_access; 219 } else { 220 error = g_eli_destroy(sc, *force ? TRUE : FALSE); 221 if (error != 0) { 222 gctl_error(req, 223 "Cannot destroy device %s (error=%d).", 224 sc->sc_name, error); 225 return; 226 } 227 } 228 } 229 } 230 231 static void 232 g_eli_ctl_onetime(struct gctl_req *req, struct g_class *mp) 233 { 234 struct g_eli_metadata md; 235 struct g_provider *pp; 236 const char *name; 237 intmax_t *keylen, *sectorsize; 238 u_char mkey[G_ELI_DATAIVKEYLEN]; 239 int *nargs, *detach, *notrim; 240 241 g_topology_assert(); 242 bzero(&md, sizeof(md)); 243 244 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 245 if (nargs == NULL) { 246 gctl_error(req, "No '%s' argument.", "nargs"); 247 return; 248 } 249 if (*nargs != 1) { 250 gctl_error(req, "Invalid number of arguments."); 251 return; 252 } 253 254 strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic)); 255 md.md_version = G_ELI_VERSION; 256 md.md_flags |= G_ELI_FLAG_ONETIME; 257 258 detach = gctl_get_paraml(req, "detach", sizeof(*detach)); 259 if (detach != NULL && *detach) 260 md.md_flags |= G_ELI_FLAG_WO_DETACH; 261 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim)); 262 if (notrim != NULL && *notrim) 263 md.md_flags |= G_ELI_FLAG_NODELETE; 264 265 md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1; 266 name = gctl_get_asciiparam(req, "aalgo"); 267 if (name == NULL) { 268 gctl_error(req, "No '%s' argument.", "aalgo"); 269 return; 270 } 271 if (*name != '\0') { 272 md.md_aalgo = g_eli_str2aalgo(name); 273 if (md.md_aalgo >= CRYPTO_ALGORITHM_MIN && 274 md.md_aalgo <= CRYPTO_ALGORITHM_MAX) { 275 md.md_flags |= G_ELI_FLAG_AUTH; 276 } else { 277 /* 278 * For backward compatibility, check if the -a option 279 * was used to provide encryption algorithm. 280 */ 281 md.md_ealgo = g_eli_str2ealgo(name); 282 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN || 283 md.md_ealgo > CRYPTO_ALGORITHM_MAX) { 284 gctl_error(req, 285 "Invalid authentication algorithm."); 286 return; 287 } else { 288 gctl_error(req, "warning: The -e option, not " 289 "the -a option is now used to specify " 290 "encryption algorithm to use."); 291 } 292 } 293 } 294 295 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN || 296 md.md_ealgo > CRYPTO_ALGORITHM_MAX) { 297 name = gctl_get_asciiparam(req, "ealgo"); 298 if (name == NULL) { 299 gctl_error(req, "No '%s' argument.", "ealgo"); 300 return; 301 } 302 md.md_ealgo = g_eli_str2ealgo(name); 303 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN || 304 md.md_ealgo > CRYPTO_ALGORITHM_MAX) { 305 gctl_error(req, "Invalid encryption algorithm."); 306 return; 307 } 308 } 309 310 keylen = gctl_get_paraml(req, "keylen", sizeof(*keylen)); 311 if (keylen == NULL) { 312 gctl_error(req, "No '%s' argument.", "keylen"); 313 return; 314 } 315 md.md_keylen = g_eli_keylen(md.md_ealgo, *keylen); 316 if (md.md_keylen == 0) { 317 gctl_error(req, "Invalid '%s' argument.", "keylen"); 318 return; 319 } 320 321 /* Not important here. */ 322 md.md_provsize = 0; 323 /* Not important here. */ 324 bzero(md.md_salt, sizeof(md.md_salt)); 325 326 md.md_keys = 0x01; 327 arc4rand(mkey, sizeof(mkey), 0); 328 329 /* Not important here. */ 330 bzero(md.md_hash, sizeof(md.md_hash)); 331 332 name = gctl_get_asciiparam(req, "arg0"); 333 if (name == NULL) { 334 gctl_error(req, "No 'arg%u' argument.", 0); 335 return; 336 } 337 if (strncmp(name, "/dev/", strlen("/dev/")) == 0) 338 name += strlen("/dev/"); 339 pp = g_provider_by_name(name); 340 if (pp == NULL) { 341 gctl_error(req, "Provider %s is invalid.", name); 342 return; 343 } 344 345 sectorsize = gctl_get_paraml(req, "sectorsize", sizeof(*sectorsize)); 346 if (sectorsize == NULL) { 347 gctl_error(req, "No '%s' argument.", "sectorsize"); 348 return; 349 } 350 if (*sectorsize == 0) 351 md.md_sectorsize = pp->sectorsize; 352 else { 353 if (*sectorsize < 0 || (*sectorsize % pp->sectorsize) != 0) { 354 gctl_error(req, "Invalid sector size."); 355 return; 356 } 357 if (*sectorsize > PAGE_SIZE) { 358 gctl_error(req, "warning: Using sectorsize bigger than " 359 "the page size!"); 360 } 361 md.md_sectorsize = *sectorsize; 362 } 363 364 g_eli_create(req, mp, pp, &md, mkey, -1); 365 bzero(mkey, sizeof(mkey)); 366 bzero(&md, sizeof(md)); 367 } 368 369 static void 370 g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp) 371 { 372 struct g_eli_softc *sc; 373 struct g_eli_metadata md; 374 struct g_provider *pp; 375 struct g_consumer *cp; 376 char param[16]; 377 const char *prov; 378 u_char *sector; 379 int *nargs, *boot, *noboot, *trim, *notrim; 380 int zero, error, changed; 381 u_int i; 382 383 g_topology_assert(); 384 385 changed = 0; 386 zero = 0; 387 388 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 389 if (nargs == NULL) { 390 gctl_error(req, "No '%s' argument.", "nargs"); 391 return; 392 } 393 if (*nargs <= 0) { 394 gctl_error(req, "Missing device(s)."); 395 return; 396 } 397 398 boot = gctl_get_paraml(req, "boot", sizeof(*boot)); 399 if (boot == NULL) 400 boot = &zero; 401 noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot)); 402 if (noboot == NULL) 403 noboot = &zero; 404 if (*boot && *noboot) { 405 gctl_error(req, "Options -b and -B are mutually exclusive."); 406 return; 407 } 408 if (*boot || *noboot) 409 changed = 1; 410 411 trim = gctl_get_paraml(req, "trim", sizeof(*trim)); 412 if (trim == NULL) 413 trim = &zero; 414 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim)); 415 if (notrim == NULL) 416 notrim = &zero; 417 if (*trim && *notrim) { 418 gctl_error(req, "Options -t and -T are mutually exclusive."); 419 return; 420 } 421 if (*trim || *notrim) 422 changed = 1; 423 424 if (!changed) { 425 gctl_error(req, "No option given."); 426 return; 427 } 428 429 for (i = 0; i < *nargs; i++) { 430 snprintf(param, sizeof(param), "arg%d", i); 431 prov = gctl_get_asciiparam(req, param); 432 if (prov == NULL) { 433 gctl_error(req, "No 'arg%d' argument.", i); 434 return; 435 } 436 sc = g_eli_find_device(mp, prov); 437 if (sc == NULL) { 438 /* 439 * We ignore not attached providers, userland part will 440 * take care of them. 441 */ 442 G_ELI_DEBUG(1, "Skipping configuration of not attached " 443 "provider %s.", prov); 444 continue; 445 } 446 if (sc->sc_flags & G_ELI_FLAG_RO) { 447 gctl_error(req, "Cannot change configuration of " 448 "read-only provider %s.", prov); 449 continue; 450 } 451 452 if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) { 453 G_ELI_DEBUG(1, "BOOT flag already configured for %s.", 454 prov); 455 continue; 456 } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) { 457 G_ELI_DEBUG(1, "BOOT flag not configured for %s.", 458 prov); 459 continue; 460 } 461 462 if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) { 463 G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.", 464 prov); 465 continue; 466 } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) { 467 G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.", 468 prov); 469 continue; 470 } 471 472 if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) { 473 /* 474 * ONETIME providers don't write metadata to 475 * disk, so don't try reading it. This means 476 * we're bit-flipping uninitialized memory in md 477 * below, but that's OK; we don't do anything 478 * with it later. 479 */ 480 cp = LIST_FIRST(&sc->sc_geom->consumer); 481 pp = cp->provider; 482 error = g_eli_read_metadata(mp, pp, &md); 483 if (error != 0) { 484 gctl_error(req, 485 "Cannot read metadata from %s (error=%d).", 486 prov, error); 487 continue; 488 } 489 } 490 491 if (*boot) { 492 md.md_flags |= G_ELI_FLAG_BOOT; 493 sc->sc_flags |= G_ELI_FLAG_BOOT; 494 } else if (*noboot) { 495 md.md_flags &= ~G_ELI_FLAG_BOOT; 496 sc->sc_flags &= ~G_ELI_FLAG_BOOT; 497 } 498 499 if (*notrim) { 500 md.md_flags |= G_ELI_FLAG_NODELETE; 501 sc->sc_flags |= G_ELI_FLAG_NODELETE; 502 } else if (*trim) { 503 md.md_flags &= ~G_ELI_FLAG_NODELETE; 504 sc->sc_flags &= ~G_ELI_FLAG_NODELETE; 505 } 506 507 if (sc->sc_flags & G_ELI_FLAG_ONETIME) { 508 /* There's no metadata on disk so we are done here. */ 509 continue; 510 } 511 512 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); 513 eli_metadata_encode(&md, sector); 514 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 515 pp->sectorsize); 516 if (error != 0) { 517 gctl_error(req, 518 "Cannot store metadata on %s (error=%d).", 519 prov, error); 520 } 521 bzero(&md, sizeof(md)); 522 bzero(sector, pp->sectorsize); 523 free(sector, M_ELI); 524 } 525 } 526 527 static void 528 g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp) 529 { 530 struct g_eli_softc *sc; 531 struct g_eli_metadata md; 532 struct g_provider *pp; 533 struct g_consumer *cp; 534 const char *name; 535 u_char *key, *mkeydst, *sector; 536 intmax_t *valp; 537 int keysize, nkey, error; 538 539 g_topology_assert(); 540 541 name = gctl_get_asciiparam(req, "arg0"); 542 if (name == NULL) { 543 gctl_error(req, "No 'arg%u' argument.", 0); 544 return; 545 } 546 sc = g_eli_find_device(mp, name); 547 if (sc == NULL) { 548 gctl_error(req, "Provider %s is invalid.", name); 549 return; 550 } 551 if (sc->sc_flags & G_ELI_FLAG_RO) { 552 gctl_error(req, "Cannot change keys for read-only provider."); 553 return; 554 } 555 cp = LIST_FIRST(&sc->sc_geom->consumer); 556 pp = cp->provider; 557 558 error = g_eli_read_metadata(mp, pp, &md); 559 if (error != 0) { 560 gctl_error(req, "Cannot read metadata from %s (error=%d).", 561 name, error); 562 return; 563 } 564 565 valp = gctl_get_paraml(req, "keyno", sizeof(*valp)); 566 if (valp == NULL) { 567 gctl_error(req, "No '%s' argument.", "keyno"); 568 return; 569 } 570 if (*valp != -1) 571 nkey = *valp; 572 else 573 nkey = sc->sc_nkey; 574 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) { 575 gctl_error(req, "Invalid '%s' argument.", "keyno"); 576 return; 577 } 578 579 valp = gctl_get_paraml(req, "iterations", sizeof(*valp)); 580 if (valp == NULL) { 581 gctl_error(req, "No '%s' argument.", "iterations"); 582 return; 583 } 584 /* Check if iterations number should and can be changed. */ 585 if (*valp != -1) { 586 if (bitcount32(md.md_keys) != 1) { 587 gctl_error(req, "To be able to use '-i' option, only " 588 "one key can be defined."); 589 return; 590 } 591 if (md.md_keys != (1 << nkey)) { 592 gctl_error(req, "Only already defined key can be " 593 "changed when '-i' option is used."); 594 return; 595 } 596 md.md_iterations = *valp; 597 } 598 599 key = gctl_get_param(req, "key", &keysize); 600 if (key == NULL || keysize != G_ELI_USERKEYLEN) { 601 bzero(&md, sizeof(md)); 602 gctl_error(req, "No '%s' argument.", "key"); 603 return; 604 } 605 606 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN; 607 md.md_keys |= (1 << nkey); 608 609 bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey)); 610 611 /* Encrypt Master Key with the new key. */ 612 error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst); 613 bzero(key, keysize); 614 if (error != 0) { 615 bzero(&md, sizeof(md)); 616 gctl_error(req, "Cannot encrypt Master Key (error=%d).", error); 617 return; 618 } 619 620 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); 621 /* Store metadata with fresh key. */ 622 eli_metadata_encode(&md, sector); 623 bzero(&md, sizeof(md)); 624 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 625 pp->sectorsize); 626 bzero(sector, pp->sectorsize); 627 free(sector, M_ELI); 628 if (error != 0) { 629 gctl_error(req, "Cannot store metadata on %s (error=%d).", 630 pp->name, error); 631 return; 632 } 633 G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name); 634 } 635 636 static void 637 g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp) 638 { 639 struct g_eli_softc *sc; 640 struct g_eli_metadata md; 641 struct g_provider *pp; 642 struct g_consumer *cp; 643 const char *name; 644 u_char *mkeydst, *sector; 645 intmax_t *valp; 646 size_t keysize; 647 int error, nkey, *all, *force; 648 u_int i; 649 650 g_topology_assert(); 651 652 nkey = 0; /* fixes causeless gcc warning */ 653 654 name = gctl_get_asciiparam(req, "arg0"); 655 if (name == NULL) { 656 gctl_error(req, "No 'arg%u' argument.", 0); 657 return; 658 } 659 sc = g_eli_find_device(mp, name); 660 if (sc == NULL) { 661 gctl_error(req, "Provider %s is invalid.", name); 662 return; 663 } 664 if (sc->sc_flags & G_ELI_FLAG_RO) { 665 gctl_error(req, "Cannot delete keys for read-only provider."); 666 return; 667 } 668 cp = LIST_FIRST(&sc->sc_geom->consumer); 669 pp = cp->provider; 670 671 error = g_eli_read_metadata(mp, pp, &md); 672 if (error != 0) { 673 gctl_error(req, "Cannot read metadata from %s (error=%d).", 674 name, error); 675 return; 676 } 677 678 all = gctl_get_paraml(req, "all", sizeof(*all)); 679 if (all == NULL) { 680 gctl_error(req, "No '%s' argument.", "all"); 681 return; 682 } 683 684 if (*all) { 685 mkeydst = md.md_mkeys; 686 keysize = sizeof(md.md_mkeys); 687 } else { 688 force = gctl_get_paraml(req, "force", sizeof(*force)); 689 if (force == NULL) { 690 gctl_error(req, "No '%s' argument.", "force"); 691 return; 692 } 693 694 valp = gctl_get_paraml(req, "keyno", sizeof(*valp)); 695 if (valp == NULL) { 696 gctl_error(req, "No '%s' argument.", "keyno"); 697 return; 698 } 699 if (*valp != -1) 700 nkey = *valp; 701 else 702 nkey = sc->sc_nkey; 703 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) { 704 gctl_error(req, "Invalid '%s' argument.", "keyno"); 705 return; 706 } 707 if (!(md.md_keys & (1 << nkey)) && !*force) { 708 gctl_error(req, "Master Key %u is not set.", nkey); 709 return; 710 } 711 md.md_keys &= ~(1 << nkey); 712 if (md.md_keys == 0 && !*force) { 713 gctl_error(req, "This is the last Master Key. Use '-f' " 714 "flag if you really want to remove it."); 715 return; 716 } 717 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN; 718 keysize = G_ELI_MKEYLEN; 719 } 720 721 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO); 722 for (i = 0; i <= g_eli_overwrites; i++) { 723 if (i == g_eli_overwrites) 724 bzero(mkeydst, keysize); 725 else 726 arc4rand(mkeydst, keysize, 0); 727 /* Store metadata with destroyed key. */ 728 eli_metadata_encode(&md, sector); 729 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector, 730 pp->sectorsize); 731 if (error != 0) { 732 G_ELI_DEBUG(0, "Cannot store metadata on %s " 733 "(error=%d).", pp->name, error); 734 } 735 /* 736 * Flush write cache so we don't overwrite data N times in cache 737 * and only once on disk. 738 */ 739 (void)g_io_flush(cp); 740 } 741 bzero(&md, sizeof(md)); 742 bzero(sector, pp->sectorsize); 743 free(sector, M_ELI); 744 if (*all) 745 G_ELI_DEBUG(1, "All keys removed from %s.", pp->name); 746 else 747 G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name); 748 } 749 750 static void 751 g_eli_suspend_one(struct g_eli_softc *sc, struct gctl_req *req) 752 { 753 struct g_eli_worker *wr; 754 755 g_topology_assert(); 756 757 KASSERT(sc != NULL, ("NULL sc")); 758 759 if (sc->sc_flags & G_ELI_FLAG_ONETIME) { 760 gctl_error(req, 761 "Device %s is using one-time key, suspend not supported.", 762 sc->sc_name); 763 return; 764 } 765 766 mtx_lock(&sc->sc_queue_mtx); 767 if (sc->sc_flags & G_ELI_FLAG_SUSPEND) { 768 mtx_unlock(&sc->sc_queue_mtx); 769 gctl_error(req, "Device %s already suspended.", 770 sc->sc_name); 771 return; 772 } 773 sc->sc_flags |= G_ELI_FLAG_SUSPEND; 774 wakeup(sc); 775 for (;;) { 776 LIST_FOREACH(wr, &sc->sc_workers, w_next) { 777 if (wr->w_active) 778 break; 779 } 780 if (wr == NULL) 781 break; 782 /* Not all threads suspended. */ 783 msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO, 784 "geli:suspend", 0); 785 } 786 /* 787 * Clear sensitive data on suspend, they will be recovered on resume. 788 */ 789 bzero(sc->sc_mkey, sizeof(sc->sc_mkey)); 790 g_eli_key_destroy(sc); 791 bzero(sc->sc_akey, sizeof(sc->sc_akey)); 792 bzero(&sc->sc_akeyctx, sizeof(sc->sc_akeyctx)); 793 bzero(sc->sc_ivkey, sizeof(sc->sc_ivkey)); 794 bzero(&sc->sc_ivctx, sizeof(sc->sc_ivctx)); 795 mtx_unlock(&sc->sc_queue_mtx); 796 G_ELI_DEBUG(0, "Device %s has been suspended.", sc->sc_name); 797 } 798 799 static void 800 g_eli_ctl_suspend(struct gctl_req *req, struct g_class *mp) 801 { 802 struct g_eli_softc *sc; 803 int *all, *nargs; 804 805 g_topology_assert(); 806 807 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 808 if (nargs == NULL) { 809 gctl_error(req, "No '%s' argument.", "nargs"); 810 return; 811 } 812 all = gctl_get_paraml(req, "all", sizeof(*all)); 813 if (all == NULL) { 814 gctl_error(req, "No '%s' argument.", "all"); 815 return; 816 } 817 if (!*all && *nargs == 0) { 818 gctl_error(req, "Too few arguments."); 819 return; 820 } 821 822 if (*all) { 823 struct g_geom *gp, *gp2; 824 825 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { 826 sc = gp->softc; 827 if (sc->sc_flags & G_ELI_FLAG_ONETIME) { 828 G_ELI_DEBUG(0, 829 "Device %s is using one-time key, suspend not supported, skipping.", 830 sc->sc_name); 831 continue; 832 } 833 g_eli_suspend_one(sc, req); 834 } 835 } else { 836 const char *prov; 837 char param[16]; 838 int i; 839 840 for (i = 0; i < *nargs; i++) { 841 snprintf(param, sizeof(param), "arg%d", i); 842 prov = gctl_get_asciiparam(req, param); 843 if (prov == NULL) { 844 G_ELI_DEBUG(0, "No 'arg%d' argument.", i); 845 continue; 846 } 847 848 sc = g_eli_find_device(mp, prov); 849 if (sc == NULL) { 850 G_ELI_DEBUG(0, "No such provider: %s.", prov); 851 continue; 852 } 853 g_eli_suspend_one(sc, req); 854 } 855 } 856 } 857 858 static void 859 g_eli_ctl_resume(struct gctl_req *req, struct g_class *mp) 860 { 861 struct g_eli_metadata md; 862 struct g_eli_softc *sc; 863 struct g_provider *pp; 864 struct g_consumer *cp; 865 const char *name; 866 u_char *key, mkey[G_ELI_DATAIVKEYLEN]; 867 int *nargs, keysize, error; 868 u_int nkey; 869 870 g_topology_assert(); 871 872 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 873 if (nargs == NULL) { 874 gctl_error(req, "No '%s' argument.", "nargs"); 875 return; 876 } 877 if (*nargs != 1) { 878 gctl_error(req, "Invalid number of arguments."); 879 return; 880 } 881 882 name = gctl_get_asciiparam(req, "arg0"); 883 if (name == NULL) { 884 gctl_error(req, "No 'arg%u' argument.", 0); 885 return; 886 } 887 sc = g_eli_find_device(mp, name); 888 if (sc == NULL) { 889 gctl_error(req, "Provider %s is invalid.", name); 890 return; 891 } 892 cp = LIST_FIRST(&sc->sc_geom->consumer); 893 pp = cp->provider; 894 error = g_eli_read_metadata(mp, pp, &md); 895 if (error != 0) { 896 gctl_error(req, "Cannot read metadata from %s (error=%d).", 897 name, error); 898 return; 899 } 900 if (md.md_keys == 0x00) { 901 bzero(&md, sizeof(md)); 902 gctl_error(req, "No valid keys on %s.", pp->name); 903 return; 904 } 905 906 key = gctl_get_param(req, "key", &keysize); 907 if (key == NULL || keysize != G_ELI_USERKEYLEN) { 908 bzero(&md, sizeof(md)); 909 gctl_error(req, "No '%s' argument.", "key"); 910 return; 911 } 912 913 error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); 914 bzero(key, keysize); 915 if (error == -1) { 916 bzero(&md, sizeof(md)); 917 gctl_error(req, "Wrong key for %s.", pp->name); 918 return; 919 } else if (error > 0) { 920 bzero(&md, sizeof(md)); 921 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", 922 pp->name, error); 923 return; 924 } 925 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); 926 927 mtx_lock(&sc->sc_queue_mtx); 928 if (!(sc->sc_flags & G_ELI_FLAG_SUSPEND)) 929 gctl_error(req, "Device %s is not suspended.", name); 930 else { 931 /* Restore sc_mkey, sc_ekeys, sc_akey and sc_ivkey. */ 932 g_eli_mkey_propagate(sc, mkey); 933 sc->sc_flags &= ~G_ELI_FLAG_SUSPEND; 934 G_ELI_DEBUG(1, "Resumed %s.", pp->name); 935 wakeup(sc); 936 } 937 mtx_unlock(&sc->sc_queue_mtx); 938 bzero(mkey, sizeof(mkey)); 939 bzero(&md, sizeof(md)); 940 } 941 942 static int 943 g_eli_kill_one(struct g_eli_softc *sc) 944 { 945 struct g_provider *pp; 946 struct g_consumer *cp; 947 int error = 0; 948 949 g_topology_assert(); 950 951 if (sc == NULL) 952 return (ENOENT); 953 954 pp = LIST_FIRST(&sc->sc_geom->provider); 955 g_error_provider(pp, ENXIO); 956 957 cp = LIST_FIRST(&sc->sc_geom->consumer); 958 pp = cp->provider; 959 960 if (sc->sc_flags & G_ELI_FLAG_RO) { 961 G_ELI_DEBUG(0, "WARNING: Metadata won't be erased on read-only " 962 "provider: %s.", pp->name); 963 } else { 964 u_char *sector; 965 u_int i; 966 int err; 967 968 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK); 969 for (i = 0; i <= g_eli_overwrites; i++) { 970 if (i == g_eli_overwrites) 971 bzero(sector, pp->sectorsize); 972 else 973 arc4rand(sector, pp->sectorsize, 0); 974 err = g_write_data(cp, pp->mediasize - pp->sectorsize, 975 sector, pp->sectorsize); 976 if (err != 0) { 977 G_ELI_DEBUG(0, "Cannot erase metadata on %s " 978 "(error=%d).", pp->name, err); 979 if (error == 0) 980 error = err; 981 } 982 /* 983 * Flush write cache so we don't overwrite data N times 984 * in cache and only once on disk. 985 */ 986 (void)g_io_flush(cp); 987 } 988 free(sector, M_ELI); 989 } 990 if (error == 0) 991 G_ELI_DEBUG(0, "%s has been killed.", pp->name); 992 g_eli_destroy(sc, TRUE); 993 return (error); 994 } 995 996 static void 997 g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp) 998 { 999 int *all, *nargs; 1000 int error; 1001 1002 g_topology_assert(); 1003 1004 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); 1005 if (nargs == NULL) { 1006 gctl_error(req, "No '%s' argument.", "nargs"); 1007 return; 1008 } 1009 all = gctl_get_paraml(req, "all", sizeof(*all)); 1010 if (all == NULL) { 1011 gctl_error(req, "No '%s' argument.", "all"); 1012 return; 1013 } 1014 if (!*all && *nargs == 0) { 1015 gctl_error(req, "Too few arguments."); 1016 return; 1017 } 1018 1019 if (*all) { 1020 struct g_geom *gp, *gp2; 1021 1022 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) { 1023 error = g_eli_kill_one(gp->softc); 1024 if (error != 0) 1025 gctl_error(req, "Not fully done."); 1026 } 1027 } else { 1028 struct g_eli_softc *sc; 1029 const char *prov; 1030 char param[16]; 1031 int i; 1032 1033 for (i = 0; i < *nargs; i++) { 1034 snprintf(param, sizeof(param), "arg%d", i); 1035 prov = gctl_get_asciiparam(req, param); 1036 if (prov == NULL) { 1037 G_ELI_DEBUG(0, "No 'arg%d' argument.", i); 1038 continue; 1039 } 1040 1041 sc = g_eli_find_device(mp, prov); 1042 if (sc == NULL) { 1043 G_ELI_DEBUG(0, "No such provider: %s.", prov); 1044 continue; 1045 } 1046 error = g_eli_kill_one(sc); 1047 if (error != 0) 1048 gctl_error(req, "Not fully done."); 1049 } 1050 } 1051 } 1052 1053 void 1054 g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb) 1055 { 1056 uint32_t *version; 1057 1058 g_topology_assert(); 1059 1060 version = gctl_get_paraml(req, "version", sizeof(*version)); 1061 if (version == NULL) { 1062 gctl_error(req, "No '%s' argument.", "version"); 1063 return; 1064 } 1065 while (*version != G_ELI_VERSION) { 1066 if (G_ELI_VERSION == G_ELI_VERSION_06 && 1067 *version == G_ELI_VERSION_05) { 1068 /* Compatible. */ 1069 break; 1070 } 1071 if (G_ELI_VERSION == G_ELI_VERSION_07 && 1072 (*version == G_ELI_VERSION_05 || 1073 *version == G_ELI_VERSION_06)) { 1074 /* Compatible. */ 1075 break; 1076 } 1077 gctl_error(req, "Userland and kernel parts are out of sync."); 1078 return; 1079 } 1080 1081 if (strcmp(verb, "attach") == 0) 1082 g_eli_ctl_attach(req, mp); 1083 else if (strcmp(verb, "detach") == 0 || strcmp(verb, "stop") == 0) 1084 g_eli_ctl_detach(req, mp); 1085 else if (strcmp(verb, "onetime") == 0) 1086 g_eli_ctl_onetime(req, mp); 1087 else if (strcmp(verb, "configure") == 0) 1088 g_eli_ctl_configure(req, mp); 1089 else if (strcmp(verb, "setkey") == 0) 1090 g_eli_ctl_setkey(req, mp); 1091 else if (strcmp(verb, "delkey") == 0) 1092 g_eli_ctl_delkey(req, mp); 1093 else if (strcmp(verb, "suspend") == 0) 1094 g_eli_ctl_suspend(req, mp); 1095 else if (strcmp(verb, "resume") == 0) 1096 g_eli_ctl_resume(req, mp); 1097 else if (strcmp(verb, "kill") == 0) 1098 g_eli_ctl_kill(req, mp); 1099 else 1100 gctl_error(req, "Unknown verb."); 1101 } 1102