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