From 087e872199039a54abb93ccc1e600e7a5f954ccc Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos <nmav@gnutls.org>
Date: Sat, 2 Oct 2010 23:15:05 +0200
Subject: [PATCH 093/291] cryptodev: Added

---
 drivers/staging/crypto/cryptodev/cryptodev.h      |  1 +
 drivers/staging/crypto/cryptodev/cryptodev_main.c |  5 +-
 drivers/staging/crypto/cryptodev/examples/hmac.c  | 76 +++++++++++++++++++++++
 3 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/crypto/cryptodev/cryptodev.h b/drivers/staging/crypto/cryptodev/cryptodev.h
index 3620325f45cd..8cee01bc79d4 100644
--- a/drivers/staging/crypto/cryptodev/cryptodev.h
+++ b/drivers/staging/crypto/cryptodev/cryptodev.h
@@ -103,6 +103,7 @@ struct session_op {
 
 #define COP_FLAG_NONE		(0 << 0) /* totally no flag */
 #define COP_FLAG_UPDATE		(1 << 0) /* multi-update hash mode */
+#define COP_FLAG_FINAL		(1 << 1) /* multi-update final hash mode */
 
 /* Stuff for bignum arithmetic and public key
  * cryptography - not supported yet by linux
diff --git a/drivers/staging/crypto/cryptodev/cryptodev_main.c b/drivers/staging/crypto/cryptodev/cryptodev_main.c
index a912cbc63a74..5347a4dc5b9a 100644
--- a/drivers/staging/crypto/cryptodev/cryptodev_main.c
+++ b/drivers/staging/crypto/cryptodev/cryptodev_main.c
@@ -654,7 +654,8 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
 		return -EINVAL;
 	}
 
-	if (ses_ptr->hdata.init != 0 && !(cop->flags & COP_FLAG_UPDATE)) {
+	if (ses_ptr->hdata.init != 0 && !(cop->flags & COP_FLAG_UPDATE) &&
+		!(cop->flags & COP_FLAG_FINAL)) {
 		ret = cryptodev_hash_reset(&ses_ptr->hdata);
 		if (unlikely(ret)) {
 			dprintk(1, KERN_ERR,
@@ -694,7 +695,7 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
 		}
 	}
 
-	if (!(cop->flags & COP_FLAG_UPDATE) || cop->len != 0) {
+	if (cop->len != 0) {
 		ret = __crypto_run_zc(ses_ptr, cop);
 		if (unlikely(ret))
 			goto out_unlock;
diff --git a/drivers/staging/crypto/cryptodev/examples/hmac.c b/drivers/staging/crypto/cryptodev/examples/hmac.c
index 9975792c3341..166b5ddb0665 100644
--- a/drivers/staging/crypto/cryptodev/examples/hmac.c
+++ b/drivers/staging/crypto/cryptodev/examples/hmac.c
@@ -8,6 +8,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <stdint.h>
 
 #include <sys/ioctl.h>
 #include <crypto/cryptodev.h>
@@ -165,6 +166,78 @@ test_crypto(int cfd)
 	return 0;
 }
 
+static int
+test_extras(int cfd)
+{
+	struct session_op sess;
+	struct crypt_op cryp;
+	uint8_t mac[AALG_MAX_RESULT_LEN];
+	uint8_t oldmac[AALG_MAX_RESULT_LEN];
+	uint8_t md5_hmac_out[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
+	uint8_t sha1_out[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
+	int i;
+
+	memset(&sess, 0, sizeof(sess));
+	memset(&cryp, 0, sizeof(cryp));
+
+	/* Use the garbage that is on the stack :-) */
+	/* memset(&data, 0, sizeof(data)); */
+
+	/* SHA1 plain test */
+	memset(mac, 0, sizeof(mac));
+
+	sess.cipher = 0;
+	sess.mac = CRYPTO_SHA1;
+	if (ioctl(cfd, CIOCGSESSION, &sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return 1;
+	}
+
+	cryp.ses = sess.ses;
+	cryp.len = sizeof("what do")-1;
+	cryp.src = "what do";
+	cryp.mac = mac;
+	cryp.op = COP_ENCRYPT;
+	cryp.flags = COP_FLAG_UPDATE;
+	if (ioctl(cfd, CIOCCRYPT, &cryp)) {
+		perror("ioctl(CIOCCRYPT)");
+		return 1;
+	}
+
+	cryp.ses = sess.ses;
+	cryp.len = sizeof(" ya want for nothing?")-1;
+	cryp.src = " ya want for nothing?";
+	cryp.mac = mac;
+	cryp.op = COP_ENCRYPT;
+	cryp.flags = COP_FLAG_FINAL;
+	if (ioctl(cfd, CIOCCRYPT, &cryp)) {
+		perror("ioctl(CIOCCRYPT)");
+		return 1;
+	}
+
+	if (memcmp(mac, sha1_out, 20)!=0) {
+		printf("mac: ");
+		for (i=0;i<SHA1_HASH_LEN;i++) {
+			printf("%.2x", (uint8_t)mac[i]);
+		}
+		puts("\n");
+		fprintf(stderr, "HASH test [update]: failed\n");
+	} else {
+		fprintf(stderr, "HASH test [update]: passed\n");
+	}
+
+	memset(mac, 0, sizeof(mac));
+
+	/* Finish crypto session */
+	if (ioctl(cfd, CIOCFSESSION, &sess.ses)) {
+		perror("ioctl(CIOCFSESSION)");
+		return 1;
+	}
+
+	return 0;
+}
+
+
 int
 main()
 {
@@ -193,6 +266,9 @@ main()
 	if (test_crypto(cfd))
 		return 1;
 
+	if (test_extras(cfd))
+		return 1;
+
 	/* Close cloned descriptor */
 	if (close(cfd)) {
 		perror("close(cfd)");
-- 
2.1.0

