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