diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2016-09-20 08:35:55 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-09-22 05:42:07 -0400 |
commit | 456bee986e0a372ad4beed5d3cedb3622633d9df (patch) | |
tree | f15f1e438e2b88d6ecae117947a9cf90de1f28ba | |
parent | 2db34e78f126c6001d79d3b66ab1abb482dc7caa (diff) |
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@vger.kernel.org
Reported-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | security/keys/encrypted-keys/encrypted.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c index 5adbfc32242f..17a06105ccb6 100644 --- a/security/keys/encrypted-keys/encrypted.c +++ b/security/keys/encrypted-keys/encrypted.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/rcupdate.h> | 29 | #include <linux/rcupdate.h> |
30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
31 | #include <linux/ctype.h> | 31 | #include <linux/ctype.h> |
32 | #include <crypto/aes.h> | ||
32 | #include <crypto/hash.h> | 33 | #include <crypto/hash.h> |
33 | #include <crypto/sha.h> | 34 | #include <crypto/sha.h> |
34 | #include <crypto/skcipher.h> | 35 | #include <crypto/skcipher.h> |
@@ -478,6 +479,7 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
478 | struct crypto_skcipher *tfm; | 479 | struct crypto_skcipher *tfm; |
479 | struct skcipher_request *req; | 480 | struct skcipher_request *req; |
480 | unsigned int encrypted_datalen; | 481 | unsigned int encrypted_datalen; |
482 | u8 iv[AES_BLOCK_SIZE]; | ||
481 | unsigned int padlen; | 483 | unsigned int padlen; |
482 | char pad[16]; | 484 | char pad[16]; |
483 | int ret; | 485 | int ret; |
@@ -500,8 +502,8 @@ static int derived_key_encrypt(struct encrypted_key_payload *epayload, | |||
500 | sg_init_table(sg_out, 1); | 502 | sg_init_table(sg_out, 1); |
501 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); | 503 | sg_set_buf(sg_out, epayload->encrypted_data, encrypted_datalen); |
502 | 504 | ||
503 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, | 505 | memcpy(iv, epayload->iv, sizeof(iv)); |
504 | epayload->iv); | 506 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); |
505 | ret = crypto_skcipher_encrypt(req); | 507 | ret = crypto_skcipher_encrypt(req); |
506 | tfm = crypto_skcipher_reqtfm(req); | 508 | tfm = crypto_skcipher_reqtfm(req); |
507 | skcipher_request_free(req); | 509 | skcipher_request_free(req); |
@@ -581,6 +583,7 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
581 | struct crypto_skcipher *tfm; | 583 | struct crypto_skcipher *tfm; |
582 | struct skcipher_request *req; | 584 | struct skcipher_request *req; |
583 | unsigned int encrypted_datalen; | 585 | unsigned int encrypted_datalen; |
586 | u8 iv[AES_BLOCK_SIZE]; | ||
584 | char pad[16]; | 587 | char pad[16]; |
585 | int ret; | 588 | int ret; |
586 | 589 | ||
@@ -599,8 +602,8 @@ static int derived_key_decrypt(struct encrypted_key_payload *epayload, | |||
599 | epayload->decrypted_datalen); | 602 | epayload->decrypted_datalen); |
600 | sg_set_buf(&sg_out[1], pad, sizeof pad); | 603 | sg_set_buf(&sg_out[1], pad, sizeof pad); |
601 | 604 | ||
602 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, | 605 | memcpy(iv, epayload->iv, sizeof(iv)); |
603 | epayload->iv); | 606 | skcipher_request_set_crypt(req, sg_in, sg_out, encrypted_datalen, iv); |
604 | ret = crypto_skcipher_decrypt(req); | 607 | ret = crypto_skcipher_decrypt(req); |
605 | tfm = crypto_skcipher_reqtfm(req); | 608 | tfm = crypto_skcipher_reqtfm(req); |
606 | skcipher_request_free(req); | 609 | skcipher_request_free(req); |