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