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