From 33c65bdb2ce388e58d77890056019907a5253aba Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Tue, 18 Jan 2011 18:33:31 +0100 Subject: [PATCH] examples: add some additional speed testing tools - sha_speed does performance testing of SHA1 and SHA256 - hashcrypt_speed additionally encrypts with AES128 and AES256 Signed-off-by: Nikos Mavrogiannopoulos --- .gitignore | 2 + examples/Makefile | 6 +- examples/hashcrypt_speed.c | 201 +++++++++++++++++++++++++++++++++++++++++++++ examples/sha_speed.c | 195 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 examples/hashcrypt_speed.c create mode 100644 examples/sha_speed.c diff --git a/.gitignore b/.gitignore index 893869a..356d53a 100644 --- a/.gitignore +++ b/.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/examples/Makefile b/examples/Makefile index ff88d54..971d436 100644 --- a/examples/Makefile +++ b/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/examples/hashcrypt_speed.c b/examples/hashcrypt_speed.c new file mode 100644 index 0000000..203a8dd --- /dev/null +++ b/examples/hashcrypt_speed.c @@ -0,0 +1,201 @@ +/* hashcrypt_speed - simple SHA+AES benchmark tool for cryptodev + * + * Copyright (C) 2011 by Phil Sutter + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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/examples/sha_speed.c b/examples/sha_speed.c new file mode 100644 index 0000000..278509a --- /dev/null +++ b/examples/sha_speed.c @@ -0,0 +1,195 @@ +/* sha_speed - simple SHA benchmark tool for cryptodev + * + * Copyright (C) 2011 by Phil Sutter + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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.11.4.GIT