When inplace encryption is required then enforce it rather than doing a low-performan...
[cryptodev-linux.git] / tests / hashcrypt_speed.c
blobe60b73d8b27448683dc8661bfb8a5cda6e543a95
1 /* hashcrypt_speed - simple SHA+AES benchmark tool for cryptodev
3 * Copyright (C) 2011 by Phil Sutter <phil.sutter@viprinet.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <fcntl.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/ioctl.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <signal.h>
28 #include <crypto/cryptodev.h>
30 #define MAX(x,y) ((x)>(y)?(x):(y))
32 static double udifftimeval(struct timeval start, struct timeval end)
34 return (double)(end.tv_usec - start.tv_usec) +
35 (double)(end.tv_sec - start.tv_sec) * 1000 * 1000;
38 static int must_finish = 0;
40 static void alarm_handler(int signo)
42 must_finish = 1;
45 static char *units[] = { "", "Ki", "Mi", "Gi", "Ti", 0};
46 static char *si_units[] = { "", "K", "M", "G", "T", 0};
48 static void value2human(int si, double bytes, double time, double* data, double* speed,char* metric)
50 int unit = 0;
52 *data = bytes;
54 if (si) {
55 while (*data > 1000 && si_units[unit + 1]) {
56 *data /= 1000;
57 unit++;
59 *speed = *data / time;
60 sprintf(metric, "%sB", si_units[unit]);
61 } else {
62 while (*data > 1024 && units[unit + 1]) {
63 *data /= 1024;
64 unit++;
66 *speed = *data / time;
67 sprintf(metric, "%sB", units[unit]);
72 int hash_data(struct session_op *sess, int fdc, int chunksize, int align)
74 struct crypt_op cop;
75 char *buffer;
76 static int val = 23;
77 struct timeval start, end;
78 double total = 0;
79 double secs, ddata, dspeed;
80 char metric[16];
81 uint8_t mac[AALG_MAX_RESULT_LEN];
83 if (align) {
84 if (posix_memalign((void **)&buffer, align, chunksize)) {
85 printf("posix_memalign() failed, align: %d, size: %d!\n", align, chunksize);
86 return 1;
88 } else {
89 if (!(buffer = malloc(chunksize))) {
90 perror("malloc()");
91 return 1;
95 printf("\tEncrypting in chunks of %d bytes: ", chunksize);
96 fflush(stdout);
98 memset(buffer, val++, chunksize);
100 must_finish = 0;
101 alarm(5);
103 gettimeofday(&start, NULL);
104 do {
105 memset(&cop, 0, sizeof(cop));
106 cop.ses = sess->ses;
107 cop.len = chunksize;
108 cop.op = COP_ENCRYPT;
109 cop.src = cop.dst = (unsigned char *)buffer;
110 cop.mac = mac;
112 if (ioctl(fdc, CIOCCRYPT, &cop)) {
113 perror("ioctl(CIOCCRYPT)");
114 return 1;
116 total+=chunksize;
117 } while(must_finish==0);
118 gettimeofday(&end, NULL);
120 secs = udifftimeval(start, end)/ 1000000.0;
122 value2human(1, total, secs, &ddata, &dspeed, metric);
123 printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
124 printf ("%.2f %s/sec\n", dspeed, metric);
126 free(buffer);
127 return 0;
130 int main(void)
132 int fd, i, fdc = -1, align = 0;
133 struct session_op sess;
134 char keybuf[32];
135 #ifdef CIOCGSESSINFO
136 struct session_info_op siop;
137 #endif
139 signal(SIGALRM, alarm_handler);
141 if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
142 perror("open()");
143 return 1;
145 if (ioctl(fd, CRIOGET, &fdc)) {
146 perror("ioctl(CRIOGET)");
147 return 1;
150 fprintf(stderr, "Testing AES128 with SHA1 Hash: \n");
151 memset(&sess, 0, sizeof(sess));
152 sess.cipher = CRYPTO_AES_CBC;
153 sess.keylen = 16;
154 memset(keybuf, 0x42, 32);
155 sess.key = (unsigned char *)keybuf;
156 sess.mac = CRYPTO_SHA1;
157 if (ioctl(fdc, CIOCGSESSION, &sess)) {
158 perror("ioctl(CIOCGSESSION)");
159 return 1;
161 #ifdef CIOCGSESSINFO
162 siop.ses = sess.ses;
163 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
164 perror("ioctl(CIOCGSESSINFO)");
165 return 1;
167 printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
168 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
169 align = MAX(sizeof(void*), siop.alignmask+1);
170 #endif
172 for (i = 256; i <= (64 * 1024); i *= 4) {
173 if (hash_data(&sess, fdc, i, align))
174 break;
177 fprintf(stderr, "\nTesting AES256 with SHA256 Hash: \n");
178 memset(&sess, 0, sizeof(sess));
179 sess.cipher = CRYPTO_AES_CBC;
180 sess.keylen = 32;
181 sess.key = (unsigned char *)keybuf;
182 sess.mac = CRYPTO_SHA2_256;
183 if (ioctl(fdc, CIOCGSESSION, &sess)) {
184 perror("ioctl(CIOCGSESSION)");
185 return 1;
187 #ifdef CIOCGSESSINFO
188 siop.ses = sess.ses;
189 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
190 perror("ioctl(CIOCGSESSINFO)");
191 return 1;
193 printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
194 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
195 align = MAX(sizeof(void*), siop.alignmask+1);
196 #endif
198 for (i = 256; i <= (64 * 1024); i *= 4) {
199 if (hash_data(&sess, fdc, i, align))
200 break;
203 close(fdc);
204 close(fd);
205 return 0;