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