Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 03 Sep 2014 14:13:53 -0500
From:      Karl Denninger <karl@denninger.net>
To:        freebsd-geom@freebsd.org
Subject:   Attempt to add multiple device attachment to "geli attach"
Message-ID:  <54076871.5010405@denninger.net>

next in thread | raw e-mail | index | archive | help
This is a cryptographically signed message in MIME format.

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

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 largest=20
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=20
less labels.)  You "geli init" them and then attach them and build a=20
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! =20
Needless to say that's not nice.  It's even worse if it's a raidz pool,=20
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=20
completely hosed.

So, here's the idea -- if you use the same password and/or keyfile for=20
ALL of the volumes then either they ALL mount (if you get it right) or=20
NONE of them mount (if you get it wrong.)  Now the pool won't import if=20
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 the =

attach command; I replaced that with "nargs < 1" for the error case. =20
Now I can pass multiple devices to the kernel's geom handler and they=20
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=20
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=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 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



--------------ms020807070100050304090902
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
KoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNDA5MDMxOTEzNTNaMCMGCSqGSIb3DQEJBDEW
BBRo5TI/5OwTSVfaIXgTkF5TYJ4SgTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL
BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA
MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIG0BgkrBgEEAYI3EAQxgaYwgaMwgZ0xCzAJBgNV
BAYTAlVTMRAwDgYDVQQIEwdGbG9yaWRhMRIwEAYDVQQHEwlOaWNldmlsbGUxGTAXBgNVBAoT
EEN1ZGEgU3lzdGVtcyBMTEMxHDAaBgNVBAMTE0N1ZGEgU3lzdGVtcyBMTEMgQ0ExLzAtBgkq
hkiG9w0BCQEWIGN1c3RvbWVyLXNlcnZpY2VAY3VkYXN5c3RlbXMubmV0AgEIMIG2BgsqhkiG
9w0BCRACCzGBpqCBozCBnTELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0Zsb3JpZGExEjAQBgNV
BAcTCU5pY2V2aWxsZTEZMBcGA1UEChMQQ3VkYSBTeXN0ZW1zIExMQzEcMBoGA1UEAxMTQ3Vk
YSBTeXN0ZW1zIExMQyBDQTEvMC0GCSqGSIb3DQEJARYgY3VzdG9tZXItc2VydmljZUBjdWRh
c3lzdGVtcy5uZXQCAQgwDQYJKoZIhvcNAQEBBQAEggIAaRY+vj1w0w5oF7vPnBRvVsH4a4Nf
UZ/S+ua6kEJCoJ7cmzz76oVnp0Nc0huidpnc6+edi8juUDWKluVTGLZnm0LI6EBUm8QoveXV
d2NJdW2CDVib4ziQqwlcIUfgkjVV+2aHs11ekxE7TKzwpdVeOmQ5Pso8T2xoWHU+M7blbg1x
ozs8v5HI/Em+3rHeulgHJ+PCcsoaTd5g+BD6eI04uwMt9nxulGeotSd23jpEUW1VrII7ZTtn
ffOAEyuhWAiOrypiyIX9bQ/1QZThZ6jPgNNqiynz+/WhNzRQ+dhrnyiDJekR9//8yTdlw8wK
wTkDclLdqrFznNNf6RVyH81fvUbtSbqgKeYWK27+PWkNjp9WgmUMCgQEDne6OYhObJ+Ud6k8
+/HrYz+RdNzPVD1YJOoQUf2nPkJe80An/506N78H5sOWN+VQxj9JxkYXDRWFwfu7qpIFYvdJ
mGvwceHKMEsBcLhFnmq6LaSB873q8nfcrJsjGckGvdyIl0gbGRfwRWaaoQICHz6zcIDz0fO4
4ypjGKt5uUB8rd15UNn6h9zDHKOn3cET4CxwKf+4BYKiP0vUbci0xswXsCw3mugRIQTPqHXm
b0TfUGdwHDlCk1cA8m5YooTA5VruybqPaEmQbEa5wSokMxdW7wZr0hzSHh9b109RUzPOyKQL
3rP34KAAAAAAAAA=
--------------ms020807070100050304090902--





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