From owner-freebsd-geom@FreeBSD.ORG Wed Sep 3 19:15:35 2014 Return-Path: Delivered-To: freebsd-geom@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 21F95EA8 for ; Wed, 3 Sep 2014 19:15:35 +0000 (UTC) Received: from fs.denninger.net (wsip-70-169-168-7.pn.at.cox.net [70.169.168.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "NewFS.denninger.net", Issuer "NewFS.denninger.net" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id C00D217B6 for ; Wed, 3 Sep 2014 19:15:34 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by fs.denninger.net (8.14.8/8.14.8) with ESMTP id s83JDwgo055792 for ; Wed, 3 Sep 2014 14:13:58 -0500 (CDT) (envelope-from karl@denninger.net) Received: from [127.0.0.1] (TLS/SSL) [192.168.1.40] by Spamblock-sys (LOCAL/AUTH); Wed Sep 3 14:13:58 2014 Message-ID: <54076871.5010405@denninger.net> Date: Wed, 03 Sep 2014 14:13:53 -0500 From: Karl Denninger User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0 MIME-Version: 1.0 To: freebsd-geom@freebsd.org Subject: Attempt to add multiple device attachment to "geli attach" Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms020807070100050304090902" X-Antivirus: avast! (VPS 140903-0, 09/03/2014), Outbound message X-Antivirus-Status: Clean X-BeenThere: freebsd-geom@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: GEOM-specific discussions and implementations List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Sep 2014 19:15:35 -0000 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--