Added support SHA224
[cryptodev-linux.git] / tests / speed.c
blob81c5a652b90784af0e8e223de54023749eaf40f7
1 /* cryptodev_test - simple benchmark tool for cryptodev
3 * Copyright (C) 2010 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 <stdlib.h>
22 #include <string.h>
23 #include <sys/ioctl.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <signal.h>
28 #include <crypto/cryptodev.h>
30 static int si = 1; /* SI by default */
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]);
71 #define MAX(x,y) ((x)>(y)?(x):(y))
73 int encrypt_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
75 struct crypt_op cop;
76 char *buffer, iv[32];
77 static int val = 23;
78 struct timeval start, end;
79 double total = 0;
80 double secs, ddata, dspeed;
81 char metric[16];
83 if (alignmask) {
84 if (posix_memalign((void **)&buffer, MAX(alignmask + 1, sizeof(void*)), chunksize)) {
85 printf("posix_memalign() failed! (mask %x, size: %d)\n", alignmask+1, chunksize);
86 return 1;
88 } else {
89 if (!(buffer = malloc(chunksize))) {
90 perror("malloc()");
91 return 1;
95 memset(iv, 0x23, 32);
97 printf("\tEncrypting in chunks of %d bytes: ", chunksize);
98 fflush(stdout);
100 memset(buffer, val++, chunksize);
102 must_finish = 0;
103 alarm(5);
105 gettimeofday(&start, NULL);
106 do {
107 memset(&cop, 0, sizeof(cop));
108 cop.ses = sess->ses;
109 cop.len = chunksize;
110 cop.iv = (unsigned char *)iv;
111 cop.op = COP_ENCRYPT;
112 cop.src = cop.dst = (unsigned char *)buffer;
114 if (ioctl(fdc, CIOCCRYPT, &cop)) {
115 perror("ioctl(CIOCCRYPT)");
116 return 1;
118 total+=chunksize;
119 } while(must_finish==0);
120 gettimeofday(&end, NULL);
122 secs = udifftimeval(start, end)/ 1000000.0;
124 value2human(si, total, secs, &ddata, &dspeed, metric);
125 printf ("done. %.2f %s in %.2f secs: ", ddata, metric, secs);
126 printf ("%.2f %s/sec\n", dspeed, metric);
128 free(buffer);
129 return 0;
132 int main(int argc, char** argv)
134 int fd, i, fdc = -1, alignmask = 0;
135 struct session_op sess;
136 #ifdef CIOCGSESSINFO
137 struct session_info_op siop;
138 #endif
139 char keybuf[32];
141 signal(SIGALRM, alarm_handler);
143 if (argc > 1) {
144 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
145 printf("Usage: speed [--kib]\n");
146 exit(0);
148 if (strcmp(argv[1], "--kib") == 0) {
149 si = 0;
153 if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
154 perror("open()");
155 return 1;
157 if (ioctl(fd, CRIOGET, &fdc)) {
158 perror("ioctl(CRIOGET)");
159 return 1;
162 fprintf(stderr, "Testing NULL cipher: \n");
163 memset(&sess, 0, sizeof(sess));
164 sess.cipher = CRYPTO_NULL;
165 sess.keylen = 0;
166 sess.key = (unsigned char *)keybuf;
167 if (ioctl(fdc, CIOCGSESSION, &sess)) {
168 perror("ioctl(CIOCGSESSION)");
169 return 1;
171 #ifdef CIOCGSESSINFO
172 siop.ses = sess.ses;
173 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
174 perror("ioctl(CIOCGSESSINFO)");
175 return 1;
177 alignmask = siop.alignmask;
178 #endif
180 for (i = 512; i <= (64 * 1024); i *= 2) {
181 if (encrypt_data(&sess, fdc, i, alignmask))
182 break;
185 fprintf(stderr, "\nTesting AES-128-CBC cipher: \n");
186 memset(&sess, 0, sizeof(sess));
187 sess.cipher = CRYPTO_AES_CBC;
188 sess.keylen = 16;
189 memset(keybuf, 0x42, 16);
190 sess.key = (unsigned char *)keybuf;
191 if (ioctl(fdc, CIOCGSESSION, &sess)) {
192 perror("ioctl(CIOCGSESSION)");
193 return 1;
195 #ifdef CIOCGSESSINFO
196 siop.ses = sess.ses;
197 if (ioctl(fdc, CIOCGSESSINFO, &siop)) {
198 perror("ioctl(CIOCGSESSINFO)");
199 return 1;
201 alignmask = siop.alignmask;
202 #endif
204 for (i = 512; i <= (64 * 1024); i *= 2) {
205 if (encrypt_data(&sess, fdc, i, alignmask))
206 break;
209 close(fdc);
210 close(fd);
211 return 0;