g_eli_ctl.c revision 344397
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: stable/11/sys/geom/eli/g_eli_ctl.c 344397 2019-02-20 23:42:03Z kevans $");
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
50MALLOC_DECLARE(M_ELI);
51
52
53static void
54g_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
173static struct g_eli_softc *
174g_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
199static void
200g_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
257static void
258g_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
395static void
396g_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
617static void
618g_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
726static void
727g_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
840static void
841g_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
889static void
890g_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
948static void
949g_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
1030static int
1031g_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
1084static void
1085g_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
1141void
1142g_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