2 * SPDX-License-Identifier: BSD-2-Clause
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 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
35 #include <sys/mutex.h>
37 #include <sys/sysctl.h>
38 #include <sys/malloc.h>
39 #include <sys/kthread.h>
41 #include <sys/sched.h>
46 #include <geom/geom.h>
47 #include <geom/geom_dbg.h>
48 #include <geom/eli/g_eli.h>
50 MALLOC_DECLARE(M_ELI);
53 g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
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;
64 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
66 gctl_error(req, "No '%s' argument.", "nargs");
70 gctl_error(req, "Invalid number of arguments.");
74 detach = gctl_get_paraml(req, "detach", sizeof(*detach));
76 gctl_error(req, "No '%s' argument.", "detach");
80 /* "keyno" is optional for backward compatibility */
82 valp = gctl_get_param(req, "keyno", &dummy);
84 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
88 if (nkey < -1 || nkey >= G_ELI_MAXMKEYS) {
89 gctl_error(req, "Invalid '%s' argument.", "keyno");
93 readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly));
94 if (readonly == NULL) {
95 gctl_error(req, "No '%s' argument.", "readonly");
99 /* "dryrun" is optional for backward compatibility */
101 dryrunp = gctl_get_param(req, "dryrun", &dummy);
102 if (dryrunp != NULL) {
103 dryrunp = gctl_get_paraml(req, "dryrun", sizeof(*dryrunp));
108 if (*detach && *readonly) {
109 gctl_error(req, "Options -d and -r are mutually exclusive.");
113 pp = gctl_get_provider(req, "arg0");
116 error = g_eli_read_metadata(mp, pp, &md);
118 gctl_error(req, "Cannot read metadata from %s (error=%d).",
122 if (md.md_keys == 0x00) {
123 explicit_bzero(&md, sizeof(md));
124 gctl_error(req, "No valid keys on %s.", pp->name);
127 if (!eli_metadata_crypto_supported(&md)) {
128 explicit_bzero(&md, sizeof(md));
129 gctl_error(req, "Invalid or unsupported algorithms.");
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");
141 error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
143 error = g_eli_mkey_decrypt(&md, key, mkey, nkey);
144 explicit_bzero(key, keysize);
146 explicit_bzero(&md, sizeof(md));
147 gctl_error(req, "Wrong key for %s.", pp->name);
149 } else if (error > 0) {
150 explicit_bzero(&md, sizeof(md));
151 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
155 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
158 md.md_flags |= G_ELI_FLAG_WO_DETACH;
160 md.md_flags |= G_ELI_FLAG_RO;
162 g_eli_create(req, mp, pp, &md, mkey, nkey);
163 explicit_bzero(mkey, sizeof(mkey));
164 explicit_bzero(&md, sizeof(md));
167 static struct g_eli_softc *
168 g_eli_find_device(struct g_class *mp, const char *prov)
170 struct g_eli_softc *sc;
172 struct g_provider *pp;
173 struct g_consumer *cp;
175 if (strncmp(prov, _PATH_DEV, strlen(_PATH_DEV)) == 0)
176 prov += strlen(_PATH_DEV);
177 LIST_FOREACH(gp, &mp->geom, geom) {
181 pp = LIST_FIRST(&gp->provider);
182 if (pp != NULL && strcmp(pp->name, prov) == 0)
184 cp = LIST_FIRST(&gp->consumer);
185 if (cp != NULL && cp->provider != NULL &&
186 strcmp(cp->provider->name, prov) == 0) {
194 g_eli_ctl_detach(struct gctl_req *req, struct g_class *mp)
196 struct g_eli_softc *sc;
197 int *force, *last, *nargs, error;
204 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
206 gctl_error(req, "No '%s' argument.", "nargs");
210 gctl_error(req, "Missing device(s).");
213 force = gctl_get_paraml(req, "force", sizeof(*force));
215 gctl_error(req, "No '%s' argument.", "force");
218 last = gctl_get_paraml(req, "last", sizeof(*last));
220 gctl_error(req, "No '%s' argument.", "last");
224 for (i = 0; i < *nargs; i++) {
225 snprintf(param, sizeof(param), "arg%d", i);
226 prov = gctl_get_asciiparam(req, param);
228 gctl_error(req, "No 'arg%d' argument.", i);
231 sc = g_eli_find_device(mp, prov);
233 gctl_error(req, "No such device: %s.", prov);
237 sc->sc_flags |= G_ELI_FLAG_RW_DETACH;
238 sc->sc_geom->access = g_eli_access;
240 error = g_eli_destroy(sc, *force ? TRUE : FALSE);
243 "Cannot destroy device %s (error=%d).",
252 g_eli_ctl_onetime(struct gctl_req *req, struct g_class *mp)
254 struct g_eli_metadata md;
255 struct g_provider *pp;
257 intmax_t *keylen, *sectorsize;
258 u_char mkey[G_ELI_DATAIVKEYLEN];
259 int *nargs, *detach, *noautoresize, *notrim;
262 bzero(&md, sizeof(md));
264 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
266 gctl_error(req, "No '%s' argument.", "nargs");
270 gctl_error(req, "Invalid number of arguments.");
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;
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;
290 md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
291 name = gctl_get_asciiparam(req, "aalgo");
293 gctl_error(req, "No '%s' argument.", "aalgo");
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;
303 * For backward compatibility, check if the -a option
304 * was used to provide encryption algorithm.
306 md.md_ealgo = g_eli_str2ealgo(name);
307 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
308 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
310 "Invalid authentication algorithm.");
313 gctl_error(req, "warning: The -e option, not "
314 "the -a option is now used to specify "
315 "encryption algorithm to use.");
320 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
321 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
322 name = gctl_get_asciiparam(req, "ealgo");
324 gctl_error(req, "No '%s' argument.", "ealgo");
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.");
335 keylen = gctl_get_paraml(req, "keylen", sizeof(*keylen));
336 if (keylen == NULL) {
337 gctl_error(req, "No '%s' argument.", "keylen");
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");
346 /* Not important here. */
348 /* Not important here. */
349 bzero(md.md_salt, sizeof(md.md_salt));
352 arc4rand(mkey, sizeof(mkey), 0);
354 /* Not important here. */
355 bzero(md.md_hash, sizeof(md.md_hash));
357 pp = gctl_get_provider(req, "arg0");
361 sectorsize = gctl_get_paraml(req, "sectorsize", sizeof(*sectorsize));
362 if (sectorsize == NULL) {
363 gctl_error(req, "No '%s' argument.", "sectorsize");
366 if (*sectorsize == 0)
367 md.md_sectorsize = pp->sectorsize;
369 if (*sectorsize < 0 || (*sectorsize % pp->sectorsize) != 0) {
370 gctl_error(req, "Invalid sector size.");
373 if (*sectorsize > PAGE_SIZE) {
374 gctl_error(req, "warning: Using sectorsize bigger than "
377 md.md_sectorsize = *sectorsize;
380 g_eli_create(req, mp, pp, &md, mkey, -1);
381 explicit_bzero(mkey, sizeof(mkey));
382 explicit_bzero(&md, sizeof(md));
386 g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
388 struct g_eli_softc *sc;
389 struct g_eli_metadata md;
390 struct g_provider *pp;
391 struct g_consumer *cp;
395 int *nargs, *boot, *noboot, *trim, *notrim, *geliboot, *nogeliboot;
396 int *displaypass, *nodisplaypass, *autoresize, *noautoresize;
397 int zero, error, changed;
405 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
407 gctl_error(req, "No '%s' argument.", "nargs");
411 gctl_error(req, "Missing device(s).");
415 boot = gctl_get_paraml(req, "boot", sizeof(*boot));
418 noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot));
421 if (*boot && *noboot) {
422 gctl_error(req, "Options -b and -B are mutually exclusive.");
425 if (*boot || *noboot)
428 trim = gctl_get_paraml(req, "trim", sizeof(*trim));
431 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
434 if (*trim && *notrim) {
435 gctl_error(req, "Options -t and -T are mutually exclusive.");
438 if (*trim || *notrim)
441 geliboot = gctl_get_paraml(req, "geliboot", sizeof(*geliboot));
442 if (geliboot == NULL)
444 nogeliboot = gctl_get_paraml(req, "nogeliboot", sizeof(*nogeliboot));
445 if (nogeliboot == NULL)
447 if (*geliboot && *nogeliboot) {
448 gctl_error(req, "Options -g and -G are mutually exclusive.");
451 if (*geliboot || *nogeliboot)
454 displaypass = gctl_get_paraml(req, "displaypass", sizeof(*displaypass));
455 if (displaypass == NULL)
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.");
464 if (*displaypass || *nodisplaypass)
467 autoresize = gctl_get_paraml(req, "autoresize", sizeof(*autoresize));
468 if (autoresize == NULL)
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.");
478 if (*autoresize || *noautoresize)
482 gctl_error(req, "No option given.");
486 for (i = 0; i < *nargs; i++) {
487 snprintf(param, sizeof(param), "arg%d", i);
488 prov = gctl_get_asciiparam(req, param);
490 gctl_error(req, "No 'arg%d' argument.", i);
493 sc = g_eli_find_device(mp, prov);
496 * We ignore not attached providers, userland part will
499 G_ELI_DEBUG(1, "Skipping configuration of not attached "
500 "provider %s.", prov);
503 if (sc->sc_flags & G_ELI_FLAG_RO) {
504 gctl_error(req, "Cannot change configuration of "
505 "read-only provider %s.", prov);
509 if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) {
510 G_ELI_DEBUG(1, "BOOT flag already configured for %s.",
513 } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) {
514 G_ELI_DEBUG(1, "BOOT flag not configured for %s.",
519 if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) {
520 G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.",
523 } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) {
524 G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.",
529 if (*geliboot && (sc->sc_flags & G_ELI_FLAG_GELIBOOT)) {
530 G_ELI_DEBUG(1, "GELIBOOT flag already configured for %s.",
533 } else if (*nogeliboot && !(sc->sc_flags & G_ELI_FLAG_GELIBOOT)) {
534 G_ELI_DEBUG(1, "GELIBOOT flag not configured for %s.",
539 if (*displaypass && (sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
540 G_ELI_DEBUG(1, "GELIDISPLAYPASS flag already configured for %s.",
543 } else if (*nodisplaypass &&
544 !(sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
545 G_ELI_DEBUG(1, "GELIDISPLAYPASS flag not configured for %s.",
550 if (*autoresize && (sc->sc_flags & G_ELI_FLAG_AUTORESIZE)) {
551 G_ELI_DEBUG(1, "AUTORESIZE flag already configured for %s.",
554 } else if (*noautoresize &&
555 !(sc->sc_flags & G_ELI_FLAG_AUTORESIZE)) {
556 G_ELI_DEBUG(1, "AUTORESIZE flag not configured for %s.",
561 if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
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
569 cp = LIST_FIRST(&sc->sc_geom->consumer);
571 error = g_eli_read_metadata(mp, pp, &md);
574 "Cannot read metadata from %s (error=%d).",
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;
589 md.md_flags |= G_ELI_FLAG_NODELETE;
590 sc->sc_flags |= G_ELI_FLAG_NODELETE;
592 md.md_flags &= ~G_ELI_FLAG_NODELETE;
593 sc->sc_flags &= ~G_ELI_FLAG_NODELETE;
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;
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;
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;
620 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
621 /* There's no metadata on disk so we are done here. */
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,
631 "Cannot store metadata on %s (error=%d).",
634 explicit_bzero(&md, sizeof(md));
635 zfree(sector, M_ELI);
640 g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp)
642 struct g_eli_softc *sc;
643 struct g_eli_metadata md;
644 struct g_provider *pp;
645 struct g_consumer *cp;
647 u_char *key, *mkeydst, *sector;
649 int keysize, nkey, error;
653 name = gctl_get_asciiparam(req, "arg0");
655 gctl_error(req, "No 'arg%u' argument.", 0);
658 key = gctl_get_param(req, "key", &keysize);
659 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
660 gctl_error(req, "No '%s' argument.", "key");
663 sc = g_eli_find_device(mp, name);
665 gctl_error(req, "Provider %s is invalid.", name);
668 if (sc->sc_flags & G_ELI_FLAG_RO) {
669 gctl_error(req, "Cannot change keys for read-only provider.");
672 cp = LIST_FIRST(&sc->sc_geom->consumer);
675 error = g_eli_read_metadata(mp, pp, &md);
677 gctl_error(req, "Cannot read metadata from %s (error=%d).",
682 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
684 gctl_error(req, "No '%s' argument.", "keyno");
691 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
692 gctl_error(req, "Invalid '%s' argument.", "keyno");
696 valp = gctl_get_paraml(req, "iterations", sizeof(*valp));
698 gctl_error(req, "No '%s' argument.", "iterations");
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.");
710 if (md.md_keys != (1 << nkey)) {
711 gctl_error(req, "Only already defined key can be "
712 "changed when '-i' option is used.");
715 md.md_iterations = *valp;
718 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
719 md.md_keys |= (1 << nkey);
721 bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey));
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);
727 explicit_bzero(&md, sizeof(md));
728 gctl_error(req, "Cannot encrypt Master Key (error=%d).", error);
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,
738 zfree(sector, M_ELI);
740 gctl_error(req, "Cannot store metadata on %s (error=%d).",
744 G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name);
748 g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp)
750 struct g_eli_softc *sc;
751 struct g_eli_metadata md;
752 struct g_provider *pp;
753 struct g_consumer *cp;
755 u_char *mkeydst, *sector;
758 int error, nkey, *all, *force;
763 nkey = 0; /* fixes causeless gcc warning */
765 name = gctl_get_asciiparam(req, "arg0");
767 gctl_error(req, "No 'arg%u' argument.", 0);
770 sc = g_eli_find_device(mp, name);
772 gctl_error(req, "Provider %s is invalid.", name);
775 if (sc->sc_flags & G_ELI_FLAG_RO) {
776 gctl_error(req, "Cannot delete keys for read-only provider.");
779 cp = LIST_FIRST(&sc->sc_geom->consumer);
782 error = g_eli_read_metadata(mp, pp, &md);
784 gctl_error(req, "Cannot read metadata from %s (error=%d).",
789 all = gctl_get_paraml(req, "all", sizeof(*all));
791 gctl_error(req, "No '%s' argument.", "all");
796 mkeydst = md.md_mkeys;
797 keysize = sizeof(md.md_mkeys);
799 force = gctl_get_paraml(req, "force", sizeof(*force));
801 gctl_error(req, "No '%s' argument.", "force");
805 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
807 gctl_error(req, "No '%s' argument.", "keyno");
814 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
815 gctl_error(req, "Invalid '%s' argument.", "keyno");
818 if (!(md.md_keys & (1 << nkey)) && !*force) {
819 gctl_error(req, "Master Key %u is not set.", nkey);
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.");
828 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
829 keysize = G_ELI_MKEYLEN;
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);
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,
843 G_ELI_DEBUG(0, "Cannot store metadata on %s "
844 "(error=%d).", pp->name, error);
847 * Flush write cache so we don't overwrite data N times in cache
848 * and only once on disk.
850 (void)g_io_flush(cp);
852 explicit_bzero(&md, sizeof(md));
853 zfree(sector, M_ELI);
855 G_ELI_DEBUG(1, "All keys removed from %s.", pp->name);
857 G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name);
861 g_eli_suspend_one(struct g_eli_softc *sc, struct gctl_req *req)
863 struct g_eli_worker *wr;
867 KASSERT(sc != NULL, ("NULL sc"));
869 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
871 "Device %s is using one-time key, suspend not supported.",
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.",
883 sc->sc_flags |= G_ELI_FLAG_SUSPEND;
886 LIST_FOREACH(wr, &sc->sc_workers, w_next) {
892 /* Not all threads suspended. */
893 msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO,
897 * Clear sensitive data on suspend, they will be recovered on resume.
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);
910 g_eli_ctl_suspend(struct gctl_req *req, struct g_class *mp)
912 struct g_eli_softc *sc;
917 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
919 gctl_error(req, "No '%s' argument.", "nargs");
922 all = gctl_get_paraml(req, "all", sizeof(*all));
924 gctl_error(req, "No '%s' argument.", "all");
927 if (!*all && *nargs == 0) {
928 gctl_error(req, "Too few arguments.");
933 struct g_geom *gp, *gp2;
935 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
937 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
939 "Device %s is using one-time key, suspend not supported, skipping.",
943 g_eli_suspend_one(sc, req);
950 for (i = 0; i < *nargs; i++) {
951 snprintf(param, sizeof(param), "arg%d", i);
952 prov = gctl_get_asciiparam(req, param);
954 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
958 sc = g_eli_find_device(mp, prov);
960 G_ELI_DEBUG(0, "No such provider: %s.", prov);
963 g_eli_suspend_one(sc, req);
969 g_eli_ctl_resume(struct gctl_req *req, struct g_class *mp)
971 struct g_eli_metadata md;
972 struct g_eli_softc *sc;
973 struct g_provider *pp;
974 struct g_consumer *cp;
976 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
977 int *nargs, keysize, error;
982 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
984 gctl_error(req, "No '%s' argument.", "nargs");
988 gctl_error(req, "Invalid number of arguments.");
992 name = gctl_get_asciiparam(req, "arg0");
994 gctl_error(req, "No 'arg%u' argument.", 0);
997 key = gctl_get_param(req, "key", &keysize);
998 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
999 gctl_error(req, "No '%s' argument.", "key");
1002 sc = g_eli_find_device(mp, name);
1004 gctl_error(req, "Provider %s is invalid.", name);
1007 cp = LIST_FIRST(&sc->sc_geom->consumer);
1009 error = g_eli_read_metadata(mp, pp, &md);
1011 gctl_error(req, "Cannot read metadata from %s (error=%d).",
1015 if (md.md_keys == 0x00) {
1016 explicit_bzero(&md, sizeof(md));
1017 gctl_error(req, "No valid keys on %s.", pp->name);
1021 error = g_eli_mkey_decrypt_any(&md, key, mkey, &nkey);
1022 explicit_bzero(key, keysize);
1024 explicit_bzero(&md, sizeof(md));
1025 gctl_error(req, "Wrong key for %s.", pp->name);
1027 } else if (error > 0) {
1028 explicit_bzero(&md, sizeof(md));
1029 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
1033 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
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);
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);
1045 mtx_unlock(&sc->sc_queue_mtx);
1046 explicit_bzero(mkey, sizeof(mkey));
1047 explicit_bzero(&md, sizeof(md));
1051 g_eli_kill_one(struct g_eli_softc *sc)
1053 struct g_provider *pp;
1054 struct g_consumer *cp;
1057 g_topology_assert();
1062 pp = LIST_FIRST(&sc->sc_geom->provider);
1063 g_error_provider(pp, ENXIO);
1065 cp = LIST_FIRST(&sc->sc_geom->consumer);
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);
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);
1081 arc4rand(sector, pp->sectorsize, 0);
1082 err = g_write_data(cp, pp->mediasize - pp->sectorsize,
1083 sector, pp->sectorsize);
1085 G_ELI_DEBUG(0, "Cannot erase metadata on %s "
1086 "(error=%d).", pp->name, err);
1091 * Flush write cache so we don't overwrite data N times
1092 * in cache and only once on disk.
1094 (void)g_io_flush(cp);
1096 free(sector, M_ELI);
1099 G_ELI_DEBUG(0, "%s has been killed.", pp->name);
1100 g_eli_destroy(sc, TRUE);
1105 g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp)
1110 g_topology_assert();
1112 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1113 if (nargs == NULL) {
1114 gctl_error(req, "No '%s' argument.", "nargs");
1117 all = gctl_get_paraml(req, "all", sizeof(*all));
1119 gctl_error(req, "No '%s' argument.", "all");
1122 if (!*all && *nargs == 0) {
1123 gctl_error(req, "Too few arguments.");
1128 struct g_geom *gp, *gp2;
1130 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
1131 error = g_eli_kill_one(gp->softc);
1133 gctl_error(req, "Not fully done.");
1136 struct g_eli_softc *sc;
1141 for (i = 0; i < *nargs; i++) {
1142 snprintf(param, sizeof(param), "arg%d", i);
1143 prov = gctl_get_asciiparam(req, param);
1145 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
1149 sc = g_eli_find_device(mp, prov);
1151 G_ELI_DEBUG(0, "No such provider: %s.", prov);
1154 error = g_eli_kill_one(sc);
1156 gctl_error(req, "Not fully done.");
1162 g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb)
1166 g_topology_assert();
1168 version = gctl_get_paraml(req, "version", sizeof(*version));
1169 if (version == NULL) {
1170 gctl_error(req, "No '%s' argument.", "version");
1173 while (*version != G_ELI_VERSION) {
1174 if (G_ELI_VERSION == G_ELI_VERSION_06 &&
1175 *version == G_ELI_VERSION_05) {
1179 if (G_ELI_VERSION == G_ELI_VERSION_07 &&
1180 (*version == G_ELI_VERSION_05 ||
1181 *version == G_ELI_VERSION_06)) {
1185 gctl_error(req, "Userland and kernel parts are out of sync.");
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);
1208 gctl_error(req, "Unknown verb.");