Date: Wed, 03 Sep 2014 14:33:18 -0500 From: Karl Denninger <karl@denninger.net> To: freebsd-geom@freebsd.org Subject: Re: Attempt to add multiple device attachment to "geli attach" Message-ID: <54076CFE.5010308@denninger.net> In-Reply-To: <54076871.5010405@denninger.net> References: <54076871.5010405@denninger.net>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Never mind... I know what I missed -- the key generation that is passed
in is dependent on the metadata read from the userspace.
More work to do here.... will have to pass a separate key structure for
each disk and it will also require some more work in the userspace
command area so it doesn't prompt a second time for a password.
I'll post the completed patch set once I have it if people here think it
would be interesting.
On 9/3/2014 14:13, Karl Denninger wrote:
> I'm aware of the potential issues here in terms of keying risks, but
> there are plenty of reasons to support this capability with the
> largest one being ZFS volumes that you wish to run encrypted.
>
> Take the following:
>
> label/pool0
> label/pool1
> label/pool2
> label/pool3
>
> (all relative to /dev, of course)
>
> These are all gpt partitions on different devices (typically full
> disks less labels.) You "geli init" them and then attach them and
> build a raidz2 pool on that.
>
> OK, now the system is rebooted. If you use the rc.conf file's option
> to request geli passwords during the boot you had better not screw up
> three times for only ONE of these volumes or the pool WILL come up
> degraded! Needless to say that's not nice. It's even worse if it's a
> raidz pool, you blow it, you reattach that disk and allow it to
> resilver *and take a disk error on the remaining drives during the
> resilver* -- now you're completely hosed.
>
> So, here's the idea -- if you use the same password and/or keyfile for
> ALL of the volumes then either they ALL mount (if you get it right) or
> NONE of them mount (if you get it wrong.) Now the pool won't import
> if you get it wrong and you're safe from the risk of taking a forced
> resilver and potential data loss.
>
> The geom subclass command has a simple "nargs" test (must be "1") in
> the attach command; I replaced that with "nargs < 1" for the error
> case. Now I can pass multiple devices to the kernel's geom handler
> and they get passed to the kernel ctl handler.
>
> The following patch should, I believe, work -- but it doesn't. The
> first disk attaches but the second one that was init'd with the same
> passphrase fails.
>
> As near as I can tell the key components are not picked up off the
> metadata until the geom driver gets ahold of it -- and thus the second
> decryption attempt should work since on the second iteration through
> the code grabs the key parameters off the request a second time.
>
> But I'm obviously missing something because the second volume returns
> "Wrong key for ...."
>
> Ideas?
>
> Patch is relative to /usr/src/sys/geom/eli:
>
> *** g_eli_ctl.c.orig Wed Sep 3 13:11:52 2014
> --- g_eli_ctl.c Wed Sep 3 13:19:15 2014
> ***************
> *** 60,65 ****
> --- 60,68 ----
> int *nargs, *detach, *readonly;
> int keysize, error;
> u_int nkey;
> + char param[16];
> +
> + u_int count;
>
> g_topology_assert();
>
> ***************
> *** 68,74 ****
> gctl_error(req, "No '%s' argument.", "nargs");
> return;
> }
> ! if (*nargs != 1) {
> gctl_error(req, "Invalid number of arguments.");
> return;
> }
> --- 71,77 ----
> gctl_error(req, "No '%s' argument.", "nargs");
> return;
> }
> ! if (*nargs < 1) {
> gctl_error(req, "Invalid number of arguments.");
> return;
> }
> ***************
> *** 84,147 ****
> gctl_error(req, "No '%s' argument.", "readonly");
> return;
> }
>
> ! name = gctl_get_asciiparam(req, "arg0");
> ! if (name == NULL) {
> ! gctl_error(req, "No 'arg%u' argument.", 0);
> ! return;
> ! }
> ! if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
> ! name += strlen("/dev/");
> ! pp = g_provider_by_name(name);
> ! if (pp == NULL) {
> ! gctl_error(req, "Provider %s is invalid.", name);
> ! return;
> ! }
> ! error = g_eli_read_metadata(mp, pp, &md);
> ! if (error != 0) {
> ! gctl_error(req, "Cannot read metadata from %s (error=%d).",
> ! name, error);
> ! return;
> ! }
> ! if (md.md_keys == 0x00) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "No valid keys on %s.", pp->name);
> ! return;
> ! }
> !
> ! key = gctl_get_param(req, "key", &keysize);
> ! if (key == NULL || keysize != G_ELI_USERKEYLEN) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "No '%s' argument.", "key");
> ! return;
> ! }
> !
> ! error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
> ! bzero(key, keysize);
> ! if (error == -1) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "Wrong key for %s.", pp->name);
> ! return;
> ! } else if (error > 0) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).",
> ! pp->name, error);
> ! return;
> ! }
> ! G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
> !
> ! if (*detach && *readonly) {
> bzero(&md, sizeof(md));
> - gctl_error(req, "Options -d and -r are mutually exclusive.");
> - return;
> }
> - if (*detach)
> - md.md_flags |= G_ELI_FLAG_WO_DETACH;
> - if (*readonly)
> - md.md_flags |= G_ELI_FLAG_RO;
> - g_eli_create(req, mp, pp, &md, mkey, nkey);
> - bzero(mkey, sizeof(mkey));
> - bzero(&md, sizeof(md));
> }
>
> static struct g_eli_softc *
> --- 87,152 ----
> gctl_error(req, "No '%s' argument.", "readonly");
> return;
> }
> + for (count = 0; count < *nargs; count++) {
> + snprintf(param, sizeof(param), "arg%d", count);
> + name = gctl_get_asciiparam(req, param);
> + if (name == NULL) {
> + gctl_error(req, "No 'arg%u' argument.", count);
> + return;
> + }
> + if (strncmp(name, "/dev/", strlen("/dev/")) == 0)
> + name += strlen("/dev/");
> + pp = g_provider_by_name(name);
> + if (pp == NULL) {
> + gctl_error(req, "Provider %s is invalid.", name);
> + return;
> + }
> + error = g_eli_read_metadata(mp, pp, &md);
> + if (error != 0) {
> + gctl_error(req, "Cannot read metadata from %s (error=%d).",
> + name, error);
> + return;
> + }
> + if (md.md_keys == 0x00) {
> + bzero(&md, sizeof(md));
> + gctl_error(req, "No valid keys on %s.", pp->name);
> + return;
> + }
> +
> + key = gctl_get_param(req, "key", &keysize);
> + if (key == NULL || keysize != G_ELI_USERKEYLEN) {
> + bzero(&md, sizeof(md));
> + gctl_error(req, "No '%s' argument.", "key");
> + return;
> + }
>
> ! error = g_eli_mkey_decrypt(&md, key, mkey, &nkey);
> ! bzero(key, keysize);
> ! if (error == -1) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "Wrong key for %s.", pp->name);
> ! return;
> ! } else if (error > 0) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "Cannot decrypt Master Key for %s
> (error=%d).",
> ! pp->name, error);
> ! return;
> ! }
> ! G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name);
> !
> ! if (*detach && *readonly) {
> ! bzero(&md, sizeof(md));
> ! gctl_error(req, "Options -d and -r are mutually
> exclusive.");
> ! return;
> ! }
> ! if (*detach)
> ! md.md_flags |= G_ELI_FLAG_WO_DETACH;
> ! if (*readonly)
> ! md.md_flags |= G_ELI_FLAG_RO;
> ! g_eli_create(req, mp, pp, &md, mkey, nkey);
> ! bzero(mkey, sizeof(mkey));
> bzero(&md, sizeof(md));
> }
> }
>
> static struct g_eli_softc *
>
>
> ------------------------
>
--
-- Karl
karl@denninger.net
[-- Attachment #2 --]
0 *H
010 + 0 *H
O0K030
*H
010 UUS10UFlorida10U Niceville10U
Cuda Systems LLC10UCuda Systems LLC CA1/0- *H
customer-service@cudasystems.net0
130824190344Z
180823190344Z0[10 UUS10UFlorida10UKarl Denninger1!0 *H
karl@denninger.net0"0
*H
0
bi՞]MNԿawx?`)'ҴcWgR@BlWh+ u}ApdCF JVй~FOL}EW^bچYp3K&ׂ(R
lxڝ.xz?6&nsJ +1v9v/( kqĪp[vjcK%fϻe?iq]z
lyzFO'ppdX//Lw(3JIA*S#՟H[f|CGqJKooy.oEuOw$/섀$삻J9b|AP~8]D1YI<"""Y^T2iQ2b yH)] Ƶ0y$_N6XqMC 9 XgώjGTP"#nˋ"Bk1 00 U0 0 `HB0U0, `HB
OpenSSL Generated Certificate0U|8 ˴d[20U#0]Af4U3x&^"408 `HB+)https://cudasystems.net:11443/revoked.crl0
*H
gBwH]j\x`( &gW32"Uf^. ^Iϱ
k!DQA g{(w/)\N'[oRW@CHO>)XrTNɘ!u`xt5(=f\-l3<@C6mnhv##1ŃbH͍_Nq
aʷ?rk$^9TIa!kh,D -ct1
00010 UUS10UFlorida10U Niceville10U
Cuda Systems LLC10UCuda Systems LLC CA1/0- *H
customer-service@cudasystems.net0 + ;0 *H
1 *H
0 *H
1
140903193318Z0# *H
1p""!+E놆f0l *H
1_0]0 `He*0 `He0
*H
0*H
0
*H
@0+0
*H
(0 +710010 UUS10UFlorida10U Niceville10U
Cuda Systems LLC10UCuda Systems LLC CA1/0- *H
customer-service@cudasystems.net0*H
1010 UUS10UFlorida10U Niceville10U
Cuda Systems LLC10UCuda Systems LLC CA1/0- *H
customer-service@cudasystems.net0
*H
-ZYgLO}R&Hc+m>%",u!78Ckdv'ۊ_P8aἺ+urS\Lޙ? >;LD;pXg4|v`M0
Y/Y^*Qe807z@>~ոǶw+lfj[snu%bHK+_T1-Pfr"U~B9-g?fJKZ֛O͕پW'8QMlD
9▅pXed
_!{Mw"4yScUyno,<4L+d|-z,N=IgDVL4*?\<\(G=)Tɽ1.[vN(gQǍ`P6u=8FE
<pQDp~"4N+Ȧls*R<Ҝ5jQ
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?54076CFE.5010308>
