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