From 16654ddf064de5947b82e1b49b95f4697004d647 Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil.sutter@viprinet.com>
Date: Tue, 18 Jan 2011 18:33:31 +0100
Subject: [PATCH 130/291] cryptodev: examples:

- sha_speed does performance testing of SHA1 and SHA256
- hashcrypt_speed additionally encrypts with AES128 and AES256

Signed-off-by: Nikos Mavrogiannopoulos <nmav@gnutls.org>
---
 drivers/staging/crypto/cryptodev/.gitignore        |   2 +
 drivers/staging/crypto/cryptodev/examples/Makefile |   6 +-
 .../crypto/cryptodev/examples/hashcrypt_speed.c    | 201 +++++++++++++++++++++
 .../staging/crypto/cryptodev/examples/sha_speed.c  | 195 ++++++++++++++++++++
 4 files changed, 402 insertions(+), 2 deletions(-)
 create mode 100644 drivers/staging/crypto/cryptodev/examples/hashcrypt_speed.c
 create mode 100644 drivers/staging/crypto/cryptodev/examples/sha_speed.c

diff --git a/drivers/staging/crypto/cryptodev/.gitignore b/drivers/staging/crypto/cryptodev/.gitignore
index 893869ab1037..356d53acaaec 100644
--- a/drivers/staging/crypto/cryptodev/.gitignore
+++ b/drivers/staging/crypto/cryptodev/.gitignore
@@ -13,6 +13,8 @@ examples/async_speed
 examples/cipher
 examples/hmac
 examples/speed
+examples/sha_speed
+examples/hashcrypt_speed
 releases
 scripts
 version.h
diff --git a/drivers/staging/crypto/cryptodev/examples/Makefile b/drivers/staging/crypto/cryptodev/examples/Makefile
index ff88d54ae999..971d4369e7fb 100644
--- a/drivers/staging/crypto/cryptodev/examples/Makefile
+++ b/drivers/staging/crypto/cryptodev/examples/Makefile
@@ -1,12 +1,14 @@
 KERNEL_DIR ?= /lib/modules/$(shell uname -r)/build
 
-hostprogs := cipher hmac speed async_cipher async_hmac async_speed
+hostprogs := cipher hmac speed async_cipher async_hmac async_speed sha_speed hashcrypt_speed
 example-cipher-objs := cipher.o
 example-hmac-objs := hmac.o
 example-speed-objs := speed.c
+example-sha-speed-objs := sha_speed.c
 example-async-cipher-objs := async_cipher.o
 example-async-hmac-objs := async_hmac.o
 example-async-speed-objs := async_speed.o
+example-hashcrypt-speed-objs := hashcrypt_speed.c
 
 check: $(hostprogs)
 	./cipher
@@ -15,4 +17,4 @@ check: $(hostprogs)
 	./async_hmac
 
 clean:
