]> www.wagner.pp.ru Git - openssl-gost/engine.git/blob - benchmark/sign.c
Fix Coverity #300461
[openssl-gost/engine.git] / benchmark / sign.c
1 /**********************************************************************
2  *             Simple benchmarking for gost-engine                    *
3  *                                                                    *
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  **********************************************************************/
8
9 #define _GNU_SOURCE
10 #include <stdio.h>
11 #include <string.h>
12 #include <time.h>
13 #include <sys/time.h>
14 #include <getopt.h>
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>
21
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",
30
31     "md_gost12_512", "gost2012_512", "A",
32     "md_gost12_512", "gost2012_512", "B",
33     "md_gost12_512", "gost2012_512", "C",
34
35     NULL,
36 };
37
38 static EVP_PKEY *create_key(const char *algname, const char *param)
39 {
40         EVP_PKEY *key1 = EVP_PKEY_new(), *newkey = NULL;
41         EVP_PKEY_CTX *ctx = NULL;
42
43         if(EVP_PKEY_set_type_str(key1, algname, strlen(algname)) <= 0)
44         {
45                 goto err;
46         }
47         if(!(ctx = EVP_PKEY_CTX_new(key1, NULL)))
48         {
49                 goto err;
50         }
51         EVP_PKEY_keygen_init(ctx);
52         if(ERR_peek_last_error())
53         {
54                 goto err;
55         }
56         if(EVP_PKEY_CTX_ctrl_str(ctx, "paramset", param) <= 0)
57         {
58                 goto err;
59         }
60         if(EVP_PKEY_keygen(ctx, &newkey) <= 0)
61         {
62                 goto err;
63         }
64 err:
65         if(ctx)
66                 EVP_PKEY_CTX_free(ctx);
67         EVP_PKEY_free(key1);
68         return newkey;
69 }
70
71 void usage(char *name)
72 {
73         fprintf(stderr, "usage: %s [-l data_len] [-c cycles]\n", name);
74         exit(1);
75 }
76
77 int main(int argc, char **argv)
78 {
79         unsigned int data_len = 1;
80         unsigned int cycles = 100;
81         int option;
82         clockid_t clock_type = CLOCK_MONOTONIC;
83         int test, test_count = 0;
84
85         opterr = 0;
86         while((option = getopt(argc, argv, "l:c:C")) >= 0)
87         {
88                 if(option == ':') option = optopt;
89                 if(optarg && (optarg[0] == '-')) { optind--; optarg = NULL; }
90                 switch (option)
91                 {
92                         case 'l':
93                                 data_len = atoi(optarg);
94                                 break;
95                         case 'c':
96                                 cycles = atoi(optarg);
97                                 break;
98                         case 'C':
99                                 clock_type = CLOCK_PROCESS_CPUTIME_ID;
100                                 break;
101                         default:
102                                 usage(argv[0]);
103                                 break;
104                 }
105         }
106         if (optind < argc) usage(argv[0]);
107         if (cycles < 100) { printf("cycles too low\n"); exit(1); }
108
109         OPENSSL_add_all_algorithms_conf();
110         ERR_load_crypto_strings();
111
112         for (test = 0; tests[test]; test += 3) {
113             double diff[2]; /* sign, verify */
114             const char *digest = tests[test];
115             const char *algo   = tests[test + 1];
116             const char *param  = tests[test + 2];
117             const EVP_MD *mdtype;
118             EVP_MD_CTX *md_ctx;
119             unsigned int siglen;
120             unsigned char *sigbuf;
121             EVP_PKEY *pkey;
122             unsigned char *data;
123             int pass;
124
125             md_ctx = EVP_MD_CTX_new();
126             mdtype = EVP_get_digestbyname(digest);
127             if (!mdtype)
128                 continue;
129             pkey = create_key(algo, param);
130             data = (unsigned char *) malloc(data_len);
131             if (!pkey)
132                 continue;
133
134             test_count++;
135             printf("wait...");
136             fflush(stdout);
137             siglen = EVP_PKEY_size(pkey);
138             sigbuf = malloc(siglen * cycles);
139         if (!sigbuf) {
140             fprintf(stderr, "No tests were run, malloc failure.\n");
141             exit(1);
142         }
143
144             for (pass = 0; pass < 2; pass++) {
145                 struct timespec ts;
146                 struct timeval debut, fin, delta;
147                 int err;
148                 unsigned int i;
149
150                 clock_gettime(clock_type, &ts);
151                 TIMESPEC_TO_TIMEVAL(&debut, &ts);
152
153                 if (pass == 0) { /* sign */
154                     for (i = 0; i < cycles; i++) {
155                         EVP_SignInit(md_ctx, mdtype);
156                         err = EVP_SignUpdate(md_ctx, data, data_len)
157                            && EVP_SignFinal(md_ctx, &sigbuf[siglen * i],
158                             (unsigned int *)&siglen, pkey);
159                         if (err != 1)
160                             printf("!");
161                         EVP_MD_CTX_reset(md_ctx);
162                     }
163                 } else { /* verify */
164                     for (i = 0; i < cycles; i++) {
165                         EVP_VerifyInit(md_ctx, mdtype);
166                         err = EVP_VerifyUpdate(md_ctx, data, data_len)
167                            && EVP_VerifyFinal(md_ctx, &sigbuf[siglen * i],
168                             siglen, pkey);
169                         EVP_MD_CTX_reset(md_ctx);
170                         if (err != 1)
171                             printf("!");
172                     }
173                 }
174
175                 clock_gettime(clock_type, &ts);
176                 TIMESPEC_TO_TIMEVAL(&fin, &ts);
177                 timersub(&fin, &debut, &delta);
178                 diff[pass] = (double)delta.tv_sec + (double)delta.tv_usec / 1000000;
179             }
180             printf("\r%s %s: sign: %.1f/s, verify: %.1f/s\n", algo, param,
181                 (double)cycles / diff[0], (double)cycles / diff[1]);
182             EVP_PKEY_free(pkey);
183             free(sigbuf);
184             free(data);
185         }
186
187         if (!test_count) {
188             fprintf(stderr, "No tests were run, something is wrong.\n");
189             exit(1);
190         }
191         exit(0);
192 }