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