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