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