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