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