2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
37 #include <sys/mutex.h>
39 #include <sys/sysctl.h>
40 #include <sys/malloc.h>
41 #include <sys/kthread.h>
43 #include <sys/sched.h>
48 #include <geom/geom.h>
49 #include <geom/eli/g_eli.h>
52 MALLOC_DECLARE(M_ELI);
56 g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
58 struct g_eli_metadata md;
59 struct g_provider *pp;
61 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
62 int *nargs, *detach, *readonly, *dryrun;
63 int keysize, error, nkey;
68 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
70 gctl_error(req, "No '%s' argument.", "nargs");
74 gctl_error(req, "Invalid number of arguments.");
78 detach = gctl_get_paraml(req, "detach", sizeof(*detach));
80 gctl_error(req, "No '%s' argument.", "detach");
84 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
86 gctl_error(req, "No '%s' argument.", "keyno");
90 if (nkey < -1 || nkey >= G_ELI_MAXMKEYS) {
91 gctl_error(req, "Invalid '%s' argument.", "keyno");
95 readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly));
96 if (readonly == NULL) {
97 gctl_error(req, "No '%s' argument.", "readonly");
101 dryrun = gctl_get_paraml(req, "dryrun", sizeof(*dryrun));
102 if (dryrun == NULL) {
103 gctl_error(req, "No '%s' argument.", "dryrun");
107 if (*detach && *readonly) {
108 gctl_error(req, "Options -d and -r are mutually exclusive.");
112 name = gctl_get_asciiparam(req, "arg0");
114 gctl_error(req, "No 'arg%u' argument.", 0);
117 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
118 name += strlen("/dev/");
119 pp = g_provider_by_name(name);
121 gctl_error(req, "Provider %s is invalid.", name);
124 error = g_eli_read_metadata(mp, pp, &md);
126 gctl_error(req, "Cannot read metadata from %s (error=%d).",
130 if (md.md_keys == 0x00) {
131 explicit_bzero(&md, sizeof(md));
132 gctl_error(req, "No valid keys on %s.", pp->name);
136 key = gctl_get_param(req, "key", &keysize);
137 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
138 explicit_bzero(&md, sizeof(md));
139 gctl_error(req, "No '%s' argument.", "key");
144 error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
146 error = g_eli_mkey_decrypt(&md, key, mkey, nkey);
147 explicit_bzero(key, keysize);
149 explicit_bzero(&md, sizeof(md));
150 gctl_error(req, "Wrong key for %s.", pp->name);
152 } else if (error > 0) {
153 explicit_bzero(&md, sizeof(md));
154 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
158 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
161 md.md_flags |= G_ELI_FLAG_WO_DETACH;
163 md.md_flags |= G_ELI_FLAG_RO;
165 g_eli_create(req, mp, pp, &md, mkey, nkey);
166 explicit_bzero(mkey, sizeof(mkey));
167 explicit_bzero(&md, sizeof(md));
170 static struct g_eli_softc *
171 g_eli_find_device(struct g_class *mp, const char *prov)
173 struct g_eli_softc *sc;
175 struct g_provider *pp;
176 struct g_consumer *cp;
178 if (strncmp(prov, "/dev/", strlen("/dev/")) == 0)
179 prov += strlen("/dev/");
180 LIST_FOREACH(gp, &mp->geom, geom) {
184 pp = LIST_FIRST(&gp->provider);
185 if (pp != NULL && strcmp(pp->name, prov) == 0)
187 cp = LIST_FIRST(&gp->consumer);
188 if (cp != NULL && cp->provider != NULL &&
189 strcmp(cp->provider->name, prov) == 0) {
197 g_eli_ctl_detach(struct gctl_req *req, struct g_class *mp)
199 struct g_eli_softc *sc;
200 int *force, *last, *nargs, error;
207 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
209 gctl_error(req, "No '%s' argument.", "nargs");
213 gctl_error(req, "Missing device(s).");
216 force = gctl_get_paraml(req, "force", sizeof(*force));
218 gctl_error(req, "No '%s' argument.", "force");
221 last = gctl_get_paraml(req, "last", sizeof(*last));
223 gctl_error(req, "No '%s' argument.", "last");
227 for (i = 0; i < *nargs; i++) {
228 snprintf(param, sizeof(param), "arg%d", i);
229 prov = gctl_get_asciiparam(req, param);
231 gctl_error(req, "No 'arg%d' argument.", i);
234 sc = g_eli_find_device(mp, prov);
236 gctl_error(req, "No such device: %s.", prov);
240 sc->sc_flags |= G_ELI_FLAG_RW_DETACH;
241 sc->sc_geom->access = g_eli_access;
243 error = g_eli_destroy(sc, *force ? TRUE : FALSE);
246 "Cannot destroy device %s (error=%d).",
255 g_eli_ctl_onetime(struct gctl_req *req, struct g_class *mp)
257 struct g_eli_metadata md;
258 struct g_provider *pp;
260 intmax_t *keylen, *sectorsize;
261 u_char mkey[G_ELI_DATAIVKEYLEN];
262 int *nargs, *detach, *notrim;
265 bzero(&md, sizeof(md));
267 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
269 gctl_error(req, "No '%s' argument.", "nargs");
273 gctl_error(req, "Invalid number of arguments.");
277 strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic));
278 md.md_version = G_ELI_VERSION;
279 md.md_flags |= G_ELI_FLAG_ONETIME;
281 detach = gctl_get_paraml(req, "detach", sizeof(*detach));
282 if (detach != NULL && *detach)
283 md.md_flags |= G_ELI_FLAG_WO_DETACH;
284 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
285 if (notrim != NULL && *notrim)
286 md.md_flags |= G_ELI_FLAG_NODELETE;
288 md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
289 name = gctl_get_asciiparam(req, "aalgo");
291 gctl_error(req, "No '%s' argument.", "aalgo");
295 md.md_aalgo = g_eli_str2aalgo(name);
296 if (md.md_aalgo >= CRYPTO_ALGORITHM_MIN &&
297 md.md_aalgo <= CRYPTO_ALGORITHM_MAX) {
298 md.md_flags |= G_ELI_FLAG_AUTH;
301 * For backward compatibility, check if the -a option
302 * was used to provide encryption algorithm.
304 md.md_ealgo = g_eli_str2ealgo(name);
305 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
306 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
308 "Invalid authentication algorithm.");
311 gctl_error(req, "warning: The -e option, not "
312 "the -a option is now used to specify "
313 "encryption algorithm to use.");
318 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
319 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
320 name = gctl_get_asciiparam(req, "ealgo");
322 gctl_error(req, "No '%s' argument.", "ealgo");
325 md.md_ealgo = g_eli_str2ealgo(name);
326 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
327 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
328 gctl_error(req, "Invalid encryption algorithm.");
333 keylen = gctl_get_paraml(req, "keylen", sizeof(*keylen));
334 if (keylen == NULL) {
335 gctl_error(req, "No '%s' argument.", "keylen");
338 md.md_keylen = g_eli_keylen(md.md_ealgo, *keylen);
339 if (md.md_keylen == 0) {
340 gctl_error(req, "Invalid '%s' argument.", "keylen");
344 /* Not important here. */
346 /* Not important here. */
347 bzero(md.md_salt, sizeof(md.md_salt));
350 arc4rand(mkey, sizeof(mkey), 0);
352 /* Not important here. */
353 bzero(md.md_hash, sizeof(md.md_hash));
355 name = gctl_get_asciiparam(req, "arg0");
357 gctl_error(req, "No 'arg%u' argument.", 0);
360 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
361 name += strlen("/dev/");
362 pp = g_provider_by_name(name);
364 gctl_error(req, "Provider %s is invalid.", name);
368 sectorsize = gctl_get_paraml(req, "sectorsize", sizeof(*sectorsize));
369 if (sectorsize == NULL) {
370 gctl_error(req, "No '%s' argument.", "sectorsize");
373 if (*sectorsize == 0)
374 md.md_sectorsize = pp->sectorsize;
376 if (*sectorsize < 0 || (*sectorsize % pp->sectorsize) != 0) {
377 gctl_error(req, "Invalid sector size.");
380 if (*sectorsize > PAGE_SIZE) {
381 gctl_error(req, "warning: Using sectorsize bigger than "
384 md.md_sectorsize = *sectorsize;
387 g_eli_create(req, mp, pp, &md, mkey, -1);
388 explicit_bzero(mkey, sizeof(mkey));
389 explicit_bzero(&md, sizeof(md));
393 g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
395 struct g_eli_softc *sc;
396 struct g_eli_metadata md;
397 struct g_provider *pp;
398 struct g_consumer *cp;
402 int *nargs, *boot, *noboot, *trim, *notrim, *geliboot, *nogeliboot;
403 int *displaypass, *nodisplaypass;
404 int zero, error, changed;
412 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
414 gctl_error(req, "No '%s' argument.", "nargs");
418 gctl_error(req, "Missing device(s).");
422 boot = gctl_get_paraml(req, "boot", sizeof(*boot));
425 noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot));
428 if (*boot && *noboot) {
429 gctl_error(req, "Options -b and -B are mutually exclusive.");
432 if (*boot || *noboot)
435 trim = gctl_get_paraml(req, "trim", sizeof(*trim));
438 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
441 if (*trim && *notrim) {
442 gctl_error(req, "Options -t and -T are mutually exclusive.");
445 if (*trim || *notrim)
448 geliboot = gctl_get_paraml(req, "geliboot", sizeof(*geliboot));
449 if (geliboot == NULL)
451 nogeliboot = gctl_get_paraml(req, "nogeliboot", sizeof(*nogeliboot));
452 if (nogeliboot == NULL)
454 if (*geliboot && *nogeliboot) {
455 gctl_error(req, "Options -g and -G are mutually exclusive.");
458 if (*geliboot || *nogeliboot)
461 displaypass = gctl_get_paraml(req, "displaypass", sizeof(*displaypass));
462 if (displaypass == NULL)
464 nodisplaypass = gctl_get_paraml(req, "nodisplaypass", sizeof(*nodisplaypass));
465 if (nodisplaypass == NULL)
466 nodisplaypass = &zero;
467 if (*displaypass && *nodisplaypass) {
468 gctl_error(req, "Options -d and -D are mutually exclusive.");
471 if (*displaypass || *nodisplaypass)
475 gctl_error(req, "No option given.");
479 for (i = 0; i < *nargs; i++) {
480 snprintf(param, sizeof(param), "arg%d", i);
481 prov = gctl_get_asciiparam(req, param);
483 gctl_error(req, "No 'arg%d' argument.", i);
486 sc = g_eli_find_device(mp, prov);
489 * We ignore not attached providers, userland part will
492 G_ELI_DEBUG(1, "Skipping configuration of not attached "
493 "provider %s.", prov);
496 if (sc->sc_flags & G_ELI_FLAG_RO) {
497 gctl_error(req, "Cannot change configuration of "
498 "read-only provider %s.", prov);
502 if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) {
503 G_ELI_DEBUG(1, "BOOT flag already configured for %s.",
506 } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) {
507 G_ELI_DEBUG(1, "BOOT flag not configured for %s.",
512 if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) {
513 G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.",
516 } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) {
517 G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.",
522 if (*geliboot && (sc->sc_flags & G_ELI_FLAG_GELIBOOT)) {
523 G_ELI_DEBUG(1, "GELIBOOT flag already configured for %s.",
526 } else if (*nogeliboot && !(sc->sc_flags & G_ELI_FLAG_GELIBOOT)) {
527 G_ELI_DEBUG(1, "GELIBOOT flag not configured for %s.",
532 if (*displaypass && (sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
533 G_ELI_DEBUG(1, "GELIDISPLAYPASS flag already configured for %s.",
536 } else if (*nodisplaypass &&
537 !(sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
538 G_ELI_DEBUG(1, "GELIDISPLAYPASS flag not configured for %s.",
543 if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
545 * ONETIME providers don't write metadata to
546 * disk, so don't try reading it. This means
547 * we're bit-flipping uninitialized memory in md
548 * below, but that's OK; we don't do anything
551 cp = LIST_FIRST(&sc->sc_geom->consumer);
553 error = g_eli_read_metadata(mp, pp, &md);
556 "Cannot read metadata from %s (error=%d).",
563 md.md_flags |= G_ELI_FLAG_BOOT;
564 sc->sc_flags |= G_ELI_FLAG_BOOT;
565 } else if (*noboot) {
566 md.md_flags &= ~G_ELI_FLAG_BOOT;
567 sc->sc_flags &= ~G_ELI_FLAG_BOOT;
571 md.md_flags |= G_ELI_FLAG_NODELETE;
572 sc->sc_flags |= G_ELI_FLAG_NODELETE;
574 md.md_flags &= ~G_ELI_FLAG_NODELETE;
575 sc->sc_flags &= ~G_ELI_FLAG_NODELETE;
579 md.md_flags |= G_ELI_FLAG_GELIBOOT;
580 sc->sc_flags |= G_ELI_FLAG_GELIBOOT;
581 } else if (*nogeliboot) {
582 md.md_flags &= ~G_ELI_FLAG_GELIBOOT;
583 sc->sc_flags &= ~G_ELI_FLAG_GELIBOOT;
587 md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
588 sc->sc_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
589 } else if (*nodisplaypass) {
590 md.md_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
591 sc->sc_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
594 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
595 /* There's no metadata on disk so we are done here. */
599 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
600 eli_metadata_encode(&md, sector);
601 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
605 "Cannot store metadata on %s (error=%d).",
608 explicit_bzero(&md, sizeof(md));
609 explicit_bzero(sector, pp->sectorsize);
615 g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp)
617 struct g_eli_softc *sc;
618 struct g_eli_metadata md;
619 struct g_provider *pp;
620 struct g_consumer *cp;
622 u_char *key, *mkeydst, *sector;
624 int keysize, nkey, error;
628 name = gctl_get_asciiparam(req, "arg0");
630 gctl_error(req, "No 'arg%u' argument.", 0);
633 key = gctl_get_param(req, "key", &keysize);
634 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
635 gctl_error(req, "No '%s' argument.", "key");
638 sc = g_eli_find_device(mp, name);
640 gctl_error(req, "Provider %s is invalid.", name);
643 if (sc->sc_flags & G_ELI_FLAG_RO) {
644 gctl_error(req, "Cannot change keys for read-only provider.");
647 cp = LIST_FIRST(&sc->sc_geom->consumer);
650 error = g_eli_read_metadata(mp, pp, &md);
652 gctl_error(req, "Cannot read metadata from %s (error=%d).",
657 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
659 gctl_error(req, "No '%s' argument.", "keyno");
666 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
667 gctl_error(req, "Invalid '%s' argument.", "keyno");
671 valp = gctl_get_paraml(req, "iterations", sizeof(*valp));
673 gctl_error(req, "No '%s' argument.", "iterations");
676 /* Check if iterations number should and can be changed. */
677 if (*valp != -1 && md.md_iterations == -1) {
678 md.md_iterations = *valp;
679 } else if (*valp != -1 && *valp != md.md_iterations) {
680 if (bitcount32(md.md_keys) != 1) {
681 gctl_error(req, "To be able to use '-i' option, only "
682 "one key can be defined.");
685 if (md.md_keys != (1 << nkey)) {
686 gctl_error(req, "Only already defined key can be "
687 "changed when '-i' option is used.");
690 md.md_iterations = *valp;
693 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
694 md.md_keys |= (1 << nkey);
696 bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey));
698 /* Encrypt Master Key with the new key. */
699 error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst);
700 explicit_bzero(key, keysize);
702 explicit_bzero(&md, sizeof(md));
703 gctl_error(req, "Cannot encrypt Master Key (error=%d).", error);
707 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
708 /* Store metadata with fresh key. */
709 eli_metadata_encode(&md, sector);
710 explicit_bzero(&md, sizeof(md));
711 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
713 explicit_bzero(sector, pp->sectorsize);
716 gctl_error(req, "Cannot store metadata on %s (error=%d).",
720 G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name);
724 g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp)
726 struct g_eli_softc *sc;
727 struct g_eli_metadata md;
728 struct g_provider *pp;
729 struct g_consumer *cp;
731 u_char *mkeydst, *sector;
734 int error, nkey, *all, *force;
739 nkey = 0; /* fixes causeless gcc warning */
741 name = gctl_get_asciiparam(req, "arg0");
743 gctl_error(req, "No 'arg%u' argument.", 0);
746 sc = g_eli_find_device(mp, name);
748 gctl_error(req, "Provider %s is invalid.", name);
751 if (sc->sc_flags & G_ELI_FLAG_RO) {
752 gctl_error(req, "Cannot delete keys for read-only provider.");
755 cp = LIST_FIRST(&sc->sc_geom->consumer);
758 error = g_eli_read_metadata(mp, pp, &md);
760 gctl_error(req, "Cannot read metadata from %s (error=%d).",
765 all = gctl_get_paraml(req, "all", sizeof(*all));
767 gctl_error(req, "No '%s' argument.", "all");
772 mkeydst = md.md_mkeys;
773 keysize = sizeof(md.md_mkeys);
775 force = gctl_get_paraml(req, "force", sizeof(*force));
777 gctl_error(req, "No '%s' argument.", "force");
781 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
783 gctl_error(req, "No '%s' argument.", "keyno");
790 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
791 gctl_error(req, "Invalid '%s' argument.", "keyno");
794 if (!(md.md_keys & (1 << nkey)) && !*force) {
795 gctl_error(req, "Master Key %u is not set.", nkey);
798 md.md_keys &= ~(1 << nkey);
799 if (md.md_keys == 0 && !*force) {
800 gctl_error(req, "This is the last Master Key. Use '-f' "
801 "flag if you really want to remove it.");
804 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
805 keysize = G_ELI_MKEYLEN;
808 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
809 for (i = 0; i <= g_eli_overwrites; i++) {
810 if (i == g_eli_overwrites)
811 explicit_bzero(mkeydst, keysize);
813 arc4rand(mkeydst, keysize, 0);
814 /* Store metadata with destroyed key. */
815 eli_metadata_encode(&md, sector);
816 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
819 G_ELI_DEBUG(0, "Cannot store metadata on %s "
820 "(error=%d).", pp->name, error);
823 * Flush write cache so we don't overwrite data N times in cache
824 * and only once on disk.
826 (void)g_io_flush(cp);
828 explicit_bzero(&md, sizeof(md));
829 explicit_bzero(sector, pp->sectorsize);
832 G_ELI_DEBUG(1, "All keys removed from %s.", pp->name);
834 G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name);
838 g_eli_suspend_one(struct g_eli_softc *sc, struct gctl_req *req)
840 struct g_eli_worker *wr;
844 KASSERT(sc != NULL, ("NULL sc"));
846 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
848 "Device %s is using one-time key, suspend not supported.",
853 mtx_lock(&sc->sc_queue_mtx);
854 if (sc->sc_flags & G_ELI_FLAG_SUSPEND) {
855 mtx_unlock(&sc->sc_queue_mtx);
856 gctl_error(req, "Device %s already suspended.",
860 sc->sc_flags |= G_ELI_FLAG_SUSPEND;
863 LIST_FOREACH(wr, &sc->sc_workers, w_next) {
869 /* Not all threads suspended. */
870 msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO,
874 * Clear sensitive data on suspend, they will be recovered on resume.
876 explicit_bzero(sc->sc_mkey, sizeof(sc->sc_mkey));
877 g_eli_key_destroy(sc);
878 explicit_bzero(sc->sc_akey, sizeof(sc->sc_akey));
879 explicit_bzero(&sc->sc_akeyctx, sizeof(sc->sc_akeyctx));
880 explicit_bzero(sc->sc_ivkey, sizeof(sc->sc_ivkey));
881 explicit_bzero(&sc->sc_ivctx, sizeof(sc->sc_ivctx));
882 mtx_unlock(&sc->sc_queue_mtx);
883 G_ELI_DEBUG(0, "Device %s has been suspended.", sc->sc_name);
887 g_eli_ctl_suspend(struct gctl_req *req, struct g_class *mp)
889 struct g_eli_softc *sc;
894 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
896 gctl_error(req, "No '%s' argument.", "nargs");
899 all = gctl_get_paraml(req, "all", sizeof(*all));
901 gctl_error(req, "No '%s' argument.", "all");
904 if (!*all && *nargs == 0) {
905 gctl_error(req, "Too few arguments.");
910 struct g_geom *gp, *gp2;
912 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
914 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
916 "Device %s is using one-time key, suspend not supported, skipping.",
920 g_eli_suspend_one(sc, req);
927 for (i = 0; i < *nargs; i++) {
928 snprintf(param, sizeof(param), "arg%d", i);
929 prov = gctl_get_asciiparam(req, param);
931 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
935 sc = g_eli_find_device(mp, prov);
937 G_ELI_DEBUG(0, "No such provider: %s.", prov);
940 g_eli_suspend_one(sc, req);
946 g_eli_ctl_resume(struct gctl_req *req, struct g_class *mp)
948 struct g_eli_metadata md;
949 struct g_eli_softc *sc;
950 struct g_provider *pp;
951 struct g_consumer *cp;
953 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
954 int *nargs, keysize, error;
959 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
961 gctl_error(req, "No '%s' argument.", "nargs");
965 gctl_error(req, "Invalid number of arguments.");
969 name = gctl_get_asciiparam(req, "arg0");
971 gctl_error(req, "No 'arg%u' argument.", 0);
974 key = gctl_get_param(req, "key", &keysize);
975 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
976 gctl_error(req, "No '%s' argument.", "key");
979 sc = g_eli_find_device(mp, name);
981 gctl_error(req, "Provider %s is invalid.", name);
984 cp = LIST_FIRST(&sc->sc_geom->consumer);
986 error = g_eli_read_metadata(mp, pp, &md);
988 gctl_error(req, "Cannot read metadata from %s (error=%d).",
992 if (md.md_keys == 0x00) {
993 explicit_bzero(&md, sizeof(md));
994 gctl_error(req, "No valid keys on %s.", pp->name);
998 error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
999 explicit_bzero(key, keysize);
1001 explicit_bzero(&md, sizeof(md));
1002 gctl_error(req, "Wrong key for %s.", pp->name);
1004 } else if (error > 0) {
1005 explicit_bzero(&md, sizeof(md));
1006 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
1010 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
1012 mtx_lock(&sc->sc_queue_mtx);
1013 if (!(sc->sc_flags & G_ELI_FLAG_SUSPEND))
1014 gctl_error(req, "Device %s is not suspended.", name);
1016 /* Restore sc_mkey, sc_ekeys, sc_akey and sc_ivkey. */
1017 g_eli_mkey_propagate(sc, mkey);
1018 sc->sc_flags &= ~G_ELI_FLAG_SUSPEND;
1019 G_ELI_DEBUG(1, "Resumed %s.", pp->name);
1022 mtx_unlock(&sc->sc_queue_mtx);
1023 explicit_bzero(mkey, sizeof(mkey));
1024 explicit_bzero(&md, sizeof(md));
1028 g_eli_kill_one(struct g_eli_softc *sc)
1030 struct g_provider *pp;
1031 struct g_consumer *cp;
1034 g_topology_assert();
1039 pp = LIST_FIRST(&sc->sc_geom->provider);
1040 g_error_provider(pp, ENXIO);
1042 cp = LIST_FIRST(&sc->sc_geom->consumer);
1045 if (sc->sc_flags & G_ELI_FLAG_RO) {
1046 G_ELI_DEBUG(0, "WARNING: Metadata won't be erased on read-only "
1047 "provider: %s.", pp->name);
1053 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK);
1054 for (i = 0; i <= g_eli_overwrites; i++) {
1055 if (i == g_eli_overwrites)
1056 bzero(sector, pp->sectorsize);
1058 arc4rand(sector, pp->sectorsize, 0);
1059 err = g_write_data(cp, pp->mediasize - pp->sectorsize,
1060 sector, pp->sectorsize);
1062 G_ELI_DEBUG(0, "Cannot erase metadata on %s "
1063 "(error=%d).", pp->name, err);
1068 * Flush write cache so we don't overwrite data N times
1069 * in cache and only once on disk.
1071 (void)g_io_flush(cp);
1073 free(sector, M_ELI);
1076 G_ELI_DEBUG(0, "%s has been killed.", pp->name);
1077 g_eli_destroy(sc, TRUE);
1082 g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp)
1087 g_topology_assert();
1089 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1090 if (nargs == NULL) {
1091 gctl_error(req, "No '%s' argument.", "nargs");
1094 all = gctl_get_paraml(req, "all", sizeof(*all));
1096 gctl_error(req, "No '%s' argument.", "all");
1099 if (!*all && *nargs == 0) {
1100 gctl_error(req, "Too few arguments.");
1105 struct g_geom *gp, *gp2;
1107 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
1108 error = g_eli_kill_one(gp->softc);
1110 gctl_error(req, "Not fully done.");
1113 struct g_eli_softc *sc;
1118 for (i = 0; i < *nargs; i++) {
1119 snprintf(param, sizeof(param), "arg%d", i);
1120 prov = gctl_get_asciiparam(req, param);
1122 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
1126 sc = g_eli_find_device(mp, prov);
1128 G_ELI_DEBUG(0, "No such provider: %s.", prov);
1131 error = g_eli_kill_one(sc);
1133 gctl_error(req, "Not fully done.");
1139 g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb)
1143 g_topology_assert();
1145 version = gctl_get_paraml(req, "version", sizeof(*version));
1146 if (version == NULL) {
1147 gctl_error(req, "No '%s' argument.", "version");
1150 while (*version != G_ELI_VERSION) {
1151 if (G_ELI_VERSION == G_ELI_VERSION_06 &&
1152 *version == G_ELI_VERSION_05) {
1156 if (G_ELI_VERSION == G_ELI_VERSION_07 &&
1157 (*version == G_ELI_VERSION_05 ||
1158 *version == G_ELI_VERSION_06)) {
1162 gctl_error(req, "Userland and kernel parts are out of sync.");
1166 if (strcmp(verb, "attach") == 0)
1167 g_eli_ctl_attach(req, mp);
1168 else if (strcmp(verb, "detach") == 0 || strcmp(verb, "stop") == 0)
1169 g_eli_ctl_detach(req, mp);
1170 else if (strcmp(verb, "onetime") == 0)
1171 g_eli_ctl_onetime(req, mp);
1172 else if (strcmp(verb, "configure") == 0)
1173 g_eli_ctl_configure(req, mp);
1174 else if (strcmp(verb, "setkey") == 0)
1175 g_eli_ctl_setkey(req, mp);
1176 else if (strcmp(verb, "delkey") == 0)
1177 g_eli_ctl_delkey(req, mp);
1178 else if (strcmp(verb, "suspend") == 0)
1179 g_eli_ctl_suspend(req, mp);
1180 else if (strcmp(verb, "resume") == 0)
1181 g_eli_ctl_resume(req, mp);
1182 else if (strcmp(verb, "kill") == 0)
1183 g_eli_ctl_kill(req, mp);
1185 gctl_error(req, "Unknown verb.");