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