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