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;
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 *
g_eli_find_device(struct g_class * mp,const char * prov)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
g_eli_ctl_detach(struct gctl_req * req,struct g_class * mp)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
g_eli_ctl_onetime(struct gctl_req * req,struct g_class * mp)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
g_eli_ctl_configure(struct gctl_req * req,struct g_class * mp)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;
380 int zero, error, changed;
381 u_int i;
382
383 g_topology_assert();
384
385 changed = 0;
386 zero = 0;
387
388 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
389 if (nargs == NULL) {
390 gctl_error(req, "No '%s' argument.", "nargs");
391 return;
392 }
393 if (*nargs <= 0) {
394 gctl_error(req, "Missing device(s).");
395 return;
396 }
397
398 boot = gctl_get_paraml(req, "boot", sizeof(*boot));
399 if (boot == NULL)
400 boot = &zero;
401 noboot = gctl_get_paraml(req, "noboot", sizeof(*noboot));
402 if (noboot == NULL)
403 noboot = &zero;
404 if (*boot && *noboot) {
405 gctl_error(req, "Options -b and -B are mutually exclusive.");
406 return;
407 }
408 if (*boot || *noboot)
409 changed = 1;
410
411 trim = gctl_get_paraml(req, "trim", sizeof(*trim));
412 if (trim == NULL)
413 trim = &zero;
414 notrim = gctl_get_paraml(req, "notrim", sizeof(*notrim));
415 if (notrim == NULL)
416 notrim = &zero;
417 if (*trim && *notrim) {
418 gctl_error(req, "Options -t and -T are mutually exclusive.");
419 return;
420 }
421 if (*trim || *notrim)
422 changed = 1;
423
424 if (!changed) {
425 gctl_error(req, "No option given.");
426 return;
427 }
428
429 for (i = 0; i < *nargs; i++) {
430 snprintf(param, sizeof(param), "arg%d", i);
431 prov = gctl_get_asciiparam(req, param);
432 if (prov == NULL) {
433 gctl_error(req, "No 'arg%d' argument.", i);
434 return;
435 }
436 sc = g_eli_find_device(mp, prov);
437 if (sc == NULL) {
438 /*
439 * We ignore not attached providers, userland part will
440 * take care of them.
441 */
442 G_ELI_DEBUG(1, "Skipping configuration of not attached "
443 "provider %s.", prov);
444 continue;
445 }
446 if (sc->sc_flags & G_ELI_FLAG_RO) {
447 gctl_error(req, "Cannot change configuration of "
448 "read-only provider %s.", prov);
449 continue;
450 }
451
452 if (*boot && (sc->sc_flags & G_ELI_FLAG_BOOT)) {
453 G_ELI_DEBUG(1, "BOOT flag already configured for %s.",
454 prov);
455 continue;
456 } else if (*noboot && !(sc->sc_flags & G_ELI_FLAG_BOOT)) {
457 G_ELI_DEBUG(1, "BOOT flag not configured for %s.",
458 prov);
459 continue;
460 }
461
462 if (*notrim && (sc->sc_flags & G_ELI_FLAG_NODELETE)) {
463 G_ELI_DEBUG(1, "TRIM disable flag already configured for %s.",
464 prov);
465 continue;
466 } else if (*trim && !(sc->sc_flags & G_ELI_FLAG_NODELETE)) {
467 G_ELI_DEBUG(1, "TRIM disable flag not configured for %s.",
468 prov);
469 continue;
470 }
471
472 if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
473 /*
474 * ONETIME providers don't write metadata to
475 * disk, so don't try reading it. This means
476 * we're bit-flipping uninitialized memory in md
477 * below, but that's OK; we don't do anything
478 * with it later.
479 */
480 cp = LIST_FIRST(&sc->sc_geom->consumer);
481 pp = cp->provider;
482 error = g_eli_read_metadata(mp, pp, &md);
483 if (error != 0) {
484 gctl_error(req,
485 "Cannot read metadata from %s (error=%d).",
486 prov, error);
487 continue;
488 }
489 }
490
491 if (*boot) {
492 md.md_flags |= G_ELI_FLAG_BOOT;
493 sc->sc_flags |= G_ELI_FLAG_BOOT;
494 } else if (*noboot) {
495 md.md_flags &= ~G_ELI_FLAG_BOOT;
496 sc->sc_flags &= ~G_ELI_FLAG_BOOT;
497 }
498
499 if (*notrim) {
500 md.md_flags |= G_ELI_FLAG_NODELETE;
501 sc->sc_flags |= G_ELI_FLAG_NODELETE;
502 } else if (*trim) {
503 md.md_flags &= ~G_ELI_FLAG_NODELETE;
504 sc->sc_flags &= ~G_ELI_FLAG_NODELETE;
505 }
506
507 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
508 /* There's no metadata on disk so we are done here. */
509 continue;
510 }
511
512 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
513 eli_metadata_encode(&md, sector);
514 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
515 pp->sectorsize);
516 if (error != 0) {
517 gctl_error(req,
518 "Cannot store metadata on %s (error=%d).",
519 prov, error);
520 }
521 bzero(&md, sizeof(md));
522 bzero(sector, pp->sectorsize);
523 free(sector, M_ELI);
524 }
525 }
526
527 static void
g_eli_ctl_setkey(struct gctl_req * req,struct g_class * mp)528 g_eli_ctl_setkey(struct gctl_req *req, struct g_class *mp)
529 {
530 struct g_eli_softc *sc;
531 struct g_eli_metadata md;
532 struct g_provider *pp;
533 struct g_consumer *cp;
534 const char *name;
535 u_char *key, *mkeydst, *sector;
536 intmax_t *valp;
537 int keysize, nkey, error;
538
539 g_topology_assert();
540
541 name = gctl_get_asciiparam(req, "arg0");
542 if (name == NULL) {
543 gctl_error(req, "No 'arg%u' argument.", 0);
544 return;
545 }
546 sc = g_eli_find_device(mp, name);
547 if (sc == NULL) {
548 gctl_error(req, "Provider %s is invalid.", name);
549 return;
550 }
551 if (sc->sc_flags & G_ELI_FLAG_RO) {
552 gctl_error(req, "Cannot change keys for read-only provider.");
553 return;
554 }
555 cp = LIST_FIRST(&sc->sc_geom->consumer);
556 pp = cp->provider;
557
558 error = g_eli_read_metadata(mp, pp, &md);
559 if (error != 0) {
560 gctl_error(req, "Cannot read metadata from %s (error=%d).",
561 name, error);
562 return;
563 }
564
565 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
566 if (valp == NULL) {
567 gctl_error(req, "No '%s' argument.", "keyno");
568 return;
569 }
570 if (*valp != -1)
571 nkey = *valp;
572 else
573 nkey = sc->sc_nkey;
574 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
575 gctl_error(req, "Invalid '%s' argument.", "keyno");
576 return;
577 }
578
579 valp = gctl_get_paraml(req, "iterations", sizeof(*valp));
580 if (valp == NULL) {
581 gctl_error(req, "No '%s' argument.", "iterations");
582 return;
583 }
584 /* Check if iterations number should and can be changed. */
585 if (*valp != -1) {
586 if (bitcount32(md.md_keys) != 1) {
587 gctl_error(req, "To be able to use '-i' option, only "
588 "one key can be defined.");
589 return;
590 }
591 if (md.md_keys != (1 << nkey)) {
592 gctl_error(req, "Only already defined key can be "
593 "changed when '-i' option is used.");
594 return;
595 }
596 md.md_iterations = *valp;
597 }
598
599 key = gctl_get_param(req, "key", &keysize);
600 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
601 bzero(&md, sizeof(md));
602 gctl_error(req, "No '%s' argument.", "key");
603 return;
604 }
605
606 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
607 md.md_keys |= (1 << nkey);
608
609 bcopy(sc->sc_mkey, mkeydst, sizeof(sc->sc_mkey));
610
611 /* Encrypt Master Key with the new key. */
612 error = g_eli_mkey_encrypt(md.md_ealgo, key, md.md_keylen, mkeydst);
613 bzero(key, keysize);
614 if (error != 0) {
615 bzero(&md, sizeof(md));
616 gctl_error(req, "Cannot encrypt Master Key (error=%d).", error);
617 return;
618 }
619
620 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
621 /* Store metadata with fresh key. */
622 eli_metadata_encode(&md, sector);
623 bzero(&md, sizeof(md));
624 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
625 pp->sectorsize);
626 bzero(sector, pp->sectorsize);
627 free(sector, M_ELI);
628 if (error != 0) {
629 gctl_error(req, "Cannot store metadata on %s (error=%d).",
630 pp->name, error);
631 return;
632 }
633 G_ELI_DEBUG(1, "Key %u changed on %s.", nkey, pp->name);
634 }
635
636 static void
g_eli_ctl_delkey(struct gctl_req * req,struct g_class * mp)637 g_eli_ctl_delkey(struct gctl_req *req, struct g_class *mp)
638 {
639 struct g_eli_softc *sc;
640 struct g_eli_metadata md;
641 struct g_provider *pp;
642 struct g_consumer *cp;
643 const char *name;
644 u_char *mkeydst, *sector;
645 intmax_t *valp;
646 size_t keysize;
647 int error, nkey, *all, *force;
648 u_int i;
649
650 g_topology_assert();
651
652 nkey = 0; /* fixes causeless gcc warning */
653
654 name = gctl_get_asciiparam(req, "arg0");
655 if (name == NULL) {
656 gctl_error(req, "No 'arg%u' argument.", 0);
657 return;
658 }
659 sc = g_eli_find_device(mp, name);
660 if (sc == NULL) {
661 gctl_error(req, "Provider %s is invalid.", name);
662 return;
663 }
664 if (sc->sc_flags & G_ELI_FLAG_RO) {
665 gctl_error(req, "Cannot delete keys for read-only provider.");
666 return;
667 }
668 cp = LIST_FIRST(&sc->sc_geom->consumer);
669 pp = cp->provider;
670
671 error = g_eli_read_metadata(mp, pp, &md);
672 if (error != 0) {
673 gctl_error(req, "Cannot read metadata from %s (error=%d).",
674 name, error);
675 return;
676 }
677
678 all = gctl_get_paraml(req, "all", sizeof(*all));
679 if (all == NULL) {
680 gctl_error(req, "No '%s' argument.", "all");
681 return;
682 }
683
684 if (*all) {
685 mkeydst = md.md_mkeys;
686 keysize = sizeof(md.md_mkeys);
687 } else {
688 force = gctl_get_paraml(req, "force", sizeof(*force));
689 if (force == NULL) {
690 gctl_error(req, "No '%s' argument.", "force");
691 return;
692 }
693
694 valp = gctl_get_paraml(req, "keyno", sizeof(*valp));
695 if (valp == NULL) {
696 gctl_error(req, "No '%s' argument.", "keyno");
697 return;
698 }
699 if (*valp != -1)
700 nkey = *valp;
701 else
702 nkey = sc->sc_nkey;
703 if (nkey < 0 || nkey >= G_ELI_MAXMKEYS) {
704 gctl_error(req, "Invalid '%s' argument.", "keyno");
705 return;
706 }
707 if (!(md.md_keys & (1 << nkey)) && !*force) {
708 gctl_error(req, "Master Key %u is not set.", nkey);
709 return;
710 }
711 md.md_keys &= ~(1 << nkey);
712 if (md.md_keys == 0 && !*force) {
713 gctl_error(req, "This is the last Master Key. Use '-f' "
714 "flag if you really want to remove it.");
715 return;
716 }
717 mkeydst = md.md_mkeys + nkey * G_ELI_MKEYLEN;
718 keysize = G_ELI_MKEYLEN;
719 }
720
721 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK | M_ZERO);
722 for (i = 0; i <= g_eli_overwrites; i++) {
723 if (i == g_eli_overwrites)
724 bzero(mkeydst, keysize);
725 else
726 arc4rand(mkeydst, keysize, 0);
727 /* Store metadata with destroyed key. */
728 eli_metadata_encode(&md, sector);
729 error = g_write_data(cp, pp->mediasize - pp->sectorsize, sector,
730 pp->sectorsize);
731 if (error != 0) {
732 G_ELI_DEBUG(0, "Cannot store metadata on %s "
733 "(error=%d).", pp->name, error);
734 }
735 /*
736 * Flush write cache so we don't overwrite data N times in cache
737 * and only once on disk.
738 */
739 (void)g_io_flush(cp);
740 }
741 bzero(&md, sizeof(md));
742 bzero(sector, pp->sectorsize);
743 free(sector, M_ELI);
744 if (*all)
745 G_ELI_DEBUG(1, "All keys removed from %s.", pp->name);
746 else
747 G_ELI_DEBUG(1, "Key %d removed from %s.", nkey, pp->name);
748 }
749
750 static void
g_eli_suspend_one(struct g_eli_softc * sc,struct gctl_req * req)751 g_eli_suspend_one(struct g_eli_softc *sc, struct gctl_req *req)
752 {
753 struct g_eli_worker *wr;
754
755 g_topology_assert();
756
757 KASSERT(sc != NULL, ("NULL sc"));
758
759 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
760 gctl_error(req,
761 "Device %s is using one-time key, suspend not supported.",
762 sc->sc_name);
763 return;
764 }
765
766 mtx_lock(&sc->sc_queue_mtx);
767 if (sc->sc_flags & G_ELI_FLAG_SUSPEND) {
768 mtx_unlock(&sc->sc_queue_mtx);
769 gctl_error(req, "Device %s already suspended.",
770 sc->sc_name);
771 return;
772 }
773 sc->sc_flags |= G_ELI_FLAG_SUSPEND;
774 wakeup(sc);
775 for (;;) {
776 LIST_FOREACH(wr, &sc->sc_workers, w_next) {
777 if (wr->w_active)
778 break;
779 }
780 if (wr == NULL)
781 break;
782 /* Not all threads suspended. */
783 msleep(&sc->sc_workers, &sc->sc_queue_mtx, PRIBIO,
784 "geli:suspend", 0);
785 }
786 /*
787 * Clear sensitive data on suspend, they will be recovered on resume.
788 */
789 bzero(sc->sc_mkey, sizeof(sc->sc_mkey));
790 g_eli_key_destroy(sc);
791 bzero(sc->sc_akey, sizeof(sc->sc_akey));
792 bzero(&sc->sc_akeyctx, sizeof(sc->sc_akeyctx));
793 bzero(sc->sc_ivkey, sizeof(sc->sc_ivkey));
794 bzero(&sc->sc_ivctx, sizeof(sc->sc_ivctx));
795 mtx_unlock(&sc->sc_queue_mtx);
796 G_ELI_DEBUG(0, "Device %s has been suspended.", sc->sc_name);
797 }
798
799 static void
g_eli_ctl_suspend(struct gctl_req * req,struct g_class * mp)800 g_eli_ctl_suspend(struct gctl_req *req, struct g_class *mp)
801 {
802 struct g_eli_softc *sc;
803 int *all, *nargs;
804
805 g_topology_assert();
806
807 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
808 if (nargs == NULL) {
809 gctl_error(req, "No '%s' argument.", "nargs");
810 return;
811 }
812 all = gctl_get_paraml(req, "all", sizeof(*all));
813 if (all == NULL) {
814 gctl_error(req, "No '%s' argument.", "all");
815 return;
816 }
817 if (!*all && *nargs == 0) {
818 gctl_error(req, "Too few arguments.");
819 return;
820 }
821
822 if (*all) {
823 struct g_geom *gp, *gp2;
824
825 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
826 sc = gp->softc;
827 if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
828 G_ELI_DEBUG(0,
829 "Device %s is using one-time key, suspend not supported, skipping.",
830 sc->sc_name);
831 continue;
832 }
833 g_eli_suspend_one(sc, req);
834 }
835 } else {
836 const char *prov;
837 char param[16];
838 int i;
839
840 for (i = 0; i < *nargs; i++) {
841 snprintf(param, sizeof(param), "arg%d", i);
842 prov = gctl_get_asciiparam(req, param);
843 if (prov == NULL) {
844 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
845 continue;
846 }
847
848 sc = g_eli_find_device(mp, prov);
849 if (sc == NULL) {
850 G_ELI_DEBUG(0, "No such provider: %s.", prov);
851 continue;
852 }
853 g_eli_suspend_one(sc, req);
854 }
855 }
856 }
857
858 static void
g_eli_ctl_resume(struct gctl_req * req,struct g_class * mp)859 g_eli_ctl_resume(struct gctl_req *req, struct g_class *mp)
860 {
861 struct g_eli_metadata md;
862 struct g_eli_softc *sc;
863 struct g_provider *pp;
864 struct g_consumer *cp;
865 const char *name;
866 u_char *key, mkey[G_ELI_DATAIVKEYLEN];
867 int *nargs, keysize, error;
868 u_int nkey;
869
870 g_topology_assert();
871
872 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
873 if (nargs == NULL) {
874 gctl_error(req, "No '%s' argument.", "nargs");
875 return;
876 }
877 if (*nargs != 1) {
878 gctl_error(req, "Invalid number of arguments.");
879 return;
880 }
881
882 name = gctl_get_asciiparam(req, "arg0");
883 if (name == NULL) {
884 gctl_error(req, "No 'arg%u' argument.", 0);
885 return;
886 }
887 sc = g_eli_find_device(mp, name);
888 if (sc == NULL) {
889 gctl_error(req, "Provider %s is invalid.", name);
890 return;
891 }
892 cp = LIST_FIRST(&sc->sc_geom->consumer);
893 pp = cp->provider;
894 error = g_eli_read_metadata(mp, pp, &md);
895 if (error != 0) {
896 gctl_error(req, "Cannot read metadata from %s (error=%d).",
897 name, error);
898 return;
899 }
900 if (md.md_keys == 0x00) {
901 bzero(&md, sizeof(md));
902 gctl_error(req, "No valid keys on %s.", pp->name);
903 return;
904 }
905
906 key = gctl_get_param(req, "key", &keysize);
907 if (key == NULL || keysize != G_ELI_USERKEYLEN) {
908 bzero(&md, sizeof(md));
909 gctl_error(req, "No '%s' argument.", "key");
910 return;
911 }
912
913 error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
914 bzero(key, keysize);
915 if (error == -1) {
916 bzero(&md, sizeof(md));
917 gctl_error(req, "Wrong key for %s.", pp->name);
918 return;
919 } else if (error > 0) {
920 bzero(&md, sizeof(md));
921 gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
922 pp->name, error);
923 return;
924 }
925 G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
926
927 mtx_lock(&sc->sc_queue_mtx);
928 if (!(sc->sc_flags & G_ELI_FLAG_SUSPEND))
929 gctl_error(req, "Device %s is not suspended.", name);
930 else {
931 /* Restore sc_mkey, sc_ekeys, sc_akey and sc_ivkey. */
932 g_eli_mkey_propagate(sc, mkey);
933 sc->sc_flags &= ~G_ELI_FLAG_SUSPEND;
934 G_ELI_DEBUG(1, "Resumed %s.", pp->name);
935 wakeup(sc);
936 }
937 mtx_unlock(&sc->sc_queue_mtx);
938 bzero(mkey, sizeof(mkey));
939 bzero(&md, sizeof(md));
940 }
941
942 static int
g_eli_kill_one(struct g_eli_softc * sc)943 g_eli_kill_one(struct g_eli_softc *sc)
944 {
945 struct g_provider *pp;
946 struct g_consumer *cp;
947 int error = 0;
948
949 g_topology_assert();
950
951 if (sc == NULL)
952 return (ENOENT);
953
954 pp = LIST_FIRST(&sc->sc_geom->provider);
955 g_error_provider(pp, ENXIO);
956
957 cp = LIST_FIRST(&sc->sc_geom->consumer);
958 pp = cp->provider;
959
960 if (sc->sc_flags & G_ELI_FLAG_RO) {
961 G_ELI_DEBUG(0, "WARNING: Metadata won't be erased on read-only "
962 "provider: %s.", pp->name);
963 } else {
964 u_char *sector;
965 u_int i;
966 int err;
967
968 sector = malloc(pp->sectorsize, M_ELI, M_WAITOK);
969 for (i = 0; i <= g_eli_overwrites; i++) {
970 if (i == g_eli_overwrites)
971 bzero(sector, pp->sectorsize);
972 else
973 arc4rand(sector, pp->sectorsize, 0);
974 err = g_write_data(cp, pp->mediasize - pp->sectorsize,
975 sector, pp->sectorsize);
976 if (err != 0) {
977 G_ELI_DEBUG(0, "Cannot erase metadata on %s "
978 "(error=%d).", pp->name, err);
979 if (error == 0)
980 error = err;
981 }
982 /*
983 * Flush write cache so we don't overwrite data N times
984 * in cache and only once on disk.
985 */
986 (void)g_io_flush(cp);
987 }
988 free(sector, M_ELI);
989 }
990 if (error == 0)
991 G_ELI_DEBUG(0, "%s has been killed.", pp->name);
992 g_eli_destroy(sc, TRUE);
993 return (error);
994 }
995
996 static void
g_eli_ctl_kill(struct gctl_req * req,struct g_class * mp)997 g_eli_ctl_kill(struct gctl_req *req, struct g_class *mp)
998 {
999 int *all, *nargs;
1000 int error;
1001
1002 g_topology_assert();
1003
1004 nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
1005 if (nargs == NULL) {
1006 gctl_error(req, "No '%s' argument.", "nargs");
1007 return;
1008 }
1009 all = gctl_get_paraml(req, "all", sizeof(*all));
1010 if (all == NULL) {
1011 gctl_error(req, "No '%s' argument.", "all");
1012 return;
1013 }
1014 if (!*all && *nargs == 0) {
1015 gctl_error(req, "Too few arguments.");
1016 return;
1017 }
1018
1019 if (*all) {
1020 struct g_geom *gp, *gp2;
1021
1022 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
1023 error = g_eli_kill_one(gp->softc);
1024 if (error != 0)
1025 gctl_error(req, "Not fully done.");
1026 }
1027 } else {
1028 struct g_eli_softc *sc;
1029 const char *prov;
1030 char param[16];
1031 int i;
1032
1033 for (i = 0; i < *nargs; i++) {
1034 snprintf(param, sizeof(param), "arg%d", i);
1035 prov = gctl_get_asciiparam(req, param);
1036 if (prov == NULL) {
1037 G_ELI_DEBUG(0, "No 'arg%d' argument.", i);
1038 continue;
1039 }
1040
1041 sc = g_eli_find_device(mp, prov);
1042 if (sc == NULL) {
1043 G_ELI_DEBUG(0, "No such provider: %s.", prov);
1044 continue;
1045 }
1046 error = g_eli_kill_one(sc);
1047 if (error != 0)
1048 gctl_error(req, "Not fully done.");
1049 }
1050 }
1051 }
1052
1053 void
g_eli_config(struct gctl_req * req,struct g_class * mp,const char * verb)1054 g_eli_config(struct gctl_req *req, struct g_class *mp, const char *verb)
1055 {
1056 uint32_t *version;
1057
1058 g_topology_assert();
1059
1060 version = gctl_get_paraml(req, "version", sizeof(*version));
1061 if (version == NULL) {
1062 gctl_error(req, "No '%s' argument.", "version");
1063 return;
1064 }
1065 while (*version != G_ELI_VERSION) {
1066 if (G_ELI_VERSION == G_ELI_VERSION_06 &&
1067 *version == G_ELI_VERSION_05) {
1068 /* Compatible. */
1069 break;
1070 }
1071 if (G_ELI_VERSION == G_ELI_VERSION_07 &&
1072 (*version == G_ELI_VERSION_05 ||
1073 *version == G_ELI_VERSION_06)) {
1074 /* Compatible. */
1075 break;
1076 }
1077 gctl_error(req, "Userland and kernel parts are out of sync.");
1078 return;
1079 }
1080
1081 if (strcmp(verb, "attach") == 0)
1082 g_eli_ctl_attach(req, mp);
1083 else if (strcmp(verb, "detach") == 0 || strcmp(verb, "stop") == 0)
1084 g_eli_ctl_detach(req, mp);
1085 else if (strcmp(verb, "onetime") == 0)
1086 g_eli_ctl_onetime(req, mp);
1087 else if (strcmp(verb, "configure") == 0)
1088 g_eli_ctl_configure(req, mp);
1089 else if (strcmp(verb, "setkey") == 0)
1090 g_eli_ctl_setkey(req, mp);
1091 else if (strcmp(verb, "delkey") == 0)
1092 g_eli_ctl_delkey(req, mp);
1093 else if (strcmp(verb, "suspend") == 0)
1094 g_eli_ctl_suspend(req, mp);
1095 else if (strcmp(verb, "resume") == 0)
1096 g_eli_ctl_resume(req, mp);
1097 else if (strcmp(verb, "kill") == 0)
1098 g_eli_ctl_kill(req, mp);
1099 else
1100 gctl_error(req, "Unknown verb.");
1101 }
1102