* [PATCH] s390/crypto: fix aes ctr concurrency issue @ 2013-11-19 10:22 Harald Freudenberger 2013-11-19 10:22 ` Harald Freudenberger 2013-11-22 13:58 ` Gerald Schaefer 0 siblings, 2 replies; 7+ messages in thread From: Harald Freudenberger @ 2013-11-19 10:22 UTC (permalink / raw) To: Herbert Xu Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer, Harald Freudenberger, Harald Freudenberger The aes-ctr mode used one preallocated page without any concurrency protection. When multiple threads run aes-ctr encryption or decryption this could lead to data corruption. The patch introduces locking for the preallocated page and alternatively allocating and freeing of an temp page in concurrency situations. Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Harald Freudenberger (1): s390/crypto: fix aes ctr concurrency issue arch/s390/crypto/aes_s390.c | 55 ++++++++++++++++++++++++++++++++---------- 1 files changed, 42 insertions(+), 13 deletions(-) ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-19 10:22 [PATCH] s390/crypto: fix aes ctr concurrency issue Harald Freudenberger @ 2013-11-19 10:22 ` Harald Freudenberger 2013-11-28 14:00 ` Herbert Xu 2013-11-22 13:58 ` Gerald Schaefer 1 sibling, 1 reply; 7+ messages in thread From: Harald Freudenberger @ 2013-11-19 10:22 UTC (permalink / raw) To: Herbert Xu Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer, Harald Freudenberger, Harald Freudenberger The aes-ctr mode used one preallocated page without any concurrency protection. When multiple threads run aes-ctr encryption or decryption this could lead to data corruption. The patch introduces locking for the preallocated page and alternatively allocating and freeing of an temp page in concurrency situations. --- arch/s390/crypto/aes_s390.c | 55 ++++++++++++++++++++++++++++++++---------- 1 files changed, 42 insertions(+), 13 deletions(-) diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 4363528..fcb5297 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c @@ -25,6 +25,7 @@ #include <linux/err.h> #include <linux/module.h> #include <linux/init.h> +#include <linux/mutex.h> #include "crypt_s390.h" #define AES_KEYLEN_128 1 @@ -32,6 +33,7 @@ #define AES_KEYLEN_256 4 static u8 *ctrblk; +static DEFINE_MUTEX(ctrblk_lock); static char keylen_flag; struct s390_aes_ctx { @@ -762,11 +764,25 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, unsigned int i, n, nbytes; u8 buf[AES_BLOCK_SIZE]; u8 *out, *in; + u8 *ctrpage; if (!walk->nbytes) return ret; - memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE); + if (mutex_trylock(&ctrblk_lock)) { + /* ctrblk is now reserved for us */ + ctrpage = ctrblk; + } else { + /* ctrblk is in use by someone else, alloc our own page */ + ctrpage = (u8*) __get_free_page(GFP_ATOMIC); + if (!ctrpage) { + /* gfp failed, wait until ctrblk becomes available */ + mutex_lock(&ctrblk_lock); + ctrpage = ctrblk; + } + } + + memcpy(ctrpage, walk->iv, AES_BLOCK_SIZE); while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { out = walk->dst.virt.addr; in = walk->src.virt.addr; @@ -775,17 +791,19 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1); for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { - memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE, + memcpy(ctrpage + i, ctrpage + i - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - crypto_inc(ctrblk + i, AES_BLOCK_SIZE); + crypto_inc(ctrpage + i, AES_BLOCK_SIZE); + } + ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrpage); + if (ret < 0 || ret != n) { + ret = -EIO; + goto out; } - ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); - if (ret < 0 || ret != n) - return -EIO; if (n > AES_BLOCK_SIZE) - memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, + memcpy(ctrpage, ctrpage + n - AES_BLOCK_SIZE, AES_BLOCK_SIZE); - crypto_inc(ctrblk, AES_BLOCK_SIZE); + crypto_inc(ctrpage, AES_BLOCK_SIZE); out += n; in += n; nbytes -= n; @@ -799,14 +817,25 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, out = walk->dst.virt.addr; in = walk->src.virt.addr; ret = crypt_s390_kmctr(func, sctx->key, buf, in, - AES_BLOCK_SIZE, ctrblk); - if (ret < 0 || ret != AES_BLOCK_SIZE) - return -EIO; + AES_BLOCK_SIZE, ctrpage); + if (ret < 0 || ret != AES_BLOCK_SIZE) { + ret = -EIO; + goto out; + } memcpy(out, buf, nbytes); - crypto_inc(ctrblk, AES_BLOCK_SIZE); + crypto_inc(ctrpage, AES_BLOCK_SIZE); ret = blkcipher_walk_done(desc, walk, 0); } - memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE); + memcpy(walk->iv, ctrpage, AES_BLOCK_SIZE); + +out: + if (ctrpage == ctrblk) { + /* free the reservation for ctrblk now */ + mutex_unlock(&ctrblk_lock); + } else { + /* free the page allocated above */ + free_page((unsigned long) ctrpage); + } return ret; } -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-19 10:22 ` Harald Freudenberger @ 2013-11-28 14:00 ` Herbert Xu 2013-11-28 15:39 ` Harald Freudenberger 0 siblings, 1 reply; 7+ messages in thread From: Herbert Xu @ 2013-11-28 14:00 UTC (permalink / raw) To: Harald Freudenberger Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer, Harald Freudenberger On Tue, Nov 19, 2013 at 11:22:12AM +0100, Harald Freudenberger wrote: > The aes-ctr mode used one preallocated page without any concurrency > protection. When multiple threads run aes-ctr encryption or decryption > this could lead to data corruption. > > The patch introduces locking for the preallocated page and alternatively > allocating and freeing of an temp page in concurrency situations. You can't use mutex_lock because you may be in a non-sleepable context. Perhaps just fall back to doing it block-by-block, like we do in aesni-intel on x86? I have to say that your hardware has a funny way of doing CTR. Somebody was generalising out of their backside :) Thanks, -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-28 14:00 ` Herbert Xu @ 2013-11-28 15:39 ` Harald Freudenberger 2013-11-29 1:50 ` Herbert Xu 0 siblings, 1 reply; 7+ messages in thread From: Harald Freudenberger @ 2013-11-28 15:39 UTC (permalink / raw) To: Herbert Xu Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer On Thu, 2013-11-28 at 22:00 +0800, Herbert Xu wrote: > On Tue, Nov 19, 2013 at 11:22:12AM +0100, Harald Freudenberger wrote: > > The aes-ctr mode used one preallocated page without any concurrency > > protection. When multiple threads run aes-ctr encryption or decryption > > this could lead to data corruption. > > > > The patch introduces locking for the preallocated page and alternatively > > allocating and freeing of an temp page in concurrency situations. > > You can't use mutex_lock because you may be in a non-sleepable > context. Perhaps just fall back to doing it block-by-block, like > we do in aesni-intel on x86? The first attempt to lock the mutex is done with mutex_trylock() which should be safe for non-sleepable context. If this fails, an attempt is made to allocate a fresh page __get_free_page(GFP_ATOMIC). If this also fails, well what could be done then ? I think, it is valid to wait for the preallocated page to get released with an mutex_lock(). Should I really add code here for handling the 3rd level of the exceptional path ? > > I have to say that your hardware has a funny way of doing CTR. > Somebody was generalising out of their backside :) > > Thanks, ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-28 15:39 ` Harald Freudenberger @ 2013-11-29 1:50 ` Herbert Xu 2013-11-29 8:58 ` Harald Freudenberger 0 siblings, 1 reply; 7+ messages in thread From: Herbert Xu @ 2013-11-29 1:50 UTC (permalink / raw) To: Harald Freudenberger Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer On Thu, Nov 28, 2013 at 04:39:43PM +0100, Harald Freudenberger wrote: > > > You can't use mutex_lock because you may be in a non-sleepable > > context. Perhaps just fall back to doing it block-by-block, like > > we do in aesni-intel on x86? > > The first attempt to lock the mutex is done with mutex_trylock() which > should be safe for non-sleepable context. If this fails, an attempt is > made to allocate a fresh page __get_free_page(GFP_ATOMIC). If this also > fails, well what could be done then ? I think, it is valid to wait for > the preallocated page to get released with an mutex_lock(). Should I > really add code here for handling the 3rd level of the exceptional > path ? If it's wrong per se, how does hiding it behind two if's make it OK? -- Email: Herbert Xu <herbert@gondor.apana.org.au> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-29 1:50 ` Herbert Xu @ 2013-11-29 8:58 ` Harald Freudenberger 0 siblings, 0 replies; 7+ messages in thread From: Harald Freudenberger @ 2013-11-29 8:58 UTC (permalink / raw) To: Herbert Xu Cc: linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Gerald Schaefer On Fri, 2013-11-29 at 09:50 +0800, Herbert Xu wrote: > On Thu, Nov 28, 2013 at 04:39:43PM +0100, Harald Freudenberger wrote: > > > > > You can't use mutex_lock because you may be in a non-sleepable > > > context. Perhaps just fall back to doing it block-by-block, like > > > we do in aesni-intel on x86? > > > > The first attempt to lock the mutex is done with mutex_trylock() which > > should be safe for non-sleepable context. If this fails, an attempt is > > made to allocate a fresh page __get_free_page(GFP_ATOMIC). If this also > > fails, well what could be done then ? I think, it is valid to wait for > > the preallocated page to get released with an mutex_lock(). Should I > > really add code here for handling the 3rd level of the exceptional > > path ? > > If it's wrong per se, how does hiding it behind two if's make it > OK? Sorry, I got the point now. Will do a rework of the patch according to your hints. Thanks ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] s390/crypto: fix aes ctr concurrency issue 2013-11-19 10:22 [PATCH] s390/crypto: fix aes ctr concurrency issue Harald Freudenberger 2013-11-19 10:22 ` Harald Freudenberger @ 2013-11-22 13:58 ` Gerald Schaefer 1 sibling, 0 replies; 7+ messages in thread From: Gerald Schaefer @ 2013-11-22 13:58 UTC (permalink / raw) To: Herbert Xu Cc: Harald Freudenberger, linux-crypto, Martin Schwidefsky, Ingo Tuchscherer, Harald Freudenberger On Tue, 19 Nov 2013 11:22:11 +0100 Harald Freudenberger <freude@linux.vnet.ibm.com> wrote: > The aes-ctr mode used one preallocated page without any concurrency > protection. When multiple threads run aes-ctr encryption or decryption > this could lead to data corruption. > > The patch introduces locking for the preallocated page and > alternatively allocating and freeing of an temp page in concurrency > situations. > > Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com> > > Harald Freudenberger (1): > s390/crypto: fix aes ctr concurrency issue > > arch/s390/crypto/aes_s390.c | 55 > ++++++++++++++++++++++++++++++++---------- 1 files changed, 42 > insertions(+), 13 deletions(-) Herbert, could you please add Cc: stable@vger.kernel.org to this? ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-11-29 8:58 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-11-19 10:22 [PATCH] s390/crypto: fix aes ctr concurrency issue Harald Freudenberger 2013-11-19 10:22 ` Harald Freudenberger 2013-11-28 14:00 ` Herbert Xu 2013-11-28 15:39 ` Harald Freudenberger 2013-11-29 1:50 ` Herbert Xu 2013-11-29 8:58 ` Harald Freudenberger 2013-11-22 13:58 ` Gerald Schaefer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox