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