1 /* hashcrypt_speed - simple SHA+AES 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
24 #include <sys/ioctl.h>
26 #include <sys/types.h>
28 #include <crypto/cryptodev.h>
30 #define MAX(x,y) ((x)>(y)?(x):(y))
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
)
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
)
55 while (*data
> 1000 && si_units
[unit
+ 1]) {
59 *speed
= *data
/ time
;
60 sprintf(metric
, "%sB", si_units
[unit
]);
62 while (*data
> 1024 && units
[unit
+ 1]) {
66 *speed
= *data
/ time
;
67 sprintf(metric
, "%sB", units
[unit
]);
72 int hash_data(struct session_op
*sess
, int fdc
, int chunksize
, int align
)
77 struct timeval start
, end
;
79 double secs
, ddata
, dspeed
;
81 uint8_t mac
[AALG_MAX_RESULT_LEN
];
84 if (posix_memalign((void **)&buffer
, align
, chunksize
)) {
85 printf("posix_memalign() failed, align: %d, size: %d!\n", align
, chunksize
);
89 if (!(buffer
= malloc(chunksize
))) {
95 printf("\tEncrypting in chunks of %d bytes: ", chunksize
);
98 memset(buffer
, val
++, chunksize
);
103 gettimeofday(&start
, NULL
);
105 memset(&cop
, 0, sizeof(cop
));
108 cop
.op
= COP_ENCRYPT
;
109 cop
.src
= cop
.dst
= (unsigned char *)buffer
;
112 if (ioctl(fdc
, CIOCCRYPT
, &cop
)) {
113 perror("ioctl(CIOCCRYPT)");
117 } while(must_finish
==0);
118 gettimeofday(&end
, NULL
);
120 secs
= udifftimeval(start
, end
)/ 1000000.0;
122 value2human(1, total
, secs
, &ddata
, &dspeed
, metric
);
123 printf ("done. %.2f %s in %.2f secs: ", ddata
, metric
, secs
);
124 printf ("%.2f %s/sec\n", dspeed
, metric
);
132 int fd
, i
, fdc
= -1, align
= 0;
133 struct session_op sess
;
136 struct session_info_op siop
;
139 signal(SIGALRM
, alarm_handler
);
141 if ((fd
= open("/dev/crypto", O_RDWR
, 0)) < 0) {
145 if (ioctl(fd
, CRIOGET
, &fdc
)) {
146 perror("ioctl(CRIOGET)");
150 fprintf(stderr
, "Testing AES128 with SHA1 Hash: \n");
151 memset(&sess
, 0, sizeof(sess
));
152 sess
.cipher
= CRYPTO_AES_CBC
;
154 memset(keybuf
, 0x42, 32);
155 sess
.key
= (unsigned char *)keybuf
;
156 sess
.mac
= CRYPTO_SHA1
;
157 if (ioctl(fdc
, CIOCGSESSION
, &sess
)) {
158 perror("ioctl(CIOCGSESSION)");
163 if (ioctl(fdc
, CIOCGSESSINFO
, &siop
)) {
164 perror("ioctl(CIOCGSESSINFO)");
167 printf("requested hash CRYPTO_SHA1, got %s with driver %s\n",
168 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
169 align
= MAX(sizeof(void*), siop
.alignmask
+1);
172 for (i
= 256; i
<= (64 * 1024); i
*= 4) {
173 if (hash_data(&sess
, fdc
, i
, align
))
177 fprintf(stderr
, "\nTesting AES256 with SHA256 Hash: \n");
178 memset(&sess
, 0, sizeof(sess
));
179 sess
.cipher
= CRYPTO_AES_CBC
;
181 sess
.key
= (unsigned char *)keybuf
;
182 sess
.mac
= CRYPTO_SHA2_256
;
183 if (ioctl(fdc
, CIOCGSESSION
, &sess
)) {
184 perror("ioctl(CIOCGSESSION)");
189 if (ioctl(fdc
, CIOCGSESSINFO
, &siop
)) {
190 perror("ioctl(CIOCGSESSINFO)");
193 printf("requested hash CRYPTO_SHA2_256, got %s with driver %s\n",
194 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
195 align
= MAX(sizeof(void*), siop
.alignmask
+1);
198 for (i
= 256; i
<= (64 * 1024); i
*= 4) {
199 if (hash_data(&sess
, fdc
, i
, align
))