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