Date: Mon, 23 Feb 2015 00:56:15 +0900 From: "Daisuke Aoyama" <aoyama@peach.ne.jp> To: "Brenden Bartelt" <brenden.bartelt@gmail.com>, "George Rosamond" <george@ceetonetechnology.com> Cc: freebsd-arm@freebsd.org, Pawel Jakub Dawidek <pjd@freebsd.org> Subject: Re: "geli: Wrong key" unable to attach in RPi/ARM environment Message-ID: <640B1015D2984FE0A5FB69DBA9ECD23E@ad.peach.ne.jp> In-Reply-To: <CANUxo4ooMHMeEBPBFH89nsHvrkt-nNmSt2xf-1TTSN6M4htxVg@mail.gmail.com> References: <CANUxo4omL1m0EkSnmad8qyZqRWbuZ5zJ29nzCA0%2BgSyCAyU9dw@mail.gmail.com> <54DB7B07.4080704@ceetonetechnology.com> <CANUxo4ooMHMeEBPBFH89nsHvrkt-nNmSt2xf-1TTSN6M4htxVg@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. ------=_NextPart_000_0571_01D04F03.866B0080 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit Hi all, It seems openssl(/usr/src/crypto/openssl/crypto/evp) doesn't like unaligned buffer. We use it from g_eli_key.c. decrypt() is called with tmpmkey located stack but encrypt() is called with the value passed to the function. According to definition in g_eli.h, md_mkeys is located odd address due to "uint8_t md_keys". So encrypt() is called with odd address! In armv6, it's a bad thing of course. armv6 can't handle unaligned data by some op. Fixing is very simple, don't pass mkey directly to openssl. Please try the patch attached this mail. (usage is bottom of this mail) I've only checked "geli init". If it does not work in other place, please follow up this mail. -------------------------------------------------- From: "Brenden Bartelt" <brenden.bartelt@gmail.com> Sent: Thursday, February 12, 2015 1:08 AM To: "George Rosamond" <george@ceetonetechnology.com> Cc: <freebsd-arm@freebsd.org>; "Pawel Jakub Dawidek" <pjd@freebsd.org> Subject: Re: "geli: Wrong key" unable to attach in RPi/ARM environment > I have tried it both with and without a -K/-k keyfile specified and with > and without a passphrase (-P/-p). Any combination results in the same > "geli: Wrong key for mmcsd0s3." > For the sake of thoroughness I have even tried it with no PKCS#5v2 > iterations and with a NULL ealgo. > Each attempt writes a master key to the device metadata, but subsequent > attempts to attach the device fail with a wrong key. > > On Wed, Feb 11, 2015 at 10:53 AM, George Rosamond < > george@ceetonetechnology.com> wrote: > >> Brenden Bartelt: >> > Hi all, >> > >> > This a follow up to a previous thread in freebsd-geom where it was >> > determined that geli is functional in 11.0-CURRENT and it could be an ARM >> > problem. >> > >> > I have been unable to geli attach in RPi, even with a very simple >> > passphrase ("test"). Has anyone had success with this? I have tried on an >> > external usb, da0 as well as a partition on the SD card itself, mmcsd0s3. >> > The geli init appears to work, and a geli dump reveals that a master key >> > was indeed written to the device. What is even more puzzling is that a >> geli >> > onetime will work for the device, so it would appear that geli is >> > functional, but something has gone wrong with the master key >> > generating/writing/reading operation. >> > >> > Can anyone shed some light on something I am missing? Is geli not fully >> > supported on ARM? >> > >> > Thanks, >> > Brenden >> >> I haven't tried this, but two things: >> >> 1. did you try setting the key with -k when you attach? >> >> 2. I don't know if he's on this list, but I'm adding pdj@ to the cc. >> >> g >> >> > >> > Log: >> > >> > # uname -a >> > FreeBSD raspberry-pi 11.0-CURRENT FreeBSD 11.0-CURRENT #0 r278031: Mon >> Feb >> > 2 02:54:08 UTC 2015 >> > root@releng2.nyi.freebsd.org:/usr/obj/arm.armv6/usr/src/sys/RPI-B >> > arm >> > >> > # kldstat >> > Id Refs Address Size Name >> > 8 1 0xc5657000 17000 geom_eli.ko >> > 9 1 0xc572e000 2c000 crypto.ko >> > >> > # geli init mmcsd0s3 >> > Enter new passphrase: >> > Reenter new passphrase: >> > >> > Metadata backup can be found in /var/backups/mmcsd0s3.eli and >> > can be restored with the following command: >> > >> > # geli restore /var/backups/mmcsd0s3.eli mmcsd0s3 >> > >> > # geli attach mmcsd0s3 >> > Enter passphrase: >> > geli: Wrong key for mmcsd0s3. >> > >> > # geli dump mmcsd0s3 >> > Metadata on mmcsd0s3: >> > magic: GEOM::ELI >> > version: 7 >> > flags: 0x0 >> > ealgo: AES-XTS >> > keylen: 128 >> > provsize: 24796725248 >> > sectorsize: 512 >> > keys: 0x01 >> > iterations: 21660 >> > Salt: >> > >> d2678fa977889263b18cbbb2e5a3151ac8185d9d0bc5dafa548abc4510ca49ce134ef9410cc63a9b0881514d9e9fedb6a3d392ba4096775030d0646fbfb4cce5 >> > Master Key: >> > >> 4c26413b864d809b7e537e13ad442d22eada3a12ef61cd538f3a2bc9fd3a1dbbe80e19d6a009c51784461380ff150602c31c4910ad63aa52d105fc93b2005f18cd0b187e0e56b44eabc9784a6255e696a9c398653e4ec669cae64961bd7b43d9af01fa0897f84fef1608c632bbb881d418bdf81e637afff4191ceda6ec829f33c93a0cb5ead63ee63e4c4ccc3ee0b076e6f86b05d514c8b006bf8a11e3f78ac658e56bd824d6958747f09f3c8e80861d2f19eed3f334bbcc83aa28a227239c4bd9c4390a9e1acb5aefed4ef4602432359271217bfb9676eb753930f5c9c45899b0f44bdd230517d3238fc9ab9763b2def43658f44fc76094ccb4af54c7c492a790eca0b407adf66fccf2f3b049c874b66d4bbccd4e82fe8a2e79985ae5e1d64affed7ac66808a2bbd9d661b460c2b9acc1bac5a537bc7d862c711c9ca4892fcf3e607b6ee255555b742352483b7ffda80545bd3774f90ff0e74db58ef87c6c050501c0643c3921345df6e6d7a296c7c535ec81468a8a739824673303664a8874 >> > MD5 hash: f97f3ca1cf95c25144c84a12b10d81ef >> > >> > # geli onetime mmcsd0s3 >> > # geli list >> > Geom name: mmcsd0s3.eli >> > State: ACTIVE >> > EncryptionAlgorithm: AES-XTS >> > KeyLength: 128 >> > Crypto: software >> > Version: 7 >> > Flags: ONETIME >> > KeysAllocated: 47 >> > KeysTotal: 47 >> > Providers: >> > 1. Name: mmcsd0s3.eli >> > Mediasize: 24796725248 (23G) >> > Sectorsize: 512 >> > Mode: r0w0e0 >> > Consumers: >> > 1. Name: mmcsd0s3 >> > Mediasize: 24796725248 (23G) >> > Sectorsize: 512 >> > Stripesize: 4194304 >> > Stripeoffset: 0 >> > Mode: r1w1e1 >> > _______________________________________________ >> > freebsd-arm@freebsd.org mailing list >> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm >> > To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org" >> > >> >> > _______________________________________________ > freebsd-arm@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-arm > To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org" g_eli_mkey_decrypt() @ /usr/src/sys/geom/eli/g_eli_key.c: ---------------------------------------------------------------------- 108 int 109 g_eli_mkey_decrypt(const struct g_eli_metadata *md, const unsigned char *key, 110 unsigned char *mkey, unsigned *nkeyp) 111 { 112 unsigned char tmpmkey[G_ELI_MKEYLEN]; 113 unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */ 114 const unsigned char *mmkey; 125 mmkey = md->md_mkeys; 126 for (nkey = 0; nkey < G_ELI_MAXMKEYS; nkey++, mmkey += G_ELI_MKEYLEN) { 127 bit = (1 << nkey); 128 if (!(md->md_keys & bit)) 129 continue; 130 bcopy(mmkey, tmpmkey, G_ELI_MKEYLEN); 131 error = g_eli_crypto_decrypt(md->md_ealgo, tmpmkey, 132 G_ELI_MKEYLEN, enckey, md->md_keylen); ---------------------------------------------------------------------- g_eli_mkey_encrypt() @ /usr/src/sys/geom/eli/g_eli_key.c: ---------------------------------------------------------------------- 156 int 157 g_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen, 158 unsigned char *mkey) 176 error = g_eli_crypto_encrypt(algo, mkey, G_ELI_MKEYLEN, enckey, keylen); ---------------------------------------------------------------------- /usr/src/sys/geom/eli/g_eli.h: ---------------------------------------------------------------------- 210 struct g_eli_metadata { 211 char md_magic[16]; /* Magic value. */ 212 uint32_t md_version; /* Version number. */ 213 uint32_t md_flags; /* Additional flags. */ 214 uint16_t md_ealgo; /* Encryption algorithm. */ 215 uint16_t md_keylen; /* Key length. */ 216 uint16_t md_aalgo; /* Authentication algorithm. */ 217 uint64_t md_provsize; /* Provider's size. */ 218 uint32_t md_sectorsize; /* Sector size. */ 219 uint8_t md_keys; /* Available keys. */ 220 int32_t md_iterations; /* Number of iterations for PKCS#5v2. */ 221 uint8_t md_salt[G_ELI_SALTLEN]; /* Salt. */ 222 /* Encrypted master key (IV-key, Data-key, HMAC). */ 223 uint8_t md_mkeys[G_ELI_MAXMKEYS * G_ELI_MKEYLEN]; 224 u_char md_hash[16]; /* MD5 hash. */ 225 } __packed; ---------------------------------------------------------------------- /usr/src/sys/geom/eli/g_eli_crypto.c: ---------------------------------------------------------------------- 119 static int 120 g_eli_crypto_cipher(u_int algo, int enc, u_char *data, size_t datasize, 121 const u_char *key, size_t keysize) 176 EVP_CIPHER_CTX_init(&ctx); 177 178 EVP_CipherInit_ex(&ctx, type, NULL, NULL, NULL, enc); 179 EVP_CIPHER_CTX_set_key_length(&ctx, keysize / 8); 180 EVP_CIPHER_CTX_set_padding(&ctx, 0); 181 bzero(iv, sizeof(iv)); 182 EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, enc); 183 184 if (EVP_CipherUpdate(&ctx, data, &outsize, data, datasize) == 0) { 185 EVP_CIPHER_CTX_cleanup(&ctx); 186 return (EINVAL); 187 } 188 assert(outsize == (int)datasize); 189 190 if (EVP_CipherFinal_ex(&ctx, data + outsize, &outsize) == 0) { 191 EVP_CIPHER_CTX_cleanup(&ctx); 192 return (EINVAL); 193 } 194 assert(outsize == 0); 195 196 EVP_CIPHER_CTX_cleanup(&ctx); 201 int 202 g_eli_crypto_encrypt(u_int algo, u_char *data, size_t datasize, 203 const u_char *key, size_t keysize) 204 { 205 206 /* We prefer AES-CBC for metadata protection. */ 207 if (algo == CRYPTO_AES_XTS) 208 algo = CRYPTO_AES_CBC; 209 210 return (g_eli_crypto_cipher(algo, 1, data, datasize, key, keysize)); 211 } ---------------------------------------------------------------------- How to use this patch on running system: ---------------------------------------------------------------------- If you don't have source tree, check out with your kernel version specified by "-r". # uname -v FreeBSD 11.0-CURRENT #0 r277169M: Wed Jan 14 22:06:07 JST 2015 aoyama@fbs11.local:/usr/local/src/crochet-freebsd/work/obj/arm.armv6/usr/src/sys/RPI-B-test22 # svnlite checkout -r 277169 svn://svn.FreeBSD.org/base/head /usr/src Apply the patch # cd /usr/src # patch < /path/to/g_eli_key.c.patch Build the patched shared library # cd /usr/src/sbin/geom/class/eli # make && make install Now you have patched shared library in /lib/geom/geom_eli.so geli command use this library. ---------------------------------------------------------------------- Thanks, -- Daisuke Aoyama ------=_NextPart_000_0571_01D04F03.866B0080 Content-Type: application/octet-stream; name="g_eli_key.c.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="g_eli_key.c.patch" Index: sys/geom/eli/g_eli_key.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= --- sys/geom/eli/g_eli_key.c (revision 277169)=0A= +++ sys/geom/eli/g_eli_key.c (working copy)=0A= @@ -158,6 +158,9 @@=0A= unsigned char *mkey)=0A= {=0A= unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */=0A= +#if !defined(__NO_STRICT_ALIGNMENT)=0A= + unsigned char tmpmkey[G_ELI_MKEYLEN];=0A= +#endif=0A= int error;=0A= =0A= /*=0A= @@ -164,7 +167,13 @@=0A= * To calculate HMAC, the whole key (G_ELI_USERKEYLEN bytes long) will=0A= * be used.=0A= */=0A= +#if !defined(__NO_STRICT_ALIGNMENT)=0A= + /* copy mkey to tmpmkey (sp aligned) */=0A= + bcopy(mkey, tmpmkey, G_ELI_MKEYLEN);=0A= + g_eli_mkey_hmac(tmpmkey, key);=0A= +#else=0A= g_eli_mkey_hmac(mkey, key);=0A= +#endif=0A= /*=0A= * The key for encryption is: enckey =3D HMAC_SHA512(Derived-Key, 1)=0A= */=0A= @@ -173,7 +182,14 @@=0A= * Encrypt the Master-Key and HMAC() result with the given key (this=0A= * time only 'keylen' bits from the key are used).=0A= */=0A= +#if !defined(__NO_STRICT_ALIGNMENT)=0A= + /* encrypt and back to mkey */=0A= + error =3D g_eli_crypto_encrypt(algo, tmpmkey, G_ELI_MKEYLEN, enckey, = keylen);=0A= + bcopy(tmpmkey, mkey, G_ELI_MKEYLEN);=0A= + bzero(tmpmkey, G_ELI_MKEYLEN);=0A= +#else=0A= error =3D g_eli_crypto_encrypt(algo, mkey, G_ELI_MKEYLEN, enckey, = keylen);=0A= +#endif=0A= =0A= bzero(enckey, sizeof(enckey));=0A= =0A= ------=_NextPart_000_0571_01D04F03.866B0080--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?640B1015D2984FE0A5FB69DBA9ECD23E>