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