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