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