1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2  *
3  * LibTomCrypt is a library that provides various cryptographic
4  * algorithms in a highly modular and flexible manner.
5  *
6  * The library is free for all purposes without any express
7  * guarantee it works.
8  */
9 #include <tomcrypt_test.h>
10 
11 #ifndef GIT_VERSION
12 #define GIT_VERSION "Undefined version"
13 #endif
14 
15 #define LTC_TEST_FN(f)  { f, #f }
16 
17 typedef struct {
18    int (*fn)(void);
19    const char* name;
20 } test_function;
21 
22 static const test_function test_functions[] =
23 {
24       LTC_TEST_FN(store_test),
25       LTC_TEST_FN(rotate_test),
26       LTC_TEST_FN(misc_test),
27       LTC_TEST_FN(mpi_test),
28       LTC_TEST_FN(cipher_hash_test),
29       LTC_TEST_FN(mac_test),
30       LTC_TEST_FN(modes_test),
31       LTC_TEST_FN(der_test),
32       LTC_TEST_FN(pkcs_1_test),
33       LTC_TEST_FN(pkcs_1_pss_test),
34       LTC_TEST_FN(pkcs_1_oaep_test),
35       LTC_TEST_FN(pkcs_1_emsa_test),
36       LTC_TEST_FN(pkcs_1_eme_test),
37       LTC_TEST_FN(rsa_test),
38       LTC_TEST_FN(dh_test),
39       LTC_TEST_FN(ecc_tests),
40       LTC_TEST_FN(dsa_test),
41       LTC_TEST_FN(katja_test),
42       LTC_TEST_FN(file_test),
43       LTC_TEST_FN(multi_test),
44       /* keep the prng_test always at the end as
45        * it has to be handled specially when
46        * testing with LTC_PTHREAD enabled
47        */
48       LTC_TEST_FN(prng_test),
49 };
50 
51 
52 #if defined(_WIN32)
53   #include <windows.h> /* GetSystemTimeAsFileTime */
54 #else
55   #include <sys/time.h>
56 #endif
57 
58 /* microseconds since 1970 (UNIX epoch) */
epoch_usec(void)59 static ulong64 epoch_usec(void)
60 {
61 #if defined(LTC_NO_TEST_TIMING)
62   return 0;
63 #elif defined(_WIN32)
64   FILETIME CurrentTime;
65   ulong64 cur_time;
66   ULARGE_INTEGER ul;
67   GetSystemTimeAsFileTime(&CurrentTime);
68   ul.LowPart  = CurrentTime.dwLowDateTime;
69   ul.HighPart = CurrentTime.dwHighDateTime;
70   cur_time = ul.QuadPart;
71   cur_time -= CONST64(116444736000000000); /* subtract epoch in microseconds */
72   cur_time /= 10; /* nanoseconds > microseconds */
73   return cur_time;
74 #else
75   struct timeval tv;
76   gettimeofday(&tv, NULL);
77   return (ulong64)(tv.tv_sec) * 1000000 + (ulong64)(tv.tv_usec); /* get microseconds */
78 #endif
79 }
80 
81 #ifdef LTC_PTHREAD
82 typedef struct
83 {
84    pthread_t thread_id;
85    const test_function* t;
86    int err;
87    ulong64 delta;
88 } thread_info;
89 
run(void * arg)90 static void *run(void *arg)
91 {
92    thread_info *tinfo = arg;
93    ulong64 ts;
94 
95    ts = epoch_usec();
96    tinfo->err = tinfo->t->fn();
97    tinfo->delta = epoch_usec() - ts;
98 
99    return arg;
100 }
101 #endif
102 
103 
104 /*
105  * unregister ciphers, hashes & prngs
106  */
_unregister_all(void)107 static void _unregister_all(void)
108 {
109 #ifdef LTC_RIJNDAEL
110 #ifdef ENCRYPT_ONLY
111    /* alternative would be
112     * unregister_cipher(&rijndael_enc_desc);
113     */
114    unregister_cipher(&aes_enc_desc);
115 #else
116    /* alternative would be
117     * unregister_cipher(&rijndael_desc);
118     */
119    unregister_cipher(&aes_desc);
120 #endif
121 #endif
122 #ifdef LTC_BLOWFISH
123   unregister_cipher(&blowfish_desc);
124 #endif
125 #ifdef LTC_XTEA
126   unregister_cipher(&xtea_desc);
127 #endif
128 #ifdef LTC_RC5
129   unregister_cipher(&rc5_desc);
130 #endif
131 #ifdef LTC_RC6
132   unregister_cipher(&rc6_desc);
133 #endif
134 #ifdef LTC_SAFERP
135   unregister_cipher(&saferp_desc);
136 #endif
137 #ifdef LTC_TWOFISH
138   unregister_cipher(&twofish_desc);
139 #endif
140 #ifdef LTC_SAFER
141   unregister_cipher(&safer_k64_desc);
142   unregister_cipher(&safer_sk64_desc);
143   unregister_cipher(&safer_k128_desc);
144   unregister_cipher(&safer_sk128_desc);
145 #endif
146 #ifdef LTC_RC2
147   unregister_cipher(&rc2_desc);
148 #endif
149 #ifdef LTC_DES
150   unregister_cipher(&des_desc);
151   unregister_cipher(&des3_desc);
152 #endif
153 #ifdef LTC_CAST5
154   unregister_cipher(&cast5_desc);
155 #endif
156 #ifdef LTC_NOEKEON
157   unregister_cipher(&noekeon_desc);
158 #endif
159 #ifdef LTC_SKIPJACK
160   unregister_cipher(&skipjack_desc);
161 #endif
162 #ifdef LTC_KHAZAD
163   unregister_cipher(&khazad_desc);
164 #endif
165 #ifdef LTC_ANUBIS
166   unregister_cipher(&anubis_desc);
167 #endif
168 #ifdef LTC_KSEED
169   unregister_cipher(&kseed_desc);
170 #endif
171 #ifdef LTC_KASUMI
172   unregister_cipher(&kasumi_desc);
173 #endif
174 #ifdef LTC_MULTI2
175   unregister_cipher(&multi2_desc);
176 #endif
177 #ifdef LTC_CAMELLIA
178   unregister_cipher(&camellia_desc);
179 #endif
180 
181 #ifdef LTC_TIGER
182   unregister_hash(&tiger_desc);
183 #endif
184 #ifdef LTC_MD2
185   unregister_hash(&md2_desc);
186 #endif
187 #ifdef LTC_MD4
188   unregister_hash(&md4_desc);
189 #endif
190 #ifdef LTC_MD5
191   unregister_hash(&md5_desc);
192 #endif
193 #ifdef LTC_SHA1
194   unregister_hash(&sha1_desc);
195 #endif
196 #ifdef LTC_SHA224
197   unregister_hash(&sha224_desc);
198 #endif
199 #ifdef LTC_SHA256
200   unregister_hash(&sha256_desc);
201 #endif
202 #ifdef LTC_SHA384
203   unregister_hash(&sha384_desc);
204 #endif
205 #ifdef LTC_SHA512
206   unregister_hash(&sha512_desc);
207 #endif
208 #ifdef LTC_SHA512_224
209   unregister_hash(&sha512_224_desc);
210 #endif
211 #ifdef LTC_SHA512_256
212   unregister_hash(&sha512_256_desc);
213 #endif
214 #ifdef LTC_SHA3
215   unregister_hash(&sha3_224_desc);
216   unregister_hash(&sha3_256_desc);
217   unregister_hash(&sha3_384_desc);
218   unregister_hash(&sha3_512_desc);
219 #endif
220 #ifdef LTC_RIPEMD128
221   unregister_hash(&rmd128_desc);
222 #endif
223 #ifdef LTC_RIPEMD160
224   unregister_hash(&rmd160_desc);
225 #endif
226 #ifdef LTC_RIPEMD256
227   unregister_hash(&rmd256_desc);
228 #endif
229 #ifdef LTC_RIPEMD320
230   unregister_hash(&rmd320_desc);
231 #endif
232 #ifdef LTC_WHIRLPOOL
233   unregister_hash(&whirlpool_desc);
234 #endif
235 #ifdef LTC_BLAKE2S
236   unregister_hash(&blake2s_128_desc);
237   unregister_hash(&blake2s_160_desc);
238   unregister_hash(&blake2s_224_desc);
239   unregister_hash(&blake2s_256_desc);
240 #endif
241 #ifdef LTC_BLAKE2B
242   unregister_hash(&blake2b_160_desc);
243   unregister_hash(&blake2b_256_desc);
244   unregister_hash(&blake2b_384_desc);
245   unregister_hash(&blake2b_512_desc);
246 #endif
247 #ifdef LTC_CHC_HASH
248   unregister_hash(&chc_desc);
249 #endif
250 
251   unregister_prng(&yarrow_desc);
252 #ifdef LTC_FORTUNA
253   unregister_prng(&fortuna_desc);
254 #endif
255 #ifdef LTC_RC4
256   unregister_prng(&rc4_desc);
257 #endif
258 #ifdef LTC_CHACHA20_PRNG
259   unregister_prng(&chacha20_prng_desc);
260 #endif
261 #ifdef LTC_SOBER128
262   unregister_prng(&sober128_desc);
263 #endif
264 #ifdef LTC_SPRNG
265   unregister_prng(&sprng_desc);
266 #endif
267 } /* _cleanup() */
268 
register_algs(void)269 static void register_algs(void)
270 {
271   int err;
272 
273   atexit(_unregister_all);
274 
275 #ifndef LTC_YARROW
276    #error This demo requires Yarrow.
277 #endif
278    if ((err = register_all_ciphers()) != CRYPT_OK) {
279       fprintf(stderr, "register_all_ciphers err=%s\n", error_to_string(err));
280       exit(EXIT_FAILURE);
281    }
282    if ((err = register_all_hashes()) != CRYPT_OK) {
283       fprintf(stderr, "register_all_hashes err=%s\n", error_to_string(err));
284       exit(EXIT_FAILURE);
285    }
286    if ((err = register_all_prngs()) != CRYPT_OK) {
287       fprintf(stderr, "register_all_prngs err=%s\n", error_to_string(err));
288       exit(EXIT_FAILURE);
289    }
290 
291    if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) {
292       fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err));
293       exit(EXIT_FAILURE);
294    }
295 
296    if (strcmp("CRYPT_OK", error_to_string(err))) {
297        exit(EXIT_FAILURE);
298    }
299 }
300 
main(int argc,char ** argv)301 int main(int argc, char **argv)
302 {
303 #ifdef LTC_PTHREAD
304    thread_info *tinfo, *res;
305 #endif
306    int x, pass = 0, fail = 0, nop = 0;
307    size_t fn_len, i, dots;
308    char *single_test = NULL;
309    ulong64 ts;
310    long delta, dur, real = 0;
311    register_algs();
312 
313    printf("LTC_VERSION  = %s\n%s\n\n", GIT_VERSION, crypt_build_settings);
314 
315 #ifdef USE_LTM
316    ltc_mp = ltm_desc;
317    printf("MP_PROVIDER  = LibTomMath\n");
318 #elif defined(USE_TFM)
319    ltc_mp = tfm_desc;
320    printf("MP_PROVIDER  = TomsFastMath\n");
321 #elif defined(USE_GMP)
322    ltc_mp = gmp_desc;
323    printf("MP_PROVIDER  = GnuMP\n");
324 #elif defined(EXT_MATH_LIB)
325    {
326       extern ltc_math_descriptor EXT_MATH_LIB;
327       ltc_mp = EXT_MATH_LIB;
328    }
329 
330 #define NAME_VALUE(s) #s"="NAME(s)
331 #define NAME(s) #s
332    printf("MP_PROVIDER  = %s\n", NAME_VALUE(EXT_MATH_LIB));
333 #undef NAME_VALUE
334 #undef NAME
335 
336 #endif
337 #ifdef LTC_TEST_MPI
338    printf("MP_DIGIT_BIT = %d\n", MP_DIGIT_BIT);
339 #else
340    printf("NO math provider selected, all tests requiring MPI were disabled and will 'nop'\n");
341 #endif
342 
343    printf("sizeof(ltc_mp_digit) = %d\n", (int)sizeof(ltc_mp_digit));
344 
345 #ifdef LTC_PTHREAD
346    tinfo = XCALLOC(sizeof(test_functions)/sizeof(test_functions[0]), sizeof(thread_info));
347    if (tinfo == NULL) {
348       printf("\n\nFAILURE: XCALLOC\n");
349       return EXIT_FAILURE;
350    }
351 #endif
352 
353    fn_len = 0;
354    for (i = 0; i < sizeof(test_functions) / sizeof(test_functions[0]); ++i) {
355       size_t len = strlen(test_functions[i].name);
356       if (fn_len < len) fn_len = len;
357 
358 #ifdef LTC_PTHREAD
359       if(test_functions[i].fn == prng_test) continue;
360       tinfo[i].t = &test_functions[i];
361       x = pthread_create(&tinfo[i].thread_id, NULL, run, &tinfo[i]);
362       if (x != 0)  {
363          printf("\n\nFAILURE: pthread_create\n");
364          return EXIT_FAILURE;
365       }
366 #endif
367    }
368 
369    fn_len = fn_len + (4 - (fn_len % 4));
370 
371    /* single test name from commandline */
372    if (argc > 1) single_test = argv[1];
373 
374    dur = epoch_usec();
375    for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
376       if (single_test && strstr(test_functions[i].name, single_test) == NULL) {
377         continue;
378       }
379       dots = fn_len - strlen(test_functions[i].name);
380 
381       printf("\n%s", test_functions[i].name);
382       while(dots--) printf(".");
383       fflush(stdout);
384 
385 #ifdef LTC_PTHREAD
386       if(test_functions[i].fn != prng_test) {
387          x = pthread_join(tinfo[i].thread_id, (void**)&res);
388          if (x != 0){
389             printf("\n\nFAILURE: pthread_join\n");
390             return EXIT_FAILURE;
391          }
392          x = res->err;
393          delta = res->delta;
394       }
395       else {
396          ts = epoch_usec();
397          x = test_functions[i].fn();
398          delta = (long)(epoch_usec() - ts);
399       }
400 #else
401       ts = epoch_usec();
402       x = test_functions[i].fn();
403       delta = (long)(epoch_usec() - ts);
404 #endif
405       real += delta;
406 
407       if (x == CRYPT_OK) {
408          printf("passed %10.3fms", (double)(delta)/1000);
409          pass++;
410       }
411       else if (x == CRYPT_NOP) {
412          printf("nop");
413          nop++;
414       }
415       else {
416          printf("failed (%s) %10.3fms", error_to_string(x), (double)(delta)/1000);
417          fail++;
418       }
419    }
420    dur = epoch_usec() - dur;
421 
422 #ifdef LTC_PTHREAD
423    XFREE(tinfo);
424 #endif
425 
426    x = (fail > 0 || fail+pass+nop == 0) ? EXIT_FAILURE : EXIT_SUCCESS;
427    printf("\n\n%s: passed=%d failed=%d nop=%d duration=%.1fsec real=%.1fsec\n", x ? "FAILURE" : "SUCCESS", pass, fail, nop, (double)(dur)/(1000*1000), (double)(real)/(1000*1000));
428    return x;
429 }
430 
431 /* ref:         HEAD -> master, tag: v1.18.2 */
432 /* git commit:  7e7eb695d581782f04b24dc444cbfde86af59853 */
433 /* commit time: 2018-07-01 22:49:01 +0200 */
434