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