Skip site navigation (1)Skip section navigation (2)
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
This is a cryptographically signed message in MIME format.

--------------ms020901090103060705010404
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Never mind... I know what I missed -- the key generation that is passed=20
in is dependent on the metadata read from the userspace.

More work to do here.... will have to pass a separate key structure for=20
each disk and it will also require some more work in the userspace=20
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=20
> there are plenty of reasons to support this capability with the=20
> 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=20
> disks less labels.)  You "geli init" them and then attach them and=20
> build a raidz2 pool on that.
>
> OK, now the system is rebooted.  If you use the rc.conf file's option=20
> to request geli passwords during the boot you had better not screw up=20
> three times for only ONE of these volumes or the pool WILL come up=20
> 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=20
> resilver *and take a disk error on the remaining drives during the=20
> 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=20
> if you get it wrong and you're safe from the risk of taking a forced=20
> resilver and potential data loss.
>
> The geom subclass command has a simple "nargs" test (must be "1") in=20
> the attach command; I replaced that with "nargs < 1" for the error=20
> case.  Now I can pass multiple devices to the kernel's geom handler=20
> and they get passed to the kernel ctl handler.
>
> The following patch should, I believe, work -- but it doesn't. The=20
> first disk attaches but the second one that was init'd with the same=20
> passphrase fails.
>
> As near as I can tell the key components are not picked up off the=20
> metadata until the geom driver gets ahold of it -- and thus the second =

