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