Minor bug fixes.
[libgcrypt.git] / tests / benchmark.c
1 /* benchmark.c - for libgcrypt
2  * Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser general Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include <stdarg.h>
27 #ifdef _WIN32
28 #include <windows.h>
29 #else
30 #include <sys/times.h>
31 #endif
32
33 #ifdef _GCRYPT_IN_LIBGCRYPT
34 # include "../src/gcrypt.h"
35 #else
36 # include <gcrypt.h>
37 #endif
38
39
40 #define PGM "benchmark"
41
42 static int verbose;
43
44 /* Do encryption tests with large buffers.  */
45 static int large_buffers;
46
47 /* Number of cipher repetitions.  */
48 static int cipher_repetitions;
49
50 /* Whether fips mode was active at startup.  */
51 static int in_fips_mode;
52
53
54 static const char sample_private_dsa_key_1024[] =
55 "(private-key\n"
56 "  (dsa\n"
57 "   (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
58        "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
59        "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
60        "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
61 "   (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
62 "   (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
63        "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
64        "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
65        "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
66 "   (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
67        "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
68        "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
69        "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
70 "   (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n"
71 "))\n";
72
73 static const char sample_public_dsa_key_1024[] =
74 "(public-key\n"
75 "  (dsa\n"
76 "   (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
77        "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
78        "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
79        "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
80 "   (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
81 "   (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
82        "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
83        "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
84        "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
85 "   (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
86        "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
87        "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
88        "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
89 "))\n";
90
91
92 static const char sample_private_dsa_key_2048[] =
93 "(private-key\n"
94 "  (dsa\n"
95 "   (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
96        "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
97        "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
98        "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
99        "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
100        "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
101        "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
102        "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
103 "   (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
104 "   (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
105        "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
106        "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
107        "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
108        "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
109        "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
110        "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
111        "6EE4425A553AF8885FEA15A88135BE133520#)\n"
112 "   (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
113        "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
114        "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
115        "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
116        "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
117        "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
118        "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
119        "14A264330AECCB24DE2A1107847B23490897#)\n"
120 "   (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n"
121 "))\n";
122
123
124 static const char sample_public_dsa_key_2048[] =
125 "(public-key\n"
126 "  (dsa\n"
127 "   (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
128        "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
129        "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
130        "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
131        "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
132        "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
133        "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
134        "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
135 "   (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
136 "   (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
137        "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
138        "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
139        "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
140        "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
141        "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
142        "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
143        "6EE4425A553AF8885FEA15A88135BE133520#)\n"
144 "   (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
145        "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
146        "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
147        "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
148        "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
149        "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
150        "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
151        "14A264330AECCB24DE2A1107847B23490897#)\n"
152 "))\n";
153
154
155 static const char sample_private_dsa_key_3072[] =
156 "(private-key\n"
157 "  (dsa\n"
158 "   (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
159        "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
160        "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
161        "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
162        "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
163        "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
164        "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
165        "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
166        "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
167        "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
168        "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
169        "8015353D3778B02B892AF7#)\n"
170 "   (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
171 "   (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
172        "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
173        "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
174        "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
175        "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
176        "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
177        "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
178        "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
179        "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
180        "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
181        "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
182        "4997AF9EB55C6660B01A#)\n"
183 "   (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
184        "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
185        "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
186        "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
187        "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
188        "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
189        "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
190        "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
191        "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
192        "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
193        "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
194        "2703D518D8D49FF0EBE6#)\n"
195 "   (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n"
196 "))\n";
197
198 static const char sample_public_dsa_key_3072[] =
199 "(public-key\n"
200 "  (dsa\n"
201 "   (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
202        "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
203        "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
204        "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
205        "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
206        "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
207        "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
208        "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
209        "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
210        "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
211        "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
212        "8015353D3778B02B892AF7#)\n"
213 "   (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
214 "   (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
215        "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
216        "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
217        "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
218        "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
219        "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
220        "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
221        "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
222        "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
223        "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
224        "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
225        "4997AF9EB55C6660B01A#)\n"
226 "   (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
227        "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
228        "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
229        "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
230        "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
231        "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
232        "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
233        "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
234        "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
235        "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
236        "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
237        "2703D518D8D49FF0EBE6#)\n"
238 "))\n";
239
240
241 #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
242 #define DIMof(type,member)   DIM(((type *)0)->member)
243 #define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
244                   exit(2);} while(0)
245
246
247 /* Helper for the start and stop timer. */
248 #ifdef _WIN32
249 struct {
250   FILETIME creation_time, exit_time, kernel_time, user_time;
251 } started_at, stopped_at;
252 #else
253 static clock_t started_at, stopped_at;
254 #endif
255
256 static void
257 die (const char *format, ...)
258 {
259   va_list arg_ptr ;
260
261   va_start( arg_ptr, format ) ;
262   putchar ('\n');
263   fputs ( PGM ": ", stderr);
264   vfprintf (stderr, format, arg_ptr );
265   va_end(arg_ptr);
266   exit (1);
267 }
268
269 static void
270 show_sexp (const char *prefix, gcry_sexp_t a)
271 {
272   char *buf;
273   size_t size;
274
275   fputs (prefix, stderr);
276   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
277   buf = malloc (size);
278   if (!buf)
279     die ("out of core\n");
280
281   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
282   fprintf (stderr, "%.*s", (int)size, buf);
283 }
284
285
286 static void
287 start_timer (void)
288 {
289 #ifdef _WIN32
290   GetProcessTimes (GetCurrentProcess (),
291                    &started_at.creation_time, &started_at.exit_time,
292                    &started_at.kernel_time, &started_at.user_time);
293   stopped_at = started_at;
294 #else
295   struct tms tmp;
296
297   times (&tmp);
298   started_at = stopped_at = tmp.tms_utime;
299 #endif
300 }
301
302 static void
303 stop_timer (void)
304 {
305 #ifdef _WIN32
306   GetProcessTimes (GetCurrentProcess (),
307                    &stopped_at.creation_time, &stopped_at.exit_time,
308                    &stopped_at.kernel_time, &stopped_at.user_time);
309 #else
310   struct tms tmp;
311
312   times (&tmp);
313   stopped_at = tmp.tms_utime;
314 #endif
315 }
316
317 static const char *
318 elapsed_time (void)
319 {
320   static char buf[50];
321 #if _WIN32
322   unsigned long long t1, t2, t;
323
324   t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
325         + started_at.kernel_time.dwLowDateTime);
326   t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
327         + started_at.user_time.dwLowDateTime);
328   t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
329         + stopped_at.kernel_time.dwLowDateTime);
330   t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32)
331         + stopped_at.user_time.dwLowDateTime);
332   t = (t2 - t1)/10000;
333   snprintf (buf, sizeof buf, "%5.0fms", (double)t );
334 #else
335   snprintf (buf, sizeof buf, "%5.0fms",
336             (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
337 #endif
338   return buf;
339 }
340
341
342 static void
343 random_bench (int very_strong)
344 {
345   char buf[128];
346   int i;
347
348   printf ("%-10s", "random");
349
350   if (!very_strong)
351     {
352       start_timer ();
353       for (i=0; i < 100; i++)
354         gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
355       stop_timer ();
356       printf (" %s", elapsed_time ());
357     }
358
359   start_timer ();
360   for (i=0; i < 100; i++)
361     gcry_randomize (buf, 8,
362                     very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM);
363   stop_timer ();
364   printf (" %s", elapsed_time ());
365
366   putchar ('\n');
367   if (verbose)
368     gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
369 }
370
371
372
373 static void
374 md_bench ( const char *algoname )
375 {
376   int algo;
377   gcry_md_hd_t hd;
378   int i;
379   char buf[1000];
380   gcry_error_t err = GPG_ERR_NO_ERROR;
381
382   if (!algoname)
383     {
384       for (i=1; i < 400; i++)
385         if (in_fips_mode && i == GCRY_MD_MD5)
386           ; /* Don't use MD5 in fips mode.  */
387         else if ( !gcry_md_test_algo (i) )
388           md_bench (gcry_md_algo_name (i));
389       return;
390     }
391
392   algo = gcry_md_map_name (algoname);
393   if (!algo)
394     {
395       fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
396       exit (1);
397     }
398
399   err = gcry_md_open (&hd, algo, 0);
400   if (err)
401     {
402       fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
403       exit (1);
404     }
405
406   for (i=0; i < sizeof buf; i++)
407     buf[i] = i;
408
409   printf ("%-12s", gcry_md_algo_name (algo));
410
411   start_timer ();
412   for (i=0; i < 1000; i++)
413     gcry_md_write (hd, buf, sizeof buf);
414   gcry_md_final (hd);
415   stop_timer ();
416   printf (" %s", elapsed_time ());
417
418   gcry_md_reset (hd);
419   start_timer ();
420   for (i=0; i < 10000; i++)
421     gcry_md_write (hd, buf, sizeof buf/10);
422   gcry_md_final (hd);
423   stop_timer ();
424   printf (" %s", elapsed_time ());
425
426   gcry_md_reset (hd);
427   start_timer ();
428   for (i=0; i < 1000000; i++)
429     gcry_md_write (hd, "", 1);
430   gcry_md_final (hd);
431   stop_timer ();
432   printf (" %s", elapsed_time ());
433
434   gcry_md_close (hd);
435   putchar ('\n');
436 }
437
438 static void
439 cipher_bench ( const char *algoname )
440 {
441   static int header_printed;
442   int algo;
443   gcry_cipher_hd_t hd;
444   int i;
445   int keylen, blklen;
446   char key[128];
447   char *outbuf, *buf;
448   size_t allocated_buflen, buflen;
449   int repetitions;
450   static struct { int mode; const char *name; int blocked; } modes[] = {
451     { GCRY_CIPHER_MODE_ECB, "      ECB", 1 },
452     { GCRY_CIPHER_MODE_CBC, "      CBC", 1 },
453     { GCRY_CIPHER_MODE_CFB, "      CFB", 0 },
454     { GCRY_CIPHER_MODE_OFB, "      OFB", 0 },
455     { GCRY_CIPHER_MODE_CTR, "      CTR", 0 },
456     { GCRY_CIPHER_MODE_STREAM, "    STREAM", 0 },
457     {0}
458   };
459   int modeidx;
460   gcry_error_t err = GPG_ERR_NO_ERROR;
461
462
463   if (!algoname)
464     {
465       for (i=1; i < 400; i++)
466         if ( !gcry_cipher_test_algo (i) )
467           cipher_bench (gcry_cipher_algo_name (i));
468       return;
469     }
470
471   if (large_buffers)
472     {
473       allocated_buflen = 1024 * 100;
474       repetitions = 10;
475     }
476   else
477     {
478       allocated_buflen = 1024;
479       repetitions = 1000;
480     }
481   repetitions *= cipher_repetitions;
482
483   buf = gcry_xmalloc (allocated_buflen);
484   outbuf = gcry_xmalloc (allocated_buflen);
485
486   if (!header_printed)
487     {
488       if (cipher_repetitions != 1)
489         printf ("Running each test %d times.\n", cipher_repetitions);
490       printf ("%-12s", "");
491       for (modeidx=0; modes[modeidx].mode; modeidx++)
492         printf (" %-15s", modes[modeidx].name );
493       putchar ('\n');
494       printf ("%-12s", "");
495       for (modeidx=0; modes[modeidx].mode; modeidx++)
496         printf (" ---------------" );
497       putchar ('\n');
498       header_printed = 1;
499     }
500
501   algo = gcry_cipher_map_name (algoname);
502   if (!algo)
503     {
504       fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
505       exit (1);
506     }
507
508   keylen = gcry_cipher_get_algo_keylen (algo);
509   if (!keylen)
510     {
511       fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
512                algoname);
513       exit (1);
514     }
515   if ( keylen > sizeof key )
516     {
517         fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
518                  algo, keylen );
519         exit (1);
520     }
521   for (i=0; i < keylen; i++)
522     key[i] = i + (clock () & 0xff);
523
524   blklen = gcry_cipher_get_algo_blklen (algo);
525   if (!blklen)
526     {
527       fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
528                algoname);
529       exit (1);
530     }
531
532   printf ("%-12s", gcry_cipher_algo_name (algo));
533   fflush (stdout);
534
535   for (modeidx=0; modes[modeidx].mode; modeidx++)
536     {
537       if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
538           | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
539         {
540           printf ("                " );
541           continue;
542         }
543
544       for (i=0; i < sizeof buf; i++)
545         buf[i] = i;
546
547       err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
548       if (err)
549         {
550           fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
551           exit (1);
552         }
553       
554       err = gcry_cipher_setkey (hd, key, keylen);
555       if (err)
556       { 
557           fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
558                    gpg_strerror (err));
559           gcry_cipher_close (hd);
560           exit (1);
561         }
562
563       buflen = allocated_buflen;
564       if (modes[modeidx].blocked)
565         buflen = (buflen / blklen) * blklen;
566       
567       start_timer ();
568       for (i=err=0; !err && i < repetitions; i++)
569         err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
570       stop_timer ();
571
572       printf (" %s", elapsed_time ());
573       fflush (stdout);
574       gcry_cipher_close (hd);
575       if (err)
576         { 
577           fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
578                    gpg_strerror (err) );
579           exit (1);
580         }
581
582       err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
583       if (err)
584         {
585           fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
586           exit (1);
587         }
588       
589       err = gcry_cipher_setkey (hd, key, keylen);
590       if (err)
591         { 
592           fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
593                    gpg_strerror (err));
594           gcry_cipher_close (hd);
595           exit (1);
596         }
597
598       start_timer ();
599       for (i=err=0; !err && i < repetitions; i++)
600         err = gcry_cipher_decrypt ( hd, outbuf, buflen,  buf, buflen);
601       stop_timer ();
602       printf (" %s", elapsed_time ());
603       fflush (stdout);
604       gcry_cipher_close (hd);
605       if (err)
606         { 
607           fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
608                    gpg_strerror (err) );
609           exit (1);
610         }
611     }
612
613   putchar ('\n');
614   gcry_free (buf);
615   gcry_free (outbuf);
616 }
617
618
619
620 static void
621 rsa_bench (int iterations, int print_header, int no_blinding)
622 {
623   gpg_error_t err;
624   int p_sizes[] = { 1024, 2048, 3072, 4096 };
625   int testno;
626
627   if (print_header)
628     printf ("Algorithm         generate %4d*sign %4d*verify\n"
629             "------------------------------------------------\n",
630             iterations, iterations );
631   for (testno=0; testno < DIM (p_sizes); testno++)
632     {
633       gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
634       gcry_mpi_t x;
635       gcry_sexp_t data;
636       gcry_sexp_t sig = NULL;
637       int count;
638
639       printf ("RSA %3d bit    ", p_sizes[testno]);
640       fflush (stdout);
641
642       err = gcry_sexp_build (&key_spec, NULL,
643                              gcry_fips_mode_active ()
644                              ? "(genkey (RSA (nbits %d)))"
645                              : "(genkey (RSA (nbits %d)(transient-key)))",
646                              p_sizes[testno]);
647       if (err)
648         die ("creating S-expression failed: %s\n", gcry_strerror (err));
649
650       start_timer ();
651       err = gcry_pk_genkey (&key_pair, key_spec);
652       if (err)
653         die ("creating %d bit RSA key failed: %s\n",
654              p_sizes[testno], gcry_strerror (err));
655
656       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
657       if (! pub_key)
658         die ("public part missing in key\n");
659       sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
660       if (! sec_key)
661         die ("private part missing in key\n");
662       gcry_sexp_release (key_pair);
663       gcry_sexp_release (key_spec);
664
665       stop_timer ();
666       printf ("   %s", elapsed_time ());
667       fflush (stdout);
668
669       x = gcry_mpi_new (p_sizes[testno]);
670       gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
671       err = gcry_sexp_build (&data, NULL,
672                              "(data (flags raw) (value %m))", x);
673       gcry_mpi_release (x);
674       if (err)
675         die ("converting data failed: %s\n", gcry_strerror (err));
676
677       start_timer ();
678       for (count=0; count < iterations; count++)
679         {
680           gcry_sexp_release (sig);
681           err = gcry_pk_sign (&sig, data, sec_key);
682           if (err)
683             die ("signing failed (%d): %s\n", count, gpg_strerror (err));
684         }
685       stop_timer ();
686       printf ("   %s", elapsed_time ());
687       fflush (stdout);
688
689       start_timer ();
690       for (count=0; count < iterations; count++)
691         {
692           err = gcry_pk_verify (sig, data, pub_key);
693           if (err)
694             {
695               putchar ('\n');
696               show_sexp ("seckey:\n", sec_key);
697               show_sexp ("data:\n", data);
698               show_sexp ("sig:\n", sig);
699               die ("verify failed (%d): %s\n", count, gpg_strerror (err));
700             }
701         }
702       stop_timer ();
703       printf ("     %s", elapsed_time ());
704
705       if (no_blinding)
706         {
707           fflush (stdout);
708           x = gcry_mpi_new (p_sizes[testno]);
709           gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
710           err = gcry_sexp_build (&data, NULL,
711                                  "(data (flags no-blinding) (value %m))", x);
712           gcry_mpi_release (x);
713           if (err)
714             die ("converting data failed: %s\n", gcry_strerror (err));
715
716           start_timer ();
717           for (count=0; count < iterations; count++)
718             {
719               gcry_sexp_release (sig);
720               err = gcry_pk_sign (&sig, data, sec_key);
721               if (err)
722                 die ("signing failed (%d): %s\n", count, gpg_strerror (err));
723             }
724           stop_timer ();
725           printf ("   %s", elapsed_time ());
726           fflush (stdout);
727         }
728
729       putchar ('\n');
730       fflush (stdout);
731
732       gcry_sexp_release (sig);
733       gcry_sexp_release (data);
734       gcry_sexp_release (sec_key);
735       gcry_sexp_release (pub_key);
736     }
737 }
738
739
740
741 static void
742 dsa_bench (int iterations, int print_header)
743 {
744   gpg_error_t err;
745   gcry_sexp_t pub_key[3], sec_key[3];
746   int p_sizes[3] = { 1024, 2048, 3072 };
747   int q_sizes[3] = { 160, 224, 256 };
748   gcry_sexp_t data;
749   gcry_sexp_t sig;
750   int i, j;
751
752   err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
753                          strlen (sample_public_dsa_key_1024));
754   if (!err)
755     err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
756                            strlen (sample_private_dsa_key_1024));
757   if (!err)
758     err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
759                            strlen (sample_public_dsa_key_2048));
760   if (!err)
761     err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
762                            strlen (sample_private_dsa_key_2048));
763   if (!err)
764     err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
765                            strlen (sample_public_dsa_key_3072));
766   if (!err)
767     err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
768                            strlen (sample_private_dsa_key_3072));
769   if (err)
770     {
771       fprintf (stderr, PGM ": converting sample keys failed: %s\n",
772                gcry_strerror (err));
773       exit (1);
774     }
775
776   if (print_header)
777     printf ("Algorithm         generate %4d*sign %4d*verify\n"
778             "------------------------------------------------\n",
779             iterations, iterations );
780   for (i=0; i < DIM (q_sizes); i++)
781     {
782       gcry_mpi_t x;
783
784       x = gcry_mpi_new (q_sizes[i]);
785       gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
786       err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
787       gcry_mpi_release (x);
788       if (err)
789         {
790           fprintf (stderr, PGM ": converting data failed: %s\n",
791                    gcry_strerror (err));
792           exit (1);
793         }
794
795       printf ("DSA %d/%d             -", p_sizes[i], q_sizes[i]);
796       fflush (stdout);
797
798       start_timer ();
799       for (j=0; j < iterations; j++)
800         {
801           err = gcry_pk_sign (&sig, data, sec_key[i]);
802           if (err)
803             {
804               putchar ('\n');
805               fprintf (stderr, PGM ": signing failed: %s\n",
806                        gpg_strerror (err));
807               exit (1);
808             }
809         }
810       stop_timer ();
811       printf ("   %s", elapsed_time ());
812       fflush (stdout);
813
814       start_timer ();
815       for (j=0; j < iterations; j++)
816         {
817           err = gcry_pk_verify (sig, data, pub_key[i]);
818           if (err)
819             {
820               putchar ('\n');
821               fprintf (stderr, PGM ": verify failed: %s\n",
822                        gpg_strerror (err));
823               exit (1);
824             }
825         }
826       stop_timer ();
827       printf ("     %s\n", elapsed_time ());
828       fflush (stdout);
829
830       gcry_sexp_release (sig);
831       gcry_sexp_release (data);
832     }
833
834
835   for (i=0; i < DIM (q_sizes); i++)
836     {
837       gcry_sexp_release (sec_key[i]);
838       gcry_sexp_release (pub_key[i]);
839     }
840 }
841
842
843 static void
844 ecc_bench (int iterations, int print_header)
845 {
846 #if USE_ECC
847   gpg_error_t err;
848   int p_sizes[] = { 192, 224, 256, 384, 521 };
849   int testno;
850
851   if (print_header)
852     printf ("Algorithm         generate %4d*sign %4d*verify\n"
853             "------------------------------------------------\n",
854             iterations, iterations );
855   for (testno=0; testno < DIM (p_sizes); testno++)
856     {
857       gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
858       gcry_mpi_t x;
859       gcry_sexp_t data;
860       gcry_sexp_t sig = NULL;
861       int count;
862
863       printf ("ECDSA %3d bit ", p_sizes[testno]);
864       fflush (stdout);
865
866       err = gcry_sexp_build (&key_spec, NULL,
867                              "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
868       if (err)
869         die ("creating S-expression failed: %s\n", gcry_strerror (err));
870
871       start_timer ();
872       err = gcry_pk_genkey (&key_pair, key_spec);
873       if (err)
874         die ("creating %d bit ECC key failed: %s\n",
875              p_sizes[testno], gcry_strerror (err));
876
877       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
878       if (! pub_key)
879         die ("public part missing in key\n");
880       sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
881       if (! sec_key)
882         die ("private part missing in key\n");
883       gcry_sexp_release (key_pair);
884       gcry_sexp_release (key_spec);
885
886       stop_timer ();
887       printf ("     %s", elapsed_time ());
888       fflush (stdout);
889
890       x = gcry_mpi_new (p_sizes[testno]);
891       gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
892       err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
893       gcry_mpi_release (x);
894       if (err)
895         die ("converting data failed: %s\n", gcry_strerror (err));
896
897       start_timer ();
898       for (count=0; count < iterations; count++)
899         {
900           gcry_sexp_release (sig);
901           err = gcry_pk_sign (&sig, data, sec_key);
902           if (err)
903             die ("signing failed: %s\n", gpg_strerror (err));
904         }
905       stop_timer ();
906       printf ("   %s", elapsed_time ());
907       fflush (stdout);
908
909       start_timer ();
910       for (count=0; count < iterations; count++)
911         {
912           err = gcry_pk_verify (sig, data, pub_key);
913           if (err)
914             {
915               putchar ('\n');
916               show_sexp ("seckey:\n", sec_key);
917               show_sexp ("data:\n", data);
918               show_sexp ("sig:\n", sig);
919               die ("verify failed: %s\n", gpg_strerror (err));
920             }
921         }
922       stop_timer ();
923       printf ("     %s\n", elapsed_time ());
924       fflush (stdout);
925
926       gcry_sexp_release (sig);
927       gcry_sexp_release (data);
928       gcry_sexp_release (sec_key);
929       gcry_sexp_release (pub_key);
930     }
931 #endif /*USE_ECC*/
932 }
933
934
935
936 static void
937 do_powm ( const char *n_str, const char *e_str, const char *m_str)
938 {
939   gcry_mpi_t e, n, msg, cip;
940   gcry_error_t err;
941   int i;
942
943   err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
944   if (err) BUG ();
945   err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
946   if (err) BUG ();
947   err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
948   if (err) BUG ();
949
950   cip = gcry_mpi_new (0);
951
952   start_timer ();
953   for (i=0; i < 1000; i++)
954     gcry_mpi_powm (cip, msg, e, n);
955   stop_timer ();
956   printf (" %s", elapsed_time ()); fflush (stdout);
957 /*    { */
958 /*      char *buf; */
959
960 /*      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
961 /*        BUG (); */
962 /*      printf ("result: %s\n", buf); */
963 /*      gcry_free (buf); */
964 /*    } */
965   gcry_mpi_release (cip);
966   gcry_mpi_release (msg);
967   gcry_mpi_release (n);
968   gcry_mpi_release (e);
969 }
970
971
972 static void
973 mpi_bench (void)
974 {
975   printf ("%-10s", "powm"); fflush (stdout);
976
977   do_powm (
978 "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
979            "29", 
980 "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
981            );
982   do_powm (
983            "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
984            "29", 
985            "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
986            );
987   do_powm (
988            "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
989            "29", 
990            "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
991            );
992
993   putchar ('\n');
994
995
996 }
997
998
999 int
1000 main( int argc, char **argv )
1001 {
1002   int last_argc = -1;
1003   int no_blinding = 0;
1004   int use_random_daemon = 0;
1005
1006   if (argc)
1007     { argc--; argv++; }
1008
1009   while (argc && last_argc != argc )
1010     {
1011       last_argc = argc;
1012       if (!strcmp (*argv, "--"))
1013         {
1014           argc--; argv++;
1015           break;
1016         }
1017       else if (!strcmp (*argv, "--help"))
1018         {
1019           fputs ("usage: benchmark "
1020                  "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
1021                  stdout);
1022           exit (0);
1023         }
1024       else if (!strcmp (*argv, "--verbose"))
1025         {
1026           verbose++;
1027           argc--; argv++;
1028         }
1029       else if (!strcmp (*argv, "--use-random-daemon"))
1030         {
1031           use_random_daemon = 1;
1032           argc--; argv++;
1033         }
1034       else if (!strcmp (*argv, "--no-blinding"))
1035         {
1036           no_blinding = 1;
1037           argc--; argv++;
1038         }
1039       else if (!strcmp (*argv, "--large-buffers"))
1040         {
1041           large_buffers = 1;
1042           argc--; argv++;
1043         }
1044       else if (!strcmp (*argv, "--cipher-repetition"))
1045         {
1046           argc--; argv++;
1047           if (argc)
1048             {
1049               cipher_repetitions = atoi(*argv);
1050               argc--; argv++;
1051             }
1052         }
1053       else if (!strcmp (*argv, "--fips"))
1054         {
1055           argc--; argv++;
1056           /* This command needs to be called before gcry_check_version.  */
1057           gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
1058         }
1059     }          
1060
1061   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
1062
1063   if (!gcry_check_version (GCRYPT_VERSION))
1064     {
1065       fprintf (stderr, PGM ": version mismatch\n");
1066       exit (1);
1067     }
1068
1069   if (gcry_fips_mode_active ())
1070     in_fips_mode = 1;
1071   else
1072     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
1073
1074   if (use_random_daemon)
1075     gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
1076
1077   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
1078
1079
1080   if (cipher_repetitions < 1)
1081     cipher_repetitions = 1;
1082   
1083   if ( !argc )
1084     {
1085       gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1086       md_bench (NULL);
1087       putchar ('\n');
1088       cipher_bench (NULL);
1089       putchar ('\n');
1090       rsa_bench (100, 1, no_blinding);
1091       dsa_bench (100, 0);
1092       ecc_bench (100, 0);
1093       putchar ('\n');
1094       mpi_bench ();
1095       putchar ('\n');
1096       random_bench (0);
1097     }
1098   else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom"))
1099     {
1100       if (argc == 1)
1101         random_bench ((**argv == 's'));
1102       else if (argc == 2)
1103         {
1104           gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]);
1105           random_bench ((**argv == 's'));
1106           gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
1107         }
1108       else
1109         fputs ("usage: benchmark [strong]random [seedfile]\n", stdout);
1110     }
1111   else if ( !strcmp (*argv, "md"))
1112     {
1113       if (argc == 1)
1114         md_bench (NULL);
1115       else
1116         for (argc--, argv++; argc; argc--, argv++)
1117           md_bench ( *argv );
1118     }
1119   else if ( !strcmp (*argv, "cipher"))
1120     {
1121       if (argc == 1)
1122         cipher_bench (NULL);
1123       else
1124         for (argc--, argv++; argc; argc--, argv++)
1125           cipher_bench ( *argv );
1126     }
1127   else if ( !strcmp (*argv, "mpi"))
1128     {
1129         mpi_bench ();
1130     }
1131   else if ( !strcmp (*argv, "rsa"))
1132     {
1133         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1134         rsa_bench (100, 1, no_blinding);
1135     }
1136   else if ( !strcmp (*argv, "dsa"))
1137     {
1138         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1139         dsa_bench (100, 1);
1140     }
1141   else if ( !strcmp (*argv, "ecc"))
1142     {
1143         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
1144         ecc_bench (100, 1);
1145     }
1146   else
1147     {
1148       fprintf (stderr, PGM ": bad arguments\n");
1149       return 1;
1150     }
1151
1152
1153   if (in_fips_mode && !gcry_fips_mode_active ())
1154     fprintf (stderr, PGM ": FIPS mode is not anymore active\n");
1155   
1156   return 0;
1157 }
1158