[CRYPTO] gcm: Fix ICV handling

The crypto_aead convention for ICVs is to include it directly in the
output.  If we decided to change this in future then we would make
the ICV (if the algorithm has an explicit one) available in the
request itself.

For now no algorithm needs this so this patch changes gcm to conform
to this convention.  It also adjusts the tcrypt aead tests to take
this into account.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index df93595..a6d4160 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -235,6 +235,7 @@
 	struct scatterlist asg[8];
 	const char *e;
 	struct tcrypt_result result;
+	unsigned int authsize;
 
 	if (enc == ENCRYPT)
 		e = "encryption";
@@ -265,6 +266,8 @@
 		return;
 	}
 
+	authsize = crypto_aead_authsize(tfm);
+
 	req = aead_request_alloc(tfm, GFP_KERNEL);
 	if (!req) {
 		printk(KERN_INFO "failed to allocate request for %s\n", algo);
@@ -296,7 +299,7 @@
 			}
 
 			sg_init_one(&sg[0], aead_tv[i].input,
-				    aead_tv[i].ilen);
+				    aead_tv[i].ilen + (enc ? authsize : 0));
 
 			sg_init_one(&asg[0], aead_tv[i].assoc,
 				    aead_tv[i].alen);
@@ -307,13 +310,9 @@
 
 			aead_request_set_assoc(req, asg, aead_tv[i].alen);
 
-			if (enc) {
-				ret = crypto_aead_encrypt(req);
-			} else {
-				memcpy(req->__ctx, aead_tv[i].tag,
-				       aead_tv[i].tlen);
-				ret = crypto_aead_decrypt(req);
-			}
+			ret = enc ?
+				crypto_aead_encrypt(req) :
+				crypto_aead_decrypt(req);
 
 			switch (ret) {
 			case 0:
@@ -335,16 +334,10 @@
 
 			q = kmap(sg_page(&sg[0])) + sg[0].offset;
 			hexdump(q, aead_tv[i].rlen);
-			printk(KERN_INFO "auth tag: ");
-			hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);
 
 			printk(KERN_INFO "enc/dec: %s\n",
 			       memcmp(q, aead_tv[i].result,
 				      aead_tv[i].rlen) ? "fail" : "pass");
-
-			printk(KERN_INFO "auth tag: %s\n",
-			       memcmp(req->__ctx, aead_tv[i].tag,
-				      aead_tv[i].tlen) ? "fail" : "pass");
 		}
 	}
 
@@ -381,6 +374,9 @@
 					   aead_tv[i].tap[k]);
 			}
 
+			if (enc)
+				sg[k - 1].length += authsize;
+
 			sg_init_table(asg, aead_tv[i].anp);
 			for (k = 0, temp = 0; k < aead_tv[i].anp; k++) {
 				memcpy(&axbuf[IDX[k]],
@@ -397,13 +393,9 @@
 
 			aead_request_set_assoc(req, asg, aead_tv[i].alen);
 
-			if (enc) {
-				ret = crypto_aead_encrypt(req);
-			} else {
-				memcpy(req->__ctx, aead_tv[i].tag,
-				       aead_tv[i].tlen);
-				ret = crypto_aead_decrypt(req);
-			}
+			ret = enc ?
+				crypto_aead_encrypt(req) :
+				crypto_aead_decrypt(req);
 
 			switch (ret) {
 			case 0:
@@ -429,17 +421,13 @@
 				hexdump(q, aead_tv[i].tap[k]);
 				printk(KERN_INFO "%s\n",
 				       memcmp(q, aead_tv[i].result + temp,
-					      aead_tv[i].tap[k]) ?
+					      aead_tv[i].tap[k] -
+					      (k < aead_tv[i].np - 1 || enc ?
+					       0 : authsize)) ?
 				       "fail" : "pass");
 
 				temp += aead_tv[i].tap[k];
 			}
-			printk(KERN_INFO "auth tag: ");
-			hexdump((unsigned char *)req->__ctx, aead_tv[i].tlen);
-
-			printk(KERN_INFO "auth tag: %s\n",
-			       memcmp(req->__ctx, aead_tv[i].tag,
-				      aead_tv[i].tlen) ? "fail" : "pass");
 		}
 	}