On Tue, 2016-09-20 at 20:35 +0800, Herbert Xu wrote: > On Tue, Sep 20, 2016 at 08:11:51AM -0400, Mimi Zohar wrote: > > Hi Herbert, > > > > The initial random iv value, initialized in encrypted_init(), should > > not be modified. Commit c3917fd "KEYS: Use skcipher", which replaced > > the blkcipher with skcipher, modifies the iv in > > crypto_skcipher_encrypt()/decrypt(). > > > > The following example creates an encrypted key, writes the key to a > > file, and then loads the key from the file. To illustrate the problem, > > this patch provides crypto_skcipher_encrypt()/decrypt() with a copy of > > the iv. With this change, the resulting test-key and test-key1 keys > > are the same. > > Sorry, I missed the subtlety. This patch should fix the problem. Thanks! Mimi > > ---8<--- > Subject: KEYS: Fix skcipher IV clobbering > > The IV must not be modified by the skcipher operation so we need > to duplicate it. > > Fixes: c3917fd9dfbc ("KEYS: Use skcipher") > Cc: stable@xxxxxxxxxxxxxxx > Reported-by: Mimi Zohar <zohar@xxxxxxxxxxxxxxxxxx> > Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> > > diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c > index 5adbfc3..17a0610 100644 > --- a/security/keys/encrypted-keys/encrypted.c > +++ b/security/keys/encrypted-keys/encrypted.c > @@ -29,6 +29,7 @@ > #include <linux/rcupdate.h> > #include <linux/scatterlist.h> > #include <linux/ctype.h> > +#include <crypto/aes.h> > #include <crypto/hash.h> > #include <crypto/sha.h> > #include <crypto/skcipher.h> > @@ -478,6 +479,7 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, > struct crypto_skcipher *tfm; > struct skcipher_request *req; > unsigned int encrypted_datalen; > + u8 iv[AES_BLOCK_SIZE]; > unsigned int padlen; > char pad[16]; > int ret; > @@ -500,8 +502,8 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, > sg_init_table(sg_out, 1); > sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); > > - skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, > - epayload->iv); > + memcpy(iv, epayload->iv, sizeof(iv)); > + skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); > ret = crypto_skcipher_encrypt(req); > tfm = crypto_skcipher_reqtfm(req); > skcipher_request_free(req); > @@ -581,6 +583,7 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, > struct crypto_skcipher *tfm; > struct skcipher_request *req; > unsigned int encrypted_datalen; > + u8 iv[AES_BLOCK_SIZE]; > char pad[16]; > int ret; > > @@ -599,8 +602,8 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, > epayload->decrypted_datalen); > sg_set_buf(&sg_out[1], pad, sizeof pad); > > - skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, > - epayload->iv); > + memcpy(iv, epayload->iv, sizeof(iv)); > + skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); > ret = crypto_skcipher_decrypt(req); > tfm = crypto_skcipher_reqtfm(req); > skcipher_request_free(req); > -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html