When inplace encryption is required then enforce it rather than doing a low-performan...
[cryptodev-linux.git] / tests / sha_speed.c
blobe1dc54ba5485d7e20043fe212eb9badabc40d3e0
1 /* sha_speed - simple SHA 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>
29 #include <crypto/cryptodev.h>
31 static double udifftimeval(struct timeval start, struct timeval end)
33 return (double)(end.tv_usec - start.tv_usec) +
34 (double)(end.tv_sec - start.tv_sec) * 1000 * 1000;
37 static int must_finish = 0;
39 static void alarm_handler(int signo)
41 must_finish = 1;
44 static char *units[] = { "", "Ki", "Mi", "Gi", "Ti", 0};
45 static char *si_units[] = { "", "K", "M", "G", "T", 0};
47 static void value2human(int si, double bytes, double time, double* data, double* speed,char* metric)
49 int unit = 0;
51 *data = bytes;
53 if (si) {
54 while (*data > 1000 && si_units[unit + 1]) {
55 *data /= 1000;
56 unit++;
58 *speed = *data / time;
59 sprintf(metric, "%sB", si_units[unit]);
60 } else {
61 while (*data > 1024 && units[unit + 1]) {
62 *data /= 1024;
63 unit++;
65 *speed = *data / time;
66 sprintf(metric, "%sB", units[unit]);
71 int hash_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
73 struct crypt_op cop;
74 char *buffer;
75 static int val = 23;
76 struct timeval start, end;
77 double total = 0;
78 double secs, ddata, dspeed;
79 char metric[16];
80 uint8_t mac[AALG_MAX_RESULT_LEN];
82 if (alignmask) {
83 if (posix_memalign((void **)&buffer, alignmask + 1, chunksize)) {
84 printf("posix_memalign() failed!\n");
85 return 1;
87 } else {
88 if (!(buffer = malloc(chunksize))) {
89 perror("malloc()");
90 return 1;
94 printf("\tEncrypting in chunks of %d bytes: ", chunksize);
95 fflush(stdout);
97 memset(buffer, val++, chunksize);
99 must_finish = 0;
100 alarm(5);
102 gettimeofday(&start, NULL);
103 do {
104 memset(&cop, 0, sizeof(cop));
105 cop.ses = sess->ses;
106 cop.len = chunksize;
107 cop.op = COP_ENCRYPT;
108 cop.src = (unsigned char *)buffer;
109 cop.mac = mac;
111 if (ioctl(fdc, CIOCCRYPT, &cop)) {
112 perror("ioctl(CIOCCRYPT)");
113 return 1;
115 total+=chunksize;
116 } while(must_finish==0);
117 gettimeofday(&end, NULL);
119 secs = udifftimeval(start, end)/ 1000000.0;
121 value2human(1, total, secs, &ddata, &dspeed, metric);
122 printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
123 printf ("%.2f %s/sec\n", dspeed, metric);
125 free(buffer);
126 return 0;
129 int main(void)
131 int fd, i, fdc = -1, alignmask = 0;
132 struct session_op sess;
133 char keybuf[32];
134 #ifdef CIOCGSESSINFO
135 struct session_info_op siop;
136 #endif
138 signal(SIGALRM, alarm_handler);
140 if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
141 perror("open()");
142 return 1;
144 if (ioctl(fd, CRIOGET, &fdc)) {
145 perror("ioctl(CRIOGET)");
146 return 1;
149 fprintf(stderr, "Testing SHA1 Hash: \n");
150 memset(&sess, 0, sizeof(sess));
151 sess.mac = CRYPTO_SHA1;
152 if (ioctl(fdc, CIOCGSESSION, &sess)) {
153 perror("ioctl(CIOCGSESSION)");
154 return 1;
156 #ifdef CIOCGSESSINFO
157 siop.ses = sess.ses;
158 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
159 perror("ioctl(CIOCGSESSINFO)");
160 return 1;
162 printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
163 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
164 alignmask = siop.alignmask;
165 #endif
167 for (i = 256; i <= (64 * 1024); i *= 4) {
168 if (hash_data(&sess, fdc, i, alignmask))
169 break;
172 fprintf(stderr, "\nTesting SHA256 Hash: \n");
173 memset(&sess, 0, sizeof(sess));
174 sess.mac = CRYPTO_SHA2_256;
175 if (ioctl(fdc, CIOCGSESSION, &sess)) {
176 perror("ioctl(CIOCGSESSION)");
177 return 1;
179 #ifdef CIOCGSESSINFO
180 siop.ses = sess.ses;
181 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
182 perror("ioctl(CIOCGSESSINFO)");
183 return 1;
185 printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
186 siop.hash_info.cra_name, siop.hash_info.cra_driver_name);
187 alignmask = siop.alignmask;
188 #endif
190 for (i = 256; i <= (64 * 1024); i *= 4) {
191 if (hash_data(&sess, fdc, i, alignmask))
192 break;
195 close(fdc);
196 close(fd);
197 return 0;