> decryption attempt should work since on the second iteration through=20
> the code grabs the key parameters off the request a second time.
>
> But I'm obviously missing something because the second volume returns=20
> "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 !=3D 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 =3D gctl_get_asciiparam(req, "arg0");
> !     if (name =3D=3D NULL) {
> !         gctl_error(req, "No 'arg%u' argument.", 0);
> !         return;
> !     }
> !     if (strncmp(name, "/dev/", strlen("/dev/")) =3D=3D 0)
> !         name +=3D strlen("/dev/");
> !     pp =3D g_provider_by_name(name);
> !     if (pp =3D=3D NULL) {
> !         gctl_error(req, "Provider %s is invalid.", name);
> !         return;
> !     }
> !     error =3D g_eli_read_metadata(mp, pp, &md);
> !     if (error !=3D 0) {
> !         gctl_error(req, "Cannot read metadata from %s (error=3D%d).",=

> !             name, error);
> !         return;
> !     }
> !     if (md.md_keys =3D=3D 0x00) {
> !         bzero(&md, sizeof(md));
> !         gctl_error(req, "No valid keys on %s.", pp->name);
> !         return;
> !     }
> !
> !     key =3D gctl_get_param(req, "key", &keysize);
> !     if (key =3D=3D NULL || keysize !=3D G_ELI_USERKEYLEN) {
> !         bzero(&md, sizeof(md));
> !         gctl_error(req, "No '%s' argument.", "key");
> !         return;
> !     }
> !
> !     error =3D g_eli_mkey_decrypt(&md, key, mkey, &nkey);
> !     bzero(key, keysize);
> !     if (error =3D=3D -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=3D%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 |=3D G_ELI_FLAG_WO_DETACH;
> -     if (*readonly)
> -         md.md_flags |=3D 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 =3D 0; count < *nargs; count++) {
> +         snprintf(param, sizeof(param), "arg%d", count);
> +         name =3D gctl_get_asciiparam(req, param);
> +         if (name =3D=3D NULL) {
> +             gctl_error(req, "No 'arg%u' argument.", count);
> +             return;
> +         }
> +         if (strncmp(name, "/dev/", strlen("/dev/")) =3D=3D 0)
> +             name +=3D strlen("/dev/");
> +         pp =3D g_provider_by_name(name);
> +         if (pp =3D=3D NULL) {
> +             gctl_error(req, "Provider %s is invalid.", name);
> +             return;
> +         }
> +         error =3D g_eli_read_metadata(mp, pp, &md);
> +         if (error !=3D 0) {
> +             gctl_error(req, "Cannot read metadata from %s (error=3D%d=
).",
> +                 name, error);
> +             return;
> +         }
> +         if (md.md_keys =3D=3D 0x00) {
> +             bzero(&md, sizeof(md));
> +             gctl_error(req, "No valid keys on %s.", pp->name);
> +             return;
> +         }
> +
> +         key =3D gctl_get_param(req, "key", &keysize);
> +         if (key =3D=3D NULL || keysize !=3D G_ELI_USERKEYLEN) {
> +             bzero(&md, sizeof(md));
> +             gctl_error(req, "No '%s' argument.", "key");
> +             return;
> +         }
>
> !         error =3D g_eli_mkey_decrypt(&md, key, mkey, &nkey);
> !         bzero(key, keysize);
> !         if (error =3D=3D -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=20
> (error=3D%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=20
> exclusive.");
> !             return;
> !         }
> !         if (*detach)
> !             md.md_flags |=3D G_ELI_FLAG_WO_DETACH;
> !         if (*readonly)
> !             md.md_flags |=3D 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 *
>
>
> ------------------------
>

--=20
-- Karl
karl@denninger.net



--------------ms020901090103060705010404
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature

MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIIFTzCC
BUswggQzoAMCAQICAQgwDQYJKoZIhvcNAQEFBQAwgZ0xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
EwdGbG9yaWRhMRIwEAYDVQQHEwlOaWNldmlsbGUxGTAXBgNVBAoTEEN1ZGEgU3lzdGVtcyBM
TEMxHDAaBgNVBAMTE0N1ZGEgU3lzdGVtcyBMTEMgQ0ExLzAtBgkqhkiG9w0BCQEWIGN1c3Rv
bWVyLXNlcnZpY2VAY3VkYXN5c3RlbXMubmV0MB4XDTEzMDgyNDE5MDM0NFoXDTE4MDgyMzE5
MDM0NFowWzELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExFzAVBgNVBAMTDkthcmwg
RGVubmluZ2VyMSEwHwYJKoZIhvcNAQkBFhJrYXJsQGRlbm5pbmdlci5uZXQwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQC5n2KBrBmG22nVntVdvgKCB9UcnapNThrW1L+dq6th
d9l4mj+qYMUpJ+8I0rTbY1dn21IXQBoBQmy8t1doKwmTdQ59F0FwZEPt/fGbRgBKVt3Quf6W
6n7kRk9MG6gdD7V9vPpFV41e+5MWYtqGWY3ScDP8SyYLjL/Xgr+5KFKkDfuubK8DeNqdLniV
jHo/vqmIgO+6NgzPGPgmbutzFQXlxUqjiNAAKzF2+Tkddi+WKABrcc/EqnBb0X8GdqcIamO5
SyVmuM+7Zdns7D9pcV16zMMQ8LfNFQCDvbCuuQKMDg2F22x5ekYXpwjqTyfjcHBkWC8vFNoY
5aFMdyiN/Kkz0/kduP2ekYOgkRqcShfLEcG9SQ4LQZgqjMpTjSOGzBr3tOvVn5LkSJSHW2Z8
Q0dxSkvFG2/lsOWFbwQeeZSaBi5vRZCYCOf5tRd1+E93FyQfpt4vsrXshIAk7IK7f0qXvxP4
GDli5PKIEubD2Bn+gp3vB/DkfKySh5NBHVB+OPCoXRUWBkQxme65wBO02OZZt0k8Iq0i4Rci
WV6z+lQHqDKtaVGgMsHn6PoeYhjf5Al5SP+U3imTjF2aCca1iDB5JOccX04MNljvifXgcbJN
nkMgrzmm1ZgJ1PLur/ADWPlnz45quOhHg1TfUCLfI/DzgG7Z6u+oy4siQuFr9QT0MQIDAQAB
o4HWMIHTMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgWgMAsGA1UdDwQEAwIF4DAsBglg
hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFHw4
+LnuALyLA5Cgy7T5ZAX1WzKPMB8GA1UdIwQYMBaAFF3U3hpBZq40HB5VM7B44/gmXiI0MDgG
CWCGSAGG+EIBAwQrFilodHRwczovL2N1ZGFzeXN0ZW1zLm5ldDoxMTQ0My9yZXZva2VkLmNy
bDANBgkqhkiG9w0BAQUFAAOCAQEAZ0L4tQbBd0hd4wuw/YVqEBDDXJ54q2AoqQAmsOlnoxLO
31ehM/LvrTIP4yK2u1VmXtUumQ4Ao15JFM+xmwqtEGsh70RRrfVBAGd7KOZ3GB39FP2TgN/c
L5fJKVxOqvEnW6cL9QtvUlcM3hXg8kDv60OB+LIcSE/P3/s+0tEpWPjxm3LHVE7JmPbZIcJ1
YMoZvHh0NSjY5D0HZlwtbDO7pDz9sZf1QEOgjH828fhtborkaHaUI46pmrMjiBnY6ujXMcWD
pxtikki0zY22nrxfTs5xDWGxyrc/cmucjxClJF6+OYVUSaZhiiHfa9Pr+41okLgsRB0AmNwE
f6ItY3TI8DGCBQowggUGAgEBMIGjMIGdMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHRmxvcmlk
YTESMBAGA1UEBxMJTmljZXZpbGxlMRkwFwYDVQQKExBDdWRhIFN5c3RlbXMgTExDMRwwGgYD
VQQDExNDdWRhIFN5c3RlbXMgTExDIENBMS8wLQYJKoZIhvcNAQkBFiBjdXN0b21lci1zZXJ2
aWNlQGN1ZGFzeXN0ZW1zLm5ldAIBCDAJBgUrDgMCGgUAoIICOzAYBgkqhkiG9w0BCQMxCwYJ
KoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNDA5MDMxOTMzMThaMCMGCSqGSIb3DQEJBDEW
BBQZsZ8ZsnAinCIEIb7p7StF64aGZjBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL
BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA
MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIG0BgkrBgEEAYI3EAQxgaYwgaMwgZ0xCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdGbG9yaWRhMRIwEAYDVQQHEwlOaWNldmlsbGUxGTAXBgNVBAoT
EEN1ZGEgU3lzdGVtcyBMTEMxHDAaBgNVBAMTE0N1ZGEgU3lzdGVtcyBMTEMgQ0ExLzAtBgkq
hkiG9w0BCQEWIGN1c3RvbWVyLXNlcnZpY2VAY3VkYXN5c3RlbXMubmV0AgEIMIG2BgsqhkiG
9w0BCRACCzGBpqCBozCBnTELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExEjAQBgNV
BAcTCU5pY2V2aWxsZTEZMBcGA1UEChMQQ3VkYSBTeXN0ZW1zIExMQzEcMBoGA1UEAxMTQ3Vk
YSBTeXN0ZW1zIExMQyBDQTEvMC0GCSqGSIb3DQEJARYgY3VzdG9tZXItc2VydmljZUBjdWRh
c3lzdGVtcy5uZXQCAQgwDQYJKoZIhvcNAQEBBQAEggIALQFa3eJZZxtMzPFPuRq3fd5Sj78m
SGOCuJMrFtxtPiX/IiyqF9UGdfOJ2yGagMw3m+23+Oc4QxKOHr3va2SuqYiBFqh2J9uKX6b+
p1A4YQ7+4by6+it1nXJTg7pcrp/XvEwI3pm7PwnivT47FdAV6/2G+tBM2kQ75XBYZzSHmXx2
YBlNj8LFMAoJE7j3FlmaLwNZXipRZe8C5PbEOKHz/DCYhjd6/kA+yH6z99W4pMe2dyvPAsfY
bGb/ahLIW6Jzbvh1JdsC/9jpYgt/r8HTCEhLK5eBX1TwrcH2MS2dtOAcgrNQZnIi4alVfrTj
yELdOS3cZz+8kwwG1WZKf+C3S4KOWgzWmx8FTxvNleHZvpFXu/6Z7yfTOJYQ8olR5k1sRArV
7YY50eKWhXD5WGWJ2O2FZA3xGM6NX4OFIXujzOBNFXcil/c0eQjqw+bphuTqoFOFY1WWtHn7
bpxvLLCAph08NJRMq48rZHynshAtev8sTj2zSWdEVrdM6bc0wxeimiqjP5mU1Vw8HvT91Fwo
R+7DPcIpVNnJvfAMEjEuW+N2BemgTiiT5cLh4cZnUZiV+RDHjRofmbtgwPdQuf4Tn/bbNnU9
OEaTnbpFDek8B9lwUUTWcAt+lSI095eXvN8aA+8cThfcK7HIpmyxc8MqUjzSnAakyDXi8qhq
2gdREbAAAAAAAAA=
--------------ms020901090103060705010404--





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?54076CFE.5010308>