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