"geli: Wrong key" unable to attach in RPi/ARM environment
Daisuke Aoyama
aoyama at peach.ne.jp
Sun Feb 22 15:56:17 UTC 2015
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 at gmail.com>
Sent: Thursday, February 12, 2015 1:08 AM
To: "George Rosamond" <george at ceetonetechnology.com>
Cc: <freebsd-arm at freebsd.org>; "Pawel Jakub Dawidek" <pjd at 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 at 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 at 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 at freebsd.org mailing list
>> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm
>> > To unsubscribe, send any mail to "freebsd-arm-unsubscribe at freebsd.org"
>> >
>>
>>
> _______________________________________________
> freebsd-arm at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-arm
> To unsubscribe, send any mail to "freebsd-arm-unsubscribe at 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 at 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: g_eli_key.c.patch
Type: application/octet-stream
Size: 1297 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-arm/attachments/20150223/fbcbefa3/attachment.obj>
More information about the freebsd-arm
mailing list