1 /* $NetBSD: test_bulk.c,v 1.3 2023/06/19 21:41:43 christos Exp $ */
2
3 /*
4 * Copyright (c) 2006 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <config.h>
37 #include <krb5/roken.h>
38 #include <assert.h>
39 #include <krb5/getarg.h>
40
41 #include <evp.h>
42 #include <evp-hcrypto.h>
43 #include <evp-cc.h>
44 #if defined(_WIN32)
45 #include <evp-w32.h>
46 #endif
47 #include <evp-pkcs11.h>
48 #include <krb5/hex.h>
49 #include <err.h>
50
51 #ifdef WIN32
52 #define STATS_START(M) \
53 LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds; \
54 LARGE_INTEGER Frequency; \
55 \
56 QueryPerformanceFrequency(&Frequency); \
57 QueryPerformanceCounter(&StartingTime);
58
59 #define STATS_END(M) \
60 QueryPerformanceCounter(&EndingTime); \
61 ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; \
62 ElapsedMicroseconds.QuadPart *= 1000000; \
63 ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; \
64 \
65 M += (ElapsedMicroseconds.QuadPart - M) / (i + 1);
66 #else
67 #define STATS_START(M) \
68 struct timeval StartingTime, EndingTime; \
69 \
70 gettimeofday(&StartingTime, NULL);
71
72 #define STATS_END(M) \
73 gettimeofday(&EndingTime, NULL); \
74 timevalsub(&EndingTime, &StartingTime); \
75 M += (EndingTime.tv_sec * 1000000 + EndingTime.tv_usec - M) / (i + 1);
76 #endif
77
78 static int version_flag;
79 static int help_flag;
80 static int len = 1;
81 static int loops = 20;
82 static char *provider = "hcrypto";
83 static unsigned char *d;
84
85 #ifdef __APPLE__
86 #define PROVIDER_USAGE "hcrypto|cc"
87 #elif defined(WIN32)
88 #define PROVIDER_USAGE "hcrypto|w32crypto"
89 #elif __sun || defined(PKCS11_MODULE_PATH)
90 #define PROVIDER_USAGE "hcrypto|pkcs11"
91 #else
92 #define PROVIDER_USAGE "hcrypto"
93 #endif
94
95 static struct getargs args[] = {
96 { "provider", 0, arg_string, &provider,
97 "crypto provider", PROVIDER_USAGE },
98 { "loops", 0, arg_integer, &loops,
99 "number of loops", "loops" },
100 { "size", 0, arg_integer, &len,
101 "size (KB)", NULL },
102 { "version", 0, arg_flag, &version_flag,
103 "print version", NULL },
104 { "help", 0, arg_flag, &help_flag,
105 NULL, NULL }
106 };
107
108 static void
usage(int ret)109 usage (int ret)
110 {
111 arg_printusage (args,
112 sizeof(args)/sizeof(*args),
113 NULL,
114 "");
115 exit (ret);
116 }
117
118 static int
test_bulk_cipher(const char * cname,const EVP_CIPHER * c)119 test_bulk_cipher(const char *cname, const EVP_CIPHER *c)
120 {
121 static unsigned char key[16];
122 static unsigned char iv[16];
123 int i;
124 int64_t M = 0;
125
126 if (c == NULL) {
127 printf("%s not supported\n", cname);
128 return 0;
129 }
130
131 for (i = 0; i < loops; i++) {
132 EVP_CIPHER_CTX ectx;
133 EVP_CIPHER_CTX dctx;
134
135 STATS_START(M)
136
137 EVP_CIPHER_CTX_init(&ectx);
138 EVP_CIPHER_CTX_init(&dctx);
139
140 if (EVP_CipherInit_ex(&ectx, c, NULL, NULL, NULL, 1) != 1)
141 errx(1, "can't init encrypt");
142 if (EVP_CipherInit_ex(&dctx, c, NULL, NULL, NULL, 0) != 1)
143 errx(1, "can't init decrypt");
144
145 EVP_CIPHER_CTX_set_key_length(&ectx, sizeof(key));
146 EVP_CIPHER_CTX_set_key_length(&dctx, sizeof(key));
147
148 if (EVP_CipherInit_ex(&ectx, NULL, NULL, key, iv, 1) != 1)
149 errx(1, "can't init encrypt");
150 if (EVP_CipherInit_ex(&dctx, NULL, NULL, key, iv, 0) != 1)
151 errx(1, "can't init decrypt");
152
153 if (!EVP_Cipher(&ectx, d, d, len))
154 errx(1, "can't encrypt");
155 if (!EVP_Cipher(&dctx, d, d, len))
156 errx(1, "can't decrypt");
157
158 EVP_CIPHER_CTX_cleanup(&ectx);
159 EVP_CIPHER_CTX_cleanup(&dctx);
160
161 STATS_END(M);
162
163 if (d[0] != 0x00 || d[len - 1] != ((len - 1) & 0xff))
164 errx(1, "encrypt/decrypt inconsistent");
165 }
166
167 printf("%s: mean time %llu usec%s\n", cname, (unsigned long long)M,
168 (M == 1) ? "" : "s");
169
170 return 0;
171 }
172
173 static int
test_bulk_digest(const char * cname,const EVP_MD * md)174 test_bulk_digest(const char *cname, const EVP_MD *md)
175 {
176 char digest[EVP_MAX_MD_SIZE];
177 int i;
178 unsigned int tmp = sizeof(digest);
179 int64_t M = 0;
180
181 if (md == NULL) {
182 printf("%s not supported\n", cname);
183 return 0;
184 }
185
186 for (i = 0; i < loops; i++) {
187 STATS_START(M);
188 EVP_Digest(d, len, digest, &tmp, md, NULL);
189 STATS_END(M);
190 }
191
192 printf("%s: mean time %llu usec%s\n", cname, (unsigned long long)M,
193 (M == 1) ? "" : "s");
194
195 return 0;
196 }
197
198 static void
test_bulk_provider_hcrypto(void)199 test_bulk_provider_hcrypto(void)
200 {
201 test_bulk_cipher("hcrypto_aes_256_cbc", EVP_hcrypto_aes_256_cbc());
202 #if 0
203 test_bulk_cipher("hcrypto_aes_256_cfb8", EVP_hcrypto_aes_256_cfb8());
204 #endif
205 test_bulk_cipher("hcrypto_rc4", EVP_hcrypto_rc4());
206 test_bulk_digest("hcrypto_md4", EVP_hcrypto_md4());
207 test_bulk_digest("hcrypto_md5", EVP_hcrypto_md5());
208 test_bulk_digest("hcrypto_sha1", EVP_hcrypto_sha1());
209 test_bulk_digest("hcrypto_sha256", EVP_hcrypto_sha256());
210 test_bulk_digest("hcrypto_sha384", EVP_hcrypto_sha384());
211 test_bulk_digest("hcrypto_sha512", EVP_hcrypto_sha512());
212 }
213
214 #ifdef __APPLE__
215 static void
test_bulk_provider_cc(void)216 test_bulk_provider_cc(void)
217 {
218 test_bulk_cipher("cc_aes_256_cbc", EVP_cc_aes_256_cbc());
219 #if 0
220 test_bulk_cipher("cc_aes_256_cfb8", EVP_cc_aes_256_cfb8());
221 #endif
222 test_bulk_cipher("cc_rc4", EVP_cc_rc4());
223 test_bulk_digest("cc_md4", EVP_cc_md4());
224 test_bulk_digest("cc_md5", EVP_cc_md5());
225 test_bulk_digest("cc_sha1", EVP_cc_sha1());
226 test_bulk_digest("cc_sha256", EVP_cc_sha256());
227 test_bulk_digest("cc_sha384", EVP_cc_sha384());
228 test_bulk_digest("cc_sha512", EVP_cc_sha512());
229 }
230 #endif /* __APPLE__ */
231
232 #ifdef WIN32
233 static void
test_bulk_provider_w32crypto(void)234 test_bulk_provider_w32crypto(void)
235 {
236 test_bulk_cipher("w32crypto_aes_256_cbc", EVP_w32crypto_aes_256_cbc());
237 #if 0
238 test_bulk_cipher("w32crypto_aes_256_cfb8", EVP_w32crypto_aes_256_cfb8());
239 #endif
240 test_bulk_cipher("w32crypto_rc4", EVP_w32crypto_rc4());
241 test_bulk_digest("w32crypto_md4", EVP_w32crypto_md4());
242 test_bulk_digest("w32crypto_md5", EVP_w32crypto_md5());
243 test_bulk_digest("w32crypto_sha1", EVP_w32crypto_sha1());
244 test_bulk_digest("w32crypto_sha256", EVP_w32crypto_sha256());
245 test_bulk_digest("w32crypto_sha384", EVP_w32crypto_sha384());
246 test_bulk_digest("w32crypto_sha512", EVP_w32crypto_sha512());
247 }
248 #endif /* WIN32 */
249
250 #if __sun || defined(PKCS11_MODULE_PATH)
251 static void
test_bulk_provider_pkcs11(void)252 test_bulk_provider_pkcs11(void)
253 {
254 test_bulk_cipher("pkcs11_aes_256_cbc", EVP_pkcs11_aes_256_cbc());
255 test_bulk_cipher("pkcs11_rc4", EVP_pkcs11_rc4());
256 test_bulk_digest("pkcs11_md5", EVP_pkcs11_md5());
257 test_bulk_digest("pkcs11_sha1", EVP_pkcs11_sha1());
258 test_bulk_digest("pkcs11_sha256", EVP_pkcs11_sha256());
259 test_bulk_digest("pkcs11_sha384", EVP_pkcs11_sha384());
260 test_bulk_digest("pkcs11_sha512", EVP_pkcs11_sha512());
261 }
262 #endif /* __sun || PKCS11_MODULE_PATH */
263
264 int
main(int argc,char ** argv)265 main(int argc, char **argv)
266 {
267 int ret = 0;
268 int idx = 0;
269 int i;
270
271 setprogname(argv[0]);
272
273 if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &idx))
274 usage(1);
275
276 if (help_flag)
277 usage(0);
278
279 if(version_flag) {
280 print_version(NULL);
281 exit(0);
282 }
283
284 argc -= idx;
285 argv += idx;
286
287 len *= 1024;
288
289 d = emalloc(len);
290 for (i = 0; i < len; i++)
291 d[i] = i & 0xff;
292
293 if (strcmp(provider, "hcrypto") == 0)
294 test_bulk_provider_hcrypto();
295 #ifdef __APPLE__
296 else if (strcmp(provider, "cc") == 0)
297 test_bulk_provider_cc();
298 #endif
299 #ifdef WIN32
300 else if (strcmp(provider, "w32crypto") == 0)
301 test_bulk_provider_w32crypto();
302 #endif
303 #if __sun || defined(PKCS11_MODULE_PATH)
304 else if (strcmp(provider, "pkcs11") == 0)
305 test_bulk_provider_pkcs11();
306 #endif
307 else
308 usage(1);
309
310 free(d);
311
312 return ret;
313 }
314