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
25 #include <sys/ioctl.h>
27 #include <sys/types.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;
38 static struct pollfd pfd
;
40 static void alarm_handler(int signo
)
46 static void value2human(double bytes
, double time
, double* data
, double* speed
,char* metric
)
48 if (bytes
> 1000 && bytes
< 1000*1000) {
49 *data
= ((double)bytes
)/1000;
53 } else if (bytes
>= 1000*1000 && bytes
< 1000*1000*1000) {
54 *data
= ((double)bytes
)/(1000*1000);
58 } else if (bytes
>= 1000*1000*1000) {
59 *data
= ((double)bytes
)/(1000*1000*1000);
64 *data
= (double)bytes
;
66 strcpy(metric
, "bytes");
72 int encrypt_data(struct session_op
*sess
, int fdc
, int chunksize
, int flags
)
75 char *buffer
[64], iv
[32];
77 struct timeval start
, end
;
79 double secs
, ddata
, dspeed
;
81 int rc
, wqueue
= 0, bufidx
= 0;
85 printf("\tEncrypting in chunks of %d bytes: ", chunksize
);
88 for (rc
= 0; rc
< 64; rc
++) {
89 buffer
[rc
] = malloc(chunksize
);
90 memset(buffer
[rc
], val
++, chunksize
);
93 pfd
.events
= POLLOUT
| POLLIN
;
98 gettimeofday(&start
, NULL
);
100 if ((rc
= poll(&pfd
, 1, 100)) < 0) {
101 if (errno
& (ERESTART
| EINTR
))
103 fprintf(stderr
, "errno = %d ", errno
);
108 if (pfd
.revents
& POLLOUT
) {
109 memset(&cop
, 0, sizeof(cop
));
112 cop
.iv
= (unsigned char *)iv
;
113 cop
.op
= COP_ENCRYPT
;
115 cop
.src
= cop
.dst
= (unsigned char *)buffer
[bufidx
];
116 bufidx
= (bufidx
+ 1) % 64;
118 if (ioctl(fdc
, CIOCASYNCCRYPT
, &cop
)) {
119 perror("ioctl(CIOCASYNCCRYPT)");
124 if (pfd
.revents
& POLLIN
) {
125 if (ioctl(fdc
, CIOCASYNCFETCH
, &cop
)) {
126 perror("ioctl(CIOCASYNCFETCH)");
132 } while(!must_finish
|| wqueue
);
133 gettimeofday(&end
, NULL
);
135 secs
= udifftimeval(start
, end
)/ 1000000.0;
137 value2human(total
, secs
, &ddata
, &dspeed
, metric
);
138 printf ("done. %.2f %s in %.2f secs: ", ddata
, metric
, secs
);
139 printf ("%.2f %s/sec\n", dspeed
, metric
);
141 for (rc
= 0; rc
< 64; rc
++)
149 struct session_op sess
;
152 signal(SIGALRM
, alarm_handler
);
154 if ((fd
= open("/dev/crypto", O_RDWR
, 0)) < 0) {
158 if (ioctl(fd
, CRIOGET
, &fdc
)) {
159 perror("ioctl(CRIOGET)");
163 fprintf(stderr
, "Testing NULL cipher: \n");
164 memset(&sess
, 0, sizeof(sess
));
165 sess
.cipher
= CRYPTO_NULL
;
167 sess
.key
= (unsigned char *)keybuf
;
168 if (ioctl(fdc
, CIOCGSESSION
, &sess
)) {
169 perror("ioctl(CIOCGSESSION)");
173 for (i
= 256; i
<= (64 * 4096); i
*= 2) {
174 if (encrypt_data(&sess
, fdc
, i
, 0))
178 fprintf(stderr
, "\nTesting AES-128-CBC cipher: \n");
179 memset(&sess
, 0, sizeof(sess
));
180 sess
.cipher
= CRYPTO_AES_CBC
;
182 memset(keybuf
, 0x42, 16);
183 sess
.key
= (unsigned char *)keybuf
;
184 if (ioctl(fdc
, CIOCGSESSION
, &sess
)) {
185 perror("ioctl(CIOCGSESSION)");
189 for (i
= 256; i
<= (64 * 1024); i
*= 2) {
190 if (encrypt_data(&sess
, fdc
, i
, 0))