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