2 * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
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/eli/g_eli.h>
50 MALLOC_DECLARE(M_ELI);
54 g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp)
56 struct g_eli_metadata md;
57 struct g_provider *pp;
59 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
60 int *nargs, *detach, *readonly;
66 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
68 gctl_error(req, "No '%s' argument.", "nargs");
72 gctl_error(req, "Invalid number of arguments.");
76 detach = gctl_get_paraml(req, "detach", sizeof(*detach));
78 gctl_error(req, "No '%s' argument.", "detach");
82 readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly));
83 if (readonly == NULL) {
84 gctl_error(req, "No '%s' argument.", "readonly");
88 name = gctl_get_asciiparam(req, "arg0");
90 gctl_error(req, "No 'arg%u' argument.", 0);
93 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
94 name += strlen("/dev/");
95 pp = g_provider_by_name(name);
97 gctl_error(req, "Provider %s is invalid.", name);
100 error = g_eli_read_metadata(mp, pp, &md);
102 gctl_error(req, "Cannot read metadata from %s (error=%d).",
106 if (md.md_keys == 0x00) {
107 bzero(&md, sizeof(md));
108 gctl_error(req, "No valid keys on %s.", pp->name);
112 key = gctl_get_param(req, "key", &keysize);
113 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
114 bzero(&md, sizeof(md));
115 gctl_error(req, "No '%s' argument.", "key");
119 error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
122 bzero(&md, sizeof(md));
123 gctl_error(req, "Wrong key for %s.", pp->name);
125 } else if (error > 0) {
126 bzero(&md, sizeof(md));
127 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
131 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
133 if (*detach && *readonly) {
134 bzero(&md, sizeof(md));
135 gctl_error(req, "Options -d and -r are mutually exclusive.");
139 md.md_flags |= G_ELI_FLAG_WO_DETACH;
141 md.md_flags |= G_ELI_FLAG_RO;
142 g_eli_create(req, mp, pp, &md, mkey, nkey);
143 bzero(mkey, sizeof(mkey));
144 bzero(&md, sizeof(md));
147 static struct g_eli_softc *
148 g_eli_find_device(struct g_class *mp, const char *prov)
150 struct g_eli_softc *sc;
152 struct g_provider *pp;
153 struct g_consumer *cp;
155 if (strncmp(prov, "/dev/", strlen("/dev/")) == 0)
156 prov += strlen("/dev/");
157 LIST_FOREACH(gp, &mp->geom, geom) {
161 pp = LIST_FIRST(&gp->provider);
162 if (pp != NULL && strcmp(pp->name, prov) == 0)
164 cp = LIST_FIRST(&gp->consumer);
165 if (cp != NULL && cp->provider != NULL &&
166 strcmp(cp->provider->name, prov) == 0) {
174 g_eli_ctl_detach(struct gctl_req *req, struct g_class *mp)
176 struct g_eli_softc *sc;
177 int *force, *last, *nargs, error;
184 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
186 gctl_error(req, "No '%s' argument.", "nargs");
190 gctl_error(req, "Missing device(s).");
193 force = gctl_get_paraml(req, "force", sizeof(*force));
195 gctl_error(req, "No '%s' argument.", "force");
198 last = gctl_get_paraml(req, "last", sizeof(*last));
200 gctl_error(req, "No '%s' argument.", "last");
204 for (i = 0; i < *nargs; i++) {
205 snprintf(param, sizeof(param), "arg%d", i);
206 prov = gctl_get_asciiparam(req, param);
208 gctl_error(req, "No 'arg%d' argument.", i);
211 sc = g_eli_find_device(mp, prov);
213 gctl_error(req, "No such device: %s.", prov);
217 sc->sc_flags |= G_ELI_FLAG_RW_DETACH;
218 sc->sc_geom->access = g_eli_access;
220 error = g_eli_destroy(sc, *force ? TRUE : FALSE);
223 "Cannot destroy device %s (error=%d).",
232 g_eli_ctl_onetime(struct gctl_req *req, struct g_class *mp)
234 struct g_eli_metadata md;
235 struct g_provider *pp;
237 intmax_t *keylen, *sectorsize;
238 u_char mkey[G_ELI_DATAIVKEYLEN];
239 int *nargs, *detach, *notrim;
242 bzero(&md, sizeof(md));
244 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
246 gctl_error(req, "No '%s' argument.", "nargs");
250 gctl_error(req, "Invalid number of arguments.");
254 strlcpy(md.md_magic, G_ELI_MAGIC, sizeof(md.md_magic));
255 md.md_version = G_ELI_VERSION;
256 md.md_flags |= G_ELI_FLAG_ONETIME;
258 detach = gctl_get_paraml(req, "detach", sizeof(*detach));
259 if (detach != NULL && *detach)
260 md.md_flags |= G_ELI_FLAG_WO_DETACH;
261 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
262 if (notrim != NULL && *notrim)
263 md.md_flags |= G_ELI_FLAG_NODELETE;
265 md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
266 name = gctl_get_asciiparam(req, "aalgo");
268 gctl_error(req, "No '%s' argument.", "aalgo");
272 md.md_aalgo = g_eli_str2aalgo(name);
273 if (md.md_aalgo >= CRYPTO_ALGORITHM_MIN &&
274 md.md_aalgo <= CRYPTO_ALGORITHM_MAX) {
275 md.md_flags |= G_ELI_FLAG_AUTH;
278 * For backward compatibility, check if the -a option
279 * was used to provide encryption algorithm.
281 md.md_ealgo = g_eli_str2ealgo(name);
282 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
283 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
285 "Invalid authentication algorithm.");
288 gctl_error(req, "warning: The -e option, not "
289 "the -a option is now used to specify "
290 "encryption algorithm to use.");
295 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
296 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
297 name = gctl_get_asciiparam(req, "ealgo");
299 gctl_error(req, "No '%s' argument.", "ealgo");
302 md.md_ealgo = g_eli_str2ealgo(name);
303 if (md.md_ealgo < CRYPTO_ALGORITHM_MIN ||
304 md.md_ealgo > CRYPTO_ALGORITHM_MAX) {
305 gctl_error(req, "Invalid encryption algorithm.");
310 keylen = gctl_get_paraml(req, "keylen", sizeof(*keylen));
311 if (keylen == NULL) {
312 gctl_error(req, "No '%s' argument.", "keylen");
315 md.md_keylen = g_eli_keylen(md.md_ealgo, *keylen);
316 if (md.md_keylen == 0) {
317 gctl_error(req, "Invalid '%s' argument.", "keylen");
321 /* Not important here. */
323 /* Not important here. */
324 bzero(md.md_salt, sizeof(md.md_salt));
327 arc4rand(mkey, sizeof(mkey), 0);
329 /* Not important here. */
330 bzero(md.md_hash, sizeof(md.md_hash));
332 name = gctl_get_asciiparam(req, "arg0");
334 gctl_error(req, "No 'arg%u' argument.", 0);
337 if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
338 name += strlen("/dev/");
339 pp = g_provider_by_name(name);
341 gctl_error(req, "Provider %s is invalid.", name);
345 sectorsize = gctl_get_paraml(req, "sectorsize", sizeof(*sectorsize));
346 if (sectorsize == NULL) {
347 gctl_error(req, "No '%s' argument.", "sectorsize");
350 if (*sectorsize == 0)
351 md.md_sectorsize = pp->sectorsize;
353 if (*sectorsize < 0 || (*sectorsize % pp->sectorsize) != 0) {
354 gctl_error(req, "Invalid sector size.");
357 if (*sectorsize > PAGE_SIZE) {
358 gctl_error(req, "warning: Using sectorsize bigger than "
361 md.md_sectorsize = *sectorsize;
364 g_eli_create(req, mp, pp, &md, mkey, -1);
365 bzero(mkey, sizeof(mkey));
366 bzero(&md, sizeof(md));
370 g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
372 struct g_eli_softc *sc;
373 struct g_eli_metadata md;
374 struct g_provider *pp;
375 struct g_consumer *cp;
379 int *nargs, *boot, *noboot, *trim, *notrim;
380 int zero, error, changed;
388 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
390 gctl_error(req, "No '%s' argument.", "nargs");
394 gctl_error(req, "Missing device(s).");
398 boot = gctl_get_paraml(req, "boot", sizeof(*boot));
401 noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot));
404 if (*boot && *noboot) {
405 gctl_error(req, "Options -b and -B are mutually exclusive.");
408 if (*boot || *noboot)
411 trim = gctl_get_paraml(req, "trim", sizeof(*trim));
414 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
417 if (*trim && *notrim) {
418 gctl_error(req, "Options -t and -T are mutually exclusive.");
421 if (*trim || *notrim)
425 gctl_error(req, "No option given.");
429 for (i = 0; i < *nargs; i++) {
430 snprintf(param, sizeof(param), "arg%d", i);
431 prov = gctl_get_asciiparam(req, param);
433 gctl_error(req, "No 'arg%d' argument.", i);
436 sc = g_eli_find_device(mp, prov);
439 * We ignore not attached providers, userland part will
442 G_ELI_DEBUG(1, "Skipping configuration of not attached "
443 "provider %s.", prov);
446 if (sc->sc_flags & G_ELI_FLAG_RO) {
447 gctl_error(req, "Cannot change configuration of "
448 "read-only provider %s.", prov);
452 if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) {
453 G_ELI_DEBUG(1, "BOOT flag already configured for %s.",
456 } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) {
457 G_ELI_DEBUG(1, "BOOT flag not configured for %s.",
462 if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) {
463 G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.",
466 } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) {
467 G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.",
472 if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
474 * ONETIME providers don't write metadata to
475 * disk, so don't try reading it. This means
476 * we're bit-flipping uninitialized memory in md
477 * below, but that's OK; we don't do anything
480 cp = LIST_FIRST(&sc->sc_geom->consumer);
482 error = g_eli_read_metadata(mp, pp, &md);
485 "Cannot read metadata from %s (error=%d).",
492 md.md_flags |= G_ELI_FLAG_BOOT;
493 sc->sc_flags |= G_ELI_FLAG_BOOT;
494 } else if (*noboot) {
495 md.md_flags &= ~G_ELI_FLAG_BOOT;
496 sc->sc_flags &= ~G_ELI_FLAG_BOOT;
500 md.md_flags |= G_ELI_FLAG_NODELETE;
501 sc->sc_flags |= G_ELI_FLAG_NODELETE;
503 md.md_flags &= ~G_ELI_FLAG_NODELETE;
504 sc->sc_flags &= ~G_ELI_FLAG_NODELETE;
507 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
508 /* There's no metadata on disk so we are done here. */
512 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
513 eli_metadata_encode(&md, sector);
514 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
518 "Cannot store metadata on %s (error=%d).",
521 bzero(&md, sizeof(md));
522 bzero(sector, pp->sectorsize);
528 g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp)
530 struct g_eli_softc *sc;
531 struct g_eli_metadata md;
532 struct g_provider *pp;
533 struct g_consumer *cp;
535 u_char *key, *mkeydst, *sector;
537 int keysize, nkey, error;
541 name = gctl_get_asciiparam(req, "arg0");
543 gctl_error(req, "No 'arg%u' argument.", 0);
546 sc = g_eli_find_device(mp, name);
548 gctl_error(req, "Provider %s is invalid.", name);
551 if (sc->sc_flags & G_ELI_FLAG_RO) {
552 gctl_error(req, "Cannot change keys for read-only provider.");
555 cp = LIST_FIRST(&sc->sc_geom->consumer);
558 error = g_eli_read_metadata(mp, pp, &md);
560 gctl_error(req, "Cannot read metadata from %s (error=%d).",
565 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
567 gctl_error(req, "No '%s' argument.", "keyno");
574 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
575 gctl_error(req, "Invalid '%s' argument.", "keyno");
579 valp = gctl_get_paraml(req, "iterations", sizeof(*valp));
581 gctl_error(req, "No '%s' argument.", "iterations");
584 /* Check if iterations number should and can be changed. */
586 if (bitcount32(md.md_keys) != 1) {
587 gctl_error(req, "To be able to use '-i' option, only "
588 "one key can be defined.");
591 if (md.md_keys != (1 << nkey)) {
592 gctl_error(req, "Only already defined key can be "
593 "changed when '-i' option is used.");
596 md.md_iterations = *valp;
599 key = gctl_get_param(req, "key", &keysize);
600 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
601 bzero(&md, sizeof(md));
602 gctl_error(req, "No '%s' argument.", "key");
606 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
607 md.md_keys |= (1 << nkey);
609 bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey));
611 /* Encrypt Master Key with the new key. */
612 error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst);
615 bzero(&md, sizeof(md));
616 gctl_error(req, "Cannot encrypt Master Key (error=%d).", error);
620 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
621 /* Store metadata with fresh key. */
622 eli_metadata_encode(&md, sector);
623 bzero(&md, sizeof(md));
624 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
626 bzero(sector, pp->sectorsize);
629 gctl_error(req, "Cannot store metadata on %s (error=%d).",
633 G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name);
637 g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp)
639 struct g_eli_softc *sc;
640 struct g_eli_metadata md;
641 struct g_provider *pp;
642 struct g_consumer *cp;
644 u_char *mkeydst, *sector;
647 int error, nkey, *all, *force;
652 nkey = 0; /* fixes causeless gcc warning */
654 name = gctl_get_asciiparam(req, "arg0");
656 gctl_error(req, "No 'arg%u' argument.", 0);
659 sc = g_eli_find_device(mp, name);
661 gctl_error(req, "Provider %s is invalid.", name);
664 if (sc->sc_flags & G_ELI_FLAG_RO) {
665 gctl_error(req, "Cannot delete keys for read-only provider.");
668 cp = LIST_FIRST(&sc->sc_geom->consumer);
671 error = g_eli_read_metadata(mp, pp, &md);
673 gctl_error(req, "Cannot read metadata from %s (error=%d).",
678 all = gctl_get_paraml(req, "all", sizeof(*all));
680 gctl_error(req, "No '%s' argument.", "all");
685 mkeydst = md.md_mkeys;
686 keysize = sizeof(md.md_mkeys);
688 force = gctl_get_paraml(req, "force", sizeof(*force));
690 gctl_error(req, "No '%s' argument.", "force");
694 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
696 gctl_error(req, "No '%s' argument.", "keyno");
703 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
704 gctl_error(req, "Invalid '%s' argument.", "keyno");
707 if (!(md.md_keys & (1 << nkey)) && !*force) {
708 gctl_error(req, "Master Key %u is not set.", nkey);
711 md.md_keys &= ~(1 << nkey);
712 if (md.md_keys == 0 && !*force) {
713 gctl_error(req, "This is the last Master Key. Use '-f' "
714 "flag if you really want to remove it.");
717 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
718 keysize = G_ELI_MKEYLEN;
721 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
722 for (i = 0; i <= g_eli_overwrites; i++) {
723 if (i == g_eli_overwrites)
724 bzero(mkeydst, keysize);
726 arc4rand(mkeydst, keysize, 0);
727 /* Store metadata with destroyed key. */
728 eli_metadata_encode(&md, sector);
729 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
732 G_ELI_DEBUG(0, "Cannot store metadata on %s "
733 "(error=%d).", pp->name, error);
736 * Flush write cache so we don't overwrite data N times in cache
737 * and only once on disk.
739 (void)g_io_flush(cp);
741 bzero(&md, sizeof(md));
742 bzero(sector, pp->sectorsize);
745 G_ELI_DEBUG(1, "All keys removed from %s.", pp->name);
747 G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name);
751 g_eli_suspend_one(struct g_eli_softc *sc, struct gctl_req *req)
753 struct g_eli_worker *wr;
757 KASSERT(sc != NULL, ("NULL sc"));
759 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
761 "Device %s is using one-time key, suspend not supported.",
766 mtx_lock(&sc->sc_queue_mtx);
767 if (sc->sc_flags & G_ELI_FLAG_SUSPEND) {
768 mtx_unlock(&sc->sc_queue_mtx);
769 gctl_error(req, "Device %s already suspended.",
773 sc->sc_flags |= G_ELI_FLAG_SUSPEND;
776 LIST_FOREACH(wr, &sc->sc_workers, w_next) {
782 /* Not all threads suspended. */
783 msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO,
787 * Clear sensitive data on suspend, they will be recovered on resume.
789 bzero(sc->sc_mkey, sizeof(sc->sc_mkey));
790 g_eli_key_destroy(sc);
791 bzero(sc->sc_akey, sizeof(sc->sc_akey));
792 bzero(&sc->sc_akeyctx, sizeof(sc->sc_akeyctx));
793 bzero(sc->sc_ivkey, sizeof(sc->sc_ivkey));
794 bzero(&sc->sc_ivctx, sizeof(sc->sc_ivctx));
795 mtx_unlock(&sc->sc_queue_mtx);
796 G_ELI_DEBUG(0, "Device %s has been suspended.", sc->sc_name);
800 g_eli_ctl_suspend(struct gctl_req *req, struct g_class *mp)
802 struct g_eli_softc *sc;
807 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
809 gctl_error(req, "No '%s' argument.", "nargs");
812 all = gctl_get_paraml(req, "all", sizeof(*all));
814 gctl_error(req, "No '%s' argument.", "all");
817 if (!*all && *nargs == 0) {
818 gctl_error(req, "Too few arguments.");
823 struct g_geom *gp, *gp2;
825 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
827 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
829 "Device %s is using one-time key, suspend not supported, skipping.",
833 g_eli_suspend_one(sc, req);
840 for (i = 0; i < *nargs; i++) {
841 snprintf(param, sizeof(param), "arg%d", i);
842 prov = gctl_get_asciiparam(req, param);
844 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
848 sc = g_eli_find_device(mp, prov);
850 G_ELI_DEBUG(0, "No such provider: %s.", prov);
853 g_eli_suspend_one(sc, req);
859 g_eli_ctl_resume(struct gctl_req *req, struct g_class *mp)
861 struct g_eli_metadata md;
862 struct g_eli_softc *sc;
863 struct g_provider *pp;
864 struct g_consumer *cp;
866 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
867 int *nargs, keysize, error;
872 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
874 gctl_error(req, "No '%s' argument.", "nargs");
878 gctl_error(req, "Invalid number of arguments.");
882 name = gctl_get_asciiparam(req, "arg0");
884 gctl_error(req, "No 'arg%u' argument.", 0);
887 sc = g_eli_find_device(mp, name);
889 gctl_error(req, "Provider %s is invalid.", name);
892 cp = LIST_FIRST(&sc->sc_geom->consumer);
894 error = g_eli_read_metadata(mp, pp, &md);
896 gctl_error(req, "Cannot read metadata from %s (error=%d).",
900 if (md.md_keys == 0x00) {
901 bzero(&md, sizeof(md));
902 gctl_error(req, "No valid keys on %s.", pp->name);
906 key = gctl_get_param(req, "key", &keysize);
907 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
908 bzero(&md, sizeof(md));
909 gctl_error(req, "No '%s' argument.", "key");
913 error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
916 bzero(&md, sizeof(md));
917 gctl_error(req, "Wrong key for %s.", pp->name);
919 } else if (error > 0) {
920 bzero(&md, sizeof(md));
921 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
925 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
927 mtx_lock(&sc->sc_queue_mtx);
928 if (!(sc->sc_flags & G_ELI_FLAG_SUSPEND))
929 gctl_error(req, "Device %s is not suspended.", name);
931 /* Restore sc_mkey, sc_ekeys, sc_akey and sc_ivkey. */
932 g_eli_mkey_propagate(sc, mkey);
933 sc->sc_flags &= ~G_ELI_FLAG_SUSPEND;
934 G_ELI_DEBUG(1, "Resumed %s.", pp->name);
937 mtx_unlock(&sc->sc_queue_mtx);
938 bzero(mkey, sizeof(mkey));
939 bzero(&md, sizeof(md));
943 g_eli_kill_one(struct g_eli_softc *sc)
945 struct g_provider *pp;
946 struct g_consumer *cp;
954 pp = LIST_FIRST(&sc->sc_geom->provider);
955 g_error_provider(pp, ENXIO);
957 cp = LIST_FIRST(&sc->sc_geom->consumer);
960 if (sc->sc_flags & G_ELI_FLAG_RO) {
961 G_ELI_DEBUG(0, "WARNING: Metadata won't be erased on read-only "
962 "provider: %s.", pp->name);
968 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK);
969 for (i = 0; i <= g_eli_overwrites; i++) {
970 if (i == g_eli_overwrites)
971 bzero(sector, pp->sectorsize);
973 arc4rand(sector, pp->sectorsize, 0);
974 err = g_write_data(cp, pp->mediasize - pp->sectorsize,
975 sector, pp->sectorsize);
977 G_ELI_DEBUG(0, "Cannot erase metadata on %s "
978 "(error=%d).", pp->name, err);
983 * Flush write cache so we don't overwrite data N times
984 * in cache and only once on disk.
986 (void)g_io_flush(cp);
991 G_ELI_DEBUG(0, "%s has been killed.", pp->name);
992 g_eli_destroy(sc, TRUE);
997 g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp)
1002 g_topology_assert();
1004 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1005 if (nargs == NULL) {
1006 gctl_error(req, "No '%s' argument.", "nargs");
1009 all = gctl_get_paraml(req, "all", sizeof(*all));
1011 gctl_error(req, "No '%s' argument.", "all");
1014 if (!*all && *nargs == 0) {
1015 gctl_error(req, "Too few arguments.");
1020 struct g_geom *gp, *gp2;
1022 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
1023 error = g_eli_kill_one(gp->softc);
1025 gctl_error(req, "Not fully done.");
1028 struct g_eli_softc *sc;
1033 for (i = 0; i < *nargs; i++) {
1034 snprintf(param, sizeof(param), "arg%d", i);
1035 prov = gctl_get_asciiparam(req, param);
1037 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
1041 sc = g_eli_find_device(mp, prov);
1043 G_ELI_DEBUG(0, "No such provider: %s.", prov);
1046 error = g_eli_kill_one(sc);
1048 gctl_error(req, "Not fully done.");
1054 g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb)
1058 g_topology_assert();
1060 version = gctl_get_paraml(req, "version", sizeof(*version));
1061 if (version == NULL) {
1062 gctl_error(req, "No '%s' argument.", "version");
1065 while (*version != G_ELI_VERSION) {
1066 if (G_ELI_VERSION == G_ELI_VERSION_06 &&
1067 *version == G_ELI_VERSION_05) {
1071 if (G_ELI_VERSION == G_ELI_VERSION_07 &&
1072 (*version == G_ELI_VERSION_05 ||
1073 *version == G_ELI_VERSION_06)) {
1077 gctl_error(req, "Userland and kernel parts are out of sync.");
1081 if (strcmp(verb, "attach") == 0)
1082 g_eli_ctl_attach(req, mp);
1083 else if (strcmp(verb, "detach") == 0 || strcmp(verb, "stop") == 0)
1084 g_eli_ctl_detach(req, mp);
1085 else if (strcmp(verb, "onetime") == 0)
1086 g_eli_ctl_onetime(req, mp);
1087 else if (strcmp(verb, "configure") == 0)
1088 g_eli_ctl_configure(req, mp);
1089 else if (strcmp(verb, "setkey") == 0)
1090 g_eli_ctl_setkey(req, mp);
1091 else if (strcmp(verb, "delkey") == 0)
1092 g_eli_ctl_delkey(req, mp);
1093 else if (strcmp(verb, "suspend") == 0)
1094 g_eli_ctl_suspend(req, mp);
1095 else if (strcmp(verb, "resume") == 0)
1096 g_eli_ctl_resume(req, mp);
1097 else if (strcmp(verb, "kill") == 0)
1098 g_eli_ctl_kill(req, mp);
1100 gctl_error(req, "Unknown verb.");