Made speed SI system configurable.
[cryptodev-linux.git] / examples / speed.c
blob38b3821681a5361e4ccf29c3fe08615a9b63fcbd
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>
27 #include "../cryptodev.h"
29 static int si = 1; /* SI by default */
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 encrypt_data(struct session_op *sess, int fdc, int chunksize, int alignmask)
73 struct crypt_op cop;
74 char *buffer, iv[32];
75 static int val = 23;
76 struct timeval start, end;
77 double total = 0;
78 double secs, ddata, dspeed;
79 char metric[16];
81 if (alignmask) {
82 if (posix_memalign((void **)&buffer, alignmask, chunksize)) {
83 printf("posix_memalign() failed!\n");
84 return 1;
86 } else {
87 if (!(buffer = malloc(chunksize))) {
88 perror("malloc()");
89 return 1;
93 memset(iv, 0x23, 32);
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.iv = (unsigned char *)iv;
109 cop.op = COP_ENCRYPT;
110 cop.src = cop.dst = (unsigned char *)buffer;
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(si, 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(int argc, char** argv)
132 int fd, i, fdc = -1;
133 struct session_op sess;
134 char keybuf[32];
136 signal(SIGALRM, alarm_handler);
138 if (argc > 1) {
139 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) {
140 printf("Usage: speed [--kib]\n");
141 exit(0);
143 if (strcmp(argv[1], "--kib") == 0) {
144 si = 0;
148 if ((fd = open("/dev/crypto", O_RDWR, 0)) < 0) {
149 perror("open()");
150 return 1;
152 if (ioctl(fd, CRIOGET, &fdc)) {
153 perror("ioctl(CRIOGET)");
154 return 1;
157 fprintf(stderr, "Testing NULL cipher: \n");
158 memset(&sess, 0, sizeof(sess));
159 sess.cipher = CRYPTO_NULL;
160 sess.keylen = 0;
161 sess.key = (unsigned char *)keybuf;
162 if (ioctl(fdc, CIOCGSESSION, &sess)) {
163 perror("ioctl(CIOCGSESSION)");
164 return 1;
167 for (i = 256; i <= (64 * 4096); i *= 2) {
168 if (encrypt_data(&sess, fdc, i, sess.alignmask))
169 break;
172 fprintf(stderr, "\nTesting AES-128-CBC cipher: \n");
173 memset(&sess, 0, sizeof(sess));
174 sess.cipher = CRYPTO_AES_CBC;
175 sess.keylen = 16;
176 memset(keybuf, 0x42, 16);
177 sess.key = (unsigned char *)keybuf;
178 if (ioctl(fdc, CIOCGSESSION, &sess)) {
179 perror("ioctl(CIOCGSESSION)");
180 return 1;
183 for (i = 256; i <= (64 * 1024); i *= 2) {
184 if (encrypt_data(&sess, fdc, i, 0))
185 break;
188 close(fdc);
189 close(fd);
190 return 0;