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