1 /**********************************************************************
2 * Simple benchmarking for gost-engine *
4 * Copyright (c) 2018 Cryptocom LTD *
5 * Copyright (c) 2018 <vt@altlinux.org>. *
6 * This file is distributed under the same license as OpenSSL *
7 **********************************************************************/
15 #include <openssl/rand.h>
16 #include <openssl/conf.h>
17 #include <openssl/err.h>
18 #include <openssl/evp.h>
19 #include <openssl/pem.h>
20 #include <openssl/engine.h>
22 const char *tests[] = {
23 "md_gost12_256", "gost2012_256", "A",
24 "md_gost12_256", "gost2012_256", "B",
25 "md_gost12_256", "gost2012_256", "C",
26 "md_gost12_256", "gost2012_256", "TCA",
27 "md_gost12_256", "gost2012_256", "TCB",
28 "md_gost12_256", "gost2012_256", "TCC",
29 "md_gost12_256", "gost2012_256", "TCD",
31 "md_gost12_512", "gost2012_512", "A",
32 "md_gost12_512", "gost2012_512", "B",
33 "md_gost12_512", "gost2012_512", "C",
38 static EVP_PKEY *create_key(const char *algname, const char *param)
40 EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
41 EVP_PKEY_CTX *ctx = NULL;
43 if(EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
47 if(!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
51 EVP_PKEY_keygen_init(ctx);
52 if(ERR_peek_last_error())
56 if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
60 if(EVP_PKEY_keygen(ctx, &newkey) <= 0)
66 EVP_PKEY_CTX_free(ctx);
71 void usage(char *name)
73 fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
77 int main(int argc, char **argv)
79 unsigned int data_len = 1;
80 unsigned int cycles = 100;
82 clockid_t clock_type = CLOCK_MONOTONIC;
83 int test, test_count = 0;
86 while((option = getopt(argc, argv, "l:c:C")) >= 0)
91 data_len = atoi(optarg);
94 cycles = atoi(optarg);
97 clock_type = CLOCK_PROCESS_CPUTIME_ID;
104 if (optind < argc) usage(argv[0]);
105 if (cycles < 100) { printf("cycles too low\n"); exit(1); }
107 OPENSSL_add_all_algorithms_conf();
108 ERR_load_crypto_strings();
110 for (test = 0; tests[test]; test += 3) {
111 double diff[2]; /* sign, verify */
112 const char *digest = tests[test];
113 const char *algo = tests[test + 1];
114 const char *param = tests[test + 2];
115 const EVP_MD *mdtype;
118 unsigned char *sigbuf;
123 md_ctx = EVP_MD_CTX_new();
124 mdtype = EVP_get_digestbyname(digest);
127 pkey = create_key(algo, param);
128 data = (unsigned char *) malloc(data_len);
135 siglen = EVP_PKEY_size(pkey);
136 sigbuf = malloc(siglen * cycles);
138 fprintf(stderr, "No tests were run, malloc failure.\n");
142 for (pass = 0; pass < 2; pass++) {
144 struct timeval debut, fin, delta;
148 clock_gettime(clock_type, &ts);
149 TIMESPEC_TO_TIMEVAL(&debut, &ts);
151 if (pass == 0) { /* sign */
152 for (i = 0; i < cycles; i++) {
153 EVP_SignInit(md_ctx, mdtype);
154 err = EVP_SignUpdate(md_ctx, data, data_len)
155 && EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
156 (unsigned int *)&siglen, pkey);
159 EVP_MD_CTX_reset(md_ctx);
161 } else { /* verify */
162 for (i = 0; i < cycles; i++) {
163 EVP_VerifyInit(md_ctx, mdtype);
164 err = EVP_VerifyUpdate(md_ctx, data, data_len)
165 && EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
167 EVP_MD_CTX_reset(md_ctx);
173 clock_gettime(clock_type, &ts);
174 TIMESPEC_TO_TIMEVAL(&fin, &ts);
175 timersub(&fin, &debut, &delta);
176 diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
178 printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
179 (double)cycles / diff[0], (double)cycles / diff[1]);
186 fprintf(stderr, "No tests were run, something is wrong.\n");