-	rm -f *.o *~ hmac cipher speed async_hmac async_cipher async_speed
+	rm -f *.o *~ $(hostprogs)
diff --git a/drivers/staging/crypto/cryptodev/examples/hashcrypt_speed.c b/drivers/staging/crypto/cryptodev/examples/hashcrypt_speed.c
new file mode 100644
index 000000000000..203a8dd7db31
--- /dev/null
+++ b/drivers/staging/crypto/cryptodev/examples/hashcrypt_speed.c
@@ -0,0 +1,201 @@
+/*  hashcrypt_speed - simple SHA+AES benchmark tool for cryptodev
+ *
+ *    Copyright (C) 2011 by Phil Sutter <phil.sutter@viprinet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <signal.h>
+#include "../cryptodev.h"
+
+static double udifftimeval(struct timeval start, struct timeval end)
+{
+	return (double)(end.tv_usec - start.tv_usec) +
+	       (double)(end.tv_sec - start.tv_sec) * 1000 * 1000;
+}
+
+static int must_finish = 0;
+
+static void alarm_handler(int signo)
+{
+        must_finish = 1;
+}
+
+static char *units[] = { "", "Ki", "Mi", "Gi", "Ti", 0};
+static char *si_units[] = { "", "K", "M", "G", "T", 0};
+
+static void value2human(int si, double bytes, double time, double* data, double* speed,char* metric)
+{
+	int unit = 0;
+
+	*data = bytes;
+
+	if (si) {
+		while (*data > 1000 && si_units[unit + 1]) {
+			*data /= 1000;
+			unit++;
+		}
+		*speed = *data / time;
+		sprintf(metric, "%sB", si_units[unit]);
+	} else {
+		while (*data > 1024 && units[unit + 1]) {
+			*data /= 1024;
+			unit++;
+		}
+		*speed = *data / time;
+		sprintf(metric, "%sB", units[unit]);
+	}
+}
+
+
+int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
+{
+	struct crypt_op cop;
+	char *buffer;
+	static int val = 23;
+	struct timeval start, end;
+	double total = 0;
+	double secs, ddata, dspeed;
+	char metric[16];
+	uint8_t mac[AALG_MAX_RESULT_LEN];
+
+	if (alignmask) {
+		if (posix_memalign((void **)&buffer, alignmask, chunksize)) {
+			printf("posix_memalign() failed!\n");
+			return 1;
+		}
+	} else {
+		if (!(buffer = malloc(chunksize))) {
+			perror("malloc()");
+			return 1;
+		}
+	}
+
+	printf("\tEncrypting in chunks of %d bytes: ", chunksize);
+	fflush(stdout);
+
+	memset(buffer, val++, chunksize);
+
+	must_finish = 0;
+	alarm(5);
+
+	gettimeofday(&start, NULL);
+	do {
+		memset(&cop, 0, sizeof(cop));
+		cop.ses = sess->ses;
+		cop.len = chunksize;
+		cop.op = COP_ENCRYPT;
+		cop.src = cop.dst = (unsigned char *)buffer;
+		cop.mac = mac;
+
+		if (ioctl(fdc, CIOCCRYPT, &cop)) {
+			perror("ioctl(CIOCCRYPT)");
+			return 1;
+		}
+		total+=chunksize;
+	} while(must_finish==0);
+	gettimeofday(&end, NULL);
+
+	secs = udifftimeval(start, end)/ 1000000.0;
+
+	value2human(1, total, secs, &ddata, &dspeed, metric);
+	printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
+	printf ("%.2f %s/sec\n", dspeed, metric);
+
+	free(buffer);
+	return 0;
+}
+
+int main(void)
+{
+	int fd, i, fdc = -1;
+	struct session_op sess;
+	char keybuf[32];
+#ifdef CIOCGSESSINFO
+	struct session_info_op siop;
+#endif
+
+	signal(SIGALRM, alarm_handler);
+
+	if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
+		perror("open()");
+		return 1;
+	}
+	if (ioctl(fd, CRIOGET, &fdc)) {
+		perror("ioctl(CRIOGET)");
+		return 1;
+	}
+
+	fprintf(stderr, "Testing AES128 with SHA1 Hash: \n");
+	memset(&sess, 0, sizeof(sess));
+	sess.cipher = CRYPTO_AES_CBC;
+	sess.keylen = 16;
+	memset(keybuf, 0x42, 32);
+	sess.key = (unsigned char *)keybuf;
+	sess.mac = CRYPTO_SHA1;
+	if (ioctl(fdc, CIOCGSESSION, &sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return 1;
+	}
+#ifdef CIOCGSESSINFO
+	siop.ses = sess.ses;
+	if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+		perror("ioctl(CIOCGSESSINFO)");
+		return 1;
+	}
+	printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
+			siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+#endif
+
+	for (i = 256; i <= (64 * 4096); i *= 2) {
+		if (hash_data(&sess, fdc, i, sess.alignmask))
+			break;
+	}
+
+	fprintf(stderr, "\nTesting AES256 with SHA256 Hash: \n");
+	memset(&sess, 0, sizeof(sess));
+	sess.cipher = CRYPTO_AES_CBC;
+	sess.keylen = 32;
+	sess.mac = CRYPTO_SHA2_256;
+	if (ioctl(fdc, CIOCGSESSION, &sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return 1;
+	}
+#ifdef CIOCGSESSINFO
+	siop.ses = sess.ses;
+	if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+		perror("ioctl(CIOCGSESSINFO)");
+		return 1;
+	}
+	printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
+			siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+#endif
+
+	for (i = 256; i <= (64 * 1024); i *= 2) {
+		if (hash_data(&sess, fdc, i, 0))
+			break;
+	}
+
+	close(fdc);
+	close(fd);
+	return 0;
+}
diff --git a/drivers/staging/crypto/cryptodev/examples/sha_speed.c b/drivers/staging/crypto/cryptodev/examples/sha_speed.c
new file mode 100644
index 000000000000..278509a29bbb
--- /dev/null
+++ b/drivers/staging/crypto/cryptodev/examples/sha_speed.c
@@ -0,0 +1,195 @@
+/*  sha_speed - simple SHA benchmark tool for cryptodev
+ *
+ *    Copyright (C) 2011 by Phil Sutter <phil.sutter@viprinet.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <signal.h>
+#include "../cryptodev.h"
+
+static double udifftimeval(struct timeval start, struct timeval end)
+{
+	return (double)(end.tv_usec - start.tv_usec) +
+	       (double)(end.tv_sec - start.tv_sec) * 1000 * 1000;
+}
+
+static int must_finish = 0;
+
+static void alarm_handler(int signo)
+{
+        must_finish = 1;
+}
+
+static char *units[] = { "", "Ki", "Mi", "Gi", "Ti", 0};
+static char *si_units[] = { "", "K", "M", "G", "T", 0};
+
+static void value2human(int si, double bytes, double time, double* data, double* speed,char* metric)
+{
+	int unit = 0;
+
+	*data = bytes;
+
+	if (si) {
+		while (*data > 1000 && si_units[unit + 1]) {
+			*data /= 1000;
+			unit++;
+		}
+		*speed = *data / time;
+		sprintf(metric, "%sB", si_units[unit]);
+	} else {
+		while (*data > 1024 && units[unit + 1]) {
+			*data /= 1024;
+			unit++;
+		}
+		*speed = *data / time;
+		sprintf(metric, "%sB", units[unit]);
+	}
+}
+
+
+int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
+{
+	struct crypt_op cop;
+	char *buffer;
+	static int val = 23;
+	struct timeval start, end;
+	double total = 0;
+	double secs, ddata, dspeed;
+	char metric[16];
+	uint8_t mac[AALG_MAX_RESULT_LEN];
+
+	if (alignmask) {
+		if (posix_memalign((void **)&buffer, alignmask, chunksize)) {
+			printf("posix_memalign() failed!\n");
+			return 1;
+		}
+	} else {
+		if (!(buffer = malloc(chunksize))) {
+			perror("malloc()");
+			return 1;
+		}
+	}
+
+	printf("\tEncrypting in chunks of %d bytes: ", chunksize);
+	fflush(stdout);
+
+	memset(buffer, val++, chunksize);
+
+	must_finish = 0;
+	alarm(5);
+
+	gettimeofday(&start, NULL);
+	do {
+		memset(&cop, 0, sizeof(cop));
+		cop.ses = sess->ses;
+		cop.len = chunksize;
+		cop.op = COP_ENCRYPT;
+		cop.src = (unsigned char *)buffer;
+		cop.mac = mac;
+
+		if (ioctl(fdc, CIOCCRYPT, &cop)) {
+			perror("ioctl(CIOCCRYPT)");
+			return 1;
+		}
+		total+=chunksize;
+	} while(must_finish==0);
+	gettimeofday(&end, NULL);
+
+	secs = udifftimeval(start, end)/ 1000000.0;
+
+	value2human(1, total, secs, &ddata, &dspeed, metric);
+	printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
+	printf ("%.2f %s/sec\n", dspeed, metric);
+
+	free(buffer);
+	return 0;
+}
+
+int main(void)
+{
+	int fd, i, fdc = -1;
+	struct session_op sess;
+	char keybuf[32];
+#ifdef CIOCGSESSINFO
+	struct session_info_op siop;
+#endif
+
+	signal(SIGALRM, alarm_handler);
+
+	if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
+		perror("open()");
+		return 1;
+	}
+	if (ioctl(fd, CRIOGET, &fdc)) {
+		perror("ioctl(CRIOGET)");
+		return 1;
+	}
+
+	fprintf(stderr, "Testing SHA1 Hash: \n");
+	memset(&sess, 0, sizeof(sess));
+	sess.mac = CRYPTO_SHA1;
+	if (ioctl(fdc, CIOCGSESSION, &sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return 1;
+	}
+#ifdef CIOCGSESSINFO
+	siop.ses = sess.ses;
+	if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+		perror("ioctl(CIOCGSESSINFO)");
+		return 1;
+	}
+	printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
+			siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+#endif
+
+	for (i = 256; i <= (64 * 4096); i *= 2) {
+		if (hash_data(&sess, fdc, i, sess.alignmask))
+			break;
+	}
+
+	fprintf(stderr, "\nTesting SHA256 Hash: \n");
+	memset(&sess, 0, sizeof(sess));
+	sess.mac = CRYPTO_SHA2_256;
+	if (ioctl(fdc, CIOCGSESSION, &sess)) {
+		perror("ioctl(CIOCGSESSION)");
+		return 1;
+	}
+#ifdef CIOCGSESSINFO
+	siop.ses = sess.ses;
+	if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
+		perror("ioctl(CIOCGSESSINFO)");
+		return 1;
+	}
+	printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
+			siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
+#endif
+
+	for (i = 256; i <= (64 * 1024); i *= 2) {
+		if (hash_data(&sess, fdc, i, 0))
+			break;
+	}
+
+	close(fdc);
+	close(fd);
+	return 0;
+}
-- 
2.1.0

