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