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