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
23 #include <sys/ioctl.h>
25 #include <sys/types.h>
29 #include <crypto/cryptodev.h>
31 static int si
= 1; /* SI by default */
33 static double udifftimeval(struct timeval start
, struct timeval end
)
35 return (double)(end
.tv_usec
- start
.tv_usec
) +
36 (double)(end
.tv_sec
- start
.tv_sec
) * 1000 * 1000;
39 static int must_finish
= 0;
41 static void alarm_handler(int signo
)
46 static char *units
[] = { "", "Ki", "Mi", "Gi", "Ti", 0};
47 static char *si_units
[] = { "", "K", "M", "G", "T", 0};
49 static void value2human(int si
, double bytes
, double time
, double* data
, double* speed
,char* metric
)
56 while (*data
> 1000 && si_units
[unit
+ 1]) {
60 *speed
= *data
/ time
;
61 sprintf(metric
, "%sB", si_units
[unit
]);
63 while (*data
> 1024 && units
[unit
+ 1]) {
67 *speed
= *data
/ time
;
68 sprintf(metric
, "%sB", units
[unit
]);
72 #define MAX(x,y) ((x)>(y)?(x):(y))
74 int encrypt_data(int algo
, void* keybuf
, int key_size
, int fdc
, int chunksize
)
79 struct timeval start
, end
;
81 double secs
, ddata
, dspeed
;
83 struct session_op sess
;
85 if (posix_memalign((void **)&buffer
, 16, chunksize
)) {
86 printf("posix_memalign() failed! (mask %x, size: %d)\n", 16, chunksize
);
92 printf("\tEncrypting in chunks of %d bytes: ", chunksize
);
95 memset(buffer
, val
++, chunksize
);
100 gettimeofday(&start
, NULL
);
102 memset(&sess
, 0, sizeof(sess
));
104 sess
.keylen
= key_size
;
106 if (ioctl(fdc
, CIOCGSESSION
, &sess
)) {
107 perror("ioctl(CIOCGSESSION)");
111 memset(&cop
, 0, sizeof(cop
));
114 cop
.iv
= (unsigned char *)iv
;
115 cop
.op
= COP_ENCRYPT
;
116 cop
.src
= (unsigned char *)buffer
;
119 if (ioctl(fdc
, CIOCCRYPT
, &cop
)) {
120 perror("ioctl(CIOCCRYPT)");
124 ioctl(fdc
, CIOCFSESSION
, &sess
.ses
);
127 } while(must_finish
==0);
128 gettimeofday(&end
, NULL
);
130 secs
= udifftimeval(start
, end
)/ 1000000.0;
132 value2human(si
, total
, secs
, &ddata
, &dspeed
, metric
);
133 printf ("done. %.2f %s in %.2f secs: ", ddata
, metric
, secs
);
134 printf ("%.2f %s/sec\n", dspeed
, metric
);
140 int main(int argc
, char** argv
)
145 signal(SIGALRM
, alarm_handler
);
148 if (strcmp(argv
[1], "--help") == 0 || strcmp(argv
[1], "-h") == 0) {
149 printf("Usage: speed [--kib]\n");
152 if (strcmp(argv
[1], "--kib") == 0) {
157 if ((fd
= open("/dev/crypto", O_RDWR
, 0)) < 0) {
161 if (ioctl(fd
, CRIOGET
, &fdc
)) {
162 perror("ioctl(CRIOGET)");
166 fprintf(stderr
, "Testing NULL cipher: \n");
168 for (i
= 512; i
<= (64 * 1024); i
*= 2) {
169 if (encrypt_data(CRYPTO_NULL
, keybuf
, 0, fdc
, i
))
173 fprintf(stderr
, "\nTesting AES-128-CBC cipher: \n");
174 memset(keybuf
, 0x42, 16);
176 for (i
= 512; i
<= (64 * 1024); i
*= 2) {
177 if (encrypt_data(CRYPTO_AES_CBC
, keybuf
, 16, fdc
, i
))