crypto: nx - Fix reentrancy bugs

This patch fixes a host of reentrancy bugs in the nx driver.  The
following algorithms are affected:

* CCM
* GCM
* CTR
* XCBC
* SHA256
* SHA512

The crypto API allows a single transform to be used by multiple
threads simultaneously.  For example, IPsec will use a single tfm
to process packets for a given SA.  As packets may arrive on
multiple CPUs that tfm must be reentrant.

The nx driver does try to deal with this by using a spin lock.
Unfortunately only the basic AES/CBC/ECB algorithms do this in
the correct way.

The symptom of these bugs may range from the generation of incorrect
output to memory corruption.

Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/drivers/crypto/nx/nx-aes-gcm.c b/drivers/crypto/nx/nx-aes-gcm.c
index 08ac6d4..92c993f 100644
--- a/drivers/crypto/nx/nx-aes-gcm.c
+++ b/drivers/crypto/nx/nx-aes-gcm.c
@@ -317,6 +317,7 @@
 static int gcm_aes_nx_crypt(struct aead_request *req, int enc)
 {
 	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
+	struct nx_gcm_rctx *rctx = aead_request_ctx(req);
 	struct nx_csbcpb *csbcpb = nx_ctx->csbcpb;
 	struct blkcipher_desc desc;
 	unsigned int nbytes = req->cryptlen;
@@ -326,7 +327,7 @@
 
 	spin_lock_irqsave(&nx_ctx->lock, irq_flags);
 
-	desc.info = nx_ctx->priv.gcm.iv;
+	desc.info = rctx->iv;
 	/* initialize the counter */
 	*(u32 *)(desc.info + NX_GCM_CTR_OFFSET) = 1;
 
@@ -424,8 +425,8 @@
 
 static int gcm_aes_nx_encrypt(struct aead_request *req)
 {
-	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
-	char *iv = nx_ctx->priv.gcm.iv;
+	struct nx_gcm_rctx *rctx = aead_request_ctx(req);
+	char *iv = rctx->iv;
 
 	memcpy(iv, req->iv, 12);
 
@@ -434,8 +435,8 @@
 
 static int gcm_aes_nx_decrypt(struct aead_request *req)
 {
-	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
-	char *iv = nx_ctx->priv.gcm.iv;
+	struct nx_gcm_rctx *rctx = aead_request_ctx(req);
+	char *iv = rctx->iv;
 
 	memcpy(iv, req->iv, 12);
 
@@ -445,7 +446,8 @@
 static int gcm4106_aes_nx_encrypt(struct aead_request *req)
 {
 	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
-	char *iv = nx_ctx->priv.gcm.iv;
+	struct nx_gcm_rctx *rctx = aead_request_ctx(req);
+	char *iv = rctx->iv;
 	char *nonce = nx_ctx->priv.gcm.nonce;
 
 	memcpy(iv, nonce, NX_GCM4106_NONCE_LEN);
@@ -457,7 +459,8 @@
 static int gcm4106_aes_nx_decrypt(struct aead_request *req)
 {
 	struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(req->base.tfm);
-	char *iv = nx_ctx->priv.gcm.iv;
+	struct nx_gcm_rctx *rctx = aead_request_ctx(req);
+	char *iv = rctx->iv;
 	char *nonce = nx_ctx->priv.gcm.nonce;
 
 	memcpy(iv, nonce, NX_GCM4106_NONCE_LEN);