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.h>
10 
11 #if defined(_WIN32)
12    #define PRI64  "I64d"
13 #else
14    #define PRI64  "ll"
15 #endif
16 
17 static prng_state yarrow_prng;
18 
19 /* timing */
20 #define KTIMES  25
21 #define TIMES   100000
22 
23 static struct list {
24     int id;
25     ulong64 spd1, spd2, avg;
26 } results[100];
27 static int no_results;
28 
sorter(const void * a,const void * b)29 static int sorter(const void *a, const void *b)
30 {
31    const struct list *A, *B;
32    A = a;
33    B = b;
34    if (A->avg < B->avg) return -1;
35    if (A->avg > B->avg) return 1;
36    return 0;
37 }
38 
tally_results(int type)39 static void tally_results(int type)
40 {
41    int x;
42 
43    /* qsort the results */
44    qsort(results, no_results, sizeof(struct list), &sorter);
45 
46    fprintf(stderr, "\n");
47    if (type == 0) {
48       for (x = 0; x < no_results; x++) {
49          fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1);
50       }
51    } else if (type == 1) {
52       for (x = 0; x < no_results; x++) {
53         printf
54           ("%-20s[%3d]: Encrypt at %5"PRI64"u, Decrypt at %5"PRI64"u\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2);
55       }
56    } else {
57       for (x = 0; x < no_results; x++) {
58         printf
59           ("%-20s: Process at %5"PRI64"u\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000);
60       }
61    }
62 }
63 
64 /* RDTSC from Scott Duplichan */
rdtsc(void)65 static ulong64 rdtsc (void)
66    {
67    #if defined __GNUC__ && !defined(LTC_NO_ASM)
68       #if defined(__i386__) || defined(__x86_64__)
69          /* version from http://www.mcs.anl.gov/~kazutomo/rdtsc.html
70           * the old code always got a warning issued by gcc, clang did not complain...
71           */
72          unsigned hi, lo;
73          __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
74          return ((ulong64)lo)|( ((ulong64)hi)<<32);
75       #elif defined(LTC_PPC32) || defined(TFM_PPC32)
76          unsigned long a, b;
77          __asm__ __volatile__ ("mftbu %1 \nmftb %0\n":"=r"(a), "=r"(b));
78          return (((ulong64)b) << 32ULL) | ((ulong64)a);
79       #elif defined(__ia64__)  /* gcc-IA64 version */
80          unsigned long result;
81          __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
82          while (__builtin_expect ((int) result == -1, 0))
83          __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
84          return result;
85       #elif defined(__sparc__)
86          #if defined(__arch64__)
87            ulong64 a;
88            asm volatile("rd %%tick,%0" : "=r" (a));
89            return a;
90          #else
91            register unsigned long x, y;
92            __asm__ __volatile__ ("rd %%tick, %0; clruw %0, %1; srlx %0, 32, %0" : "=r" (x), "=r" (y) : "0" (x), "1" (y));
93            return ((unsigned long long) x << 32) | y;
94          #endif
95       #else
96          return XCLOCK();
97       #endif
98 
99    /* Microsoft and Intel Windows compilers */
100    #elif defined _M_IX86 && !defined(LTC_NO_ASM)
101      __asm rdtsc
102    #elif defined _M_AMD64 && !defined(LTC_NO_ASM)
103      return __rdtsc ();
104    #elif defined _M_IA64 && !defined(LTC_NO_ASM)
105      #if defined __INTEL_COMPILER
106        #include <ia64intrin.h>
107      #endif
108       return __getReg (3116);
109    #else
110      return XCLOCK();
111    #endif
112    }
113 
114 static ulong64 timer, skew = 0;
115 
t_start(void)116 static void t_start(void)
117 {
118    timer = rdtsc();
119 }
120 
t_read(void)121 static ulong64 t_read(void)
122 {
123    return rdtsc() - timer;
124 }
125 
init_timer(void)126 static void init_timer(void)
127 {
128    ulong64 c1, c2, t1, t2;
129    unsigned long y1;
130 
131    c1 = c2 = (ulong64)-1;
132    for (y1 = 0; y1 < TIMES*100; y1++) {
133       t_start();
134       t1 = t_read();
135       t2 = (t_read() - t1)>>1;
136 
137       c1 = (t1 > c1) ? t1 : c1;
138       c2 = (t2 > c2) ? t2 : c2;
139    }
140    skew = c2 - c1;
141    fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew);
142 }
143 
time_keysched(void)144 static void time_keysched(void)
145 {
146   unsigned long x, y1;
147   ulong64 t1, c1;
148   symmetric_key skey;
149   int kl;
150   int    (*func) (const unsigned char *, int , int , symmetric_key *);
151   unsigned char key[MAXBLOCKSIZE];
152 
153   fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
154   no_results = 0;
155  for (x = 0; cipher_descriptor[x].name != NULL; x++) {
156 #define DO1(k)   func(k, kl, 0, &skey);
157 
158     func = cipher_descriptor[x].setup;
159     kl   = cipher_descriptor[x].min_key_length;
160     c1 = (ulong64)-1;
161     for (y1 = 0; y1 < KTIMES; y1++) {
162        yarrow_read(key, kl, &yarrow_prng);
163        t_start();
164        DO1(key);
165        t1 = t_read();
166        c1 = (t1 > c1) ? c1 : t1;
167     }
168     t1 = c1 - skew;
169     results[no_results].spd1 = results[no_results].avg = t1;
170     results[no_results++].id = x;
171     fprintf(stderr, "."); fflush(stdout);
172 
173 #undef DO1
174    }
175    tally_results(0);
176 }
177 
178 #ifdef LTC_ECB_MODE
time_cipher_ecb(void)179 static void time_cipher_ecb(void)
180 {
181   unsigned long x, y1;
182   ulong64  t1, t2, c1, c2, a1, a2;
183   symmetric_ECB ecb;
184   unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
185   int err;
186 
187   fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n");
188   no_results = 0;
189   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
190     ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb);
191 
192     /* sanity check on cipher */
193     if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
194        fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
195        exit(EXIT_FAILURE);
196     }
197 
198 #define DO1   ecb_encrypt(pt, pt, sizeof(pt), &ecb);
199 #define DO2   DO1 DO1
200 
201     c1 = c2 = (ulong64)-1;
202     for (y1 = 0; y1 < 100; y1++) {
203         t_start();
204         DO1;
205         t1 = t_read();
206         DO2;
207         t2 = t_read();
208         t2 -= t1;
209 
210         c1 = (t1 > c1 ? c1 : t1);
211         c2 = (t2 > c2 ? c2 : t2);
212     }
213     a1 = c2 - c1 - skew;
214 
215 #undef DO1
216 #undef DO2
217 #define DO1   ecb_decrypt(pt, pt, sizeof(pt), &ecb);
218 #define DO2   DO1 DO1
219 
220     c1 = c2 = (ulong64)-1;
221     for (y1 = 0; y1 < 100; y1++) {
222         t_start();
223         DO1;
224         t1 = t_read();
225         DO2;
226         t2 = t_read();
227         t2 -= t1;
228 
229         c1 = (t1 > c1 ? c1 : t1);
230         c2 = (t2 > c2 ? c2 : t2);
231     }
232     a2 = c2 - c1 - skew;
233     ecb_done(&ecb);
234 
235     results[no_results].id = x;
236     results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
237     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
238     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
239     ++no_results;
240     fprintf(stderr, "."); fflush(stdout);
241 
242 #undef DO2
243 #undef DO1
244    }
245    tally_results(1);
246 }
247 #else
time_cipher_ecb(void)248 static void time_cipher_ecb(void) { fprintf(stderr, "NO ECB\n"); return 0; }
249 #endif
250 
251 #ifdef LTC_CBC_MODE
time_cipher_cbc(void)252 static void time_cipher_cbc(void)
253 {
254   unsigned long x, y1;
255   ulong64  t1, t2, c1, c2, a1, a2;
256   symmetric_CBC cbc;
257   unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
258   int err;
259 
260   fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n");
261   no_results = 0;
262   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
263     cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc);
264 
265     /* sanity check on cipher */
266     if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
267        fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
268        exit(EXIT_FAILURE);
269     }
270 
271 #define DO1   cbc_encrypt(pt, pt, sizeof(pt), &cbc);
272 #define DO2   DO1 DO1
273 
274     c1 = c2 = (ulong64)-1;
275     for (y1 = 0; y1 < 100; y1++) {
276         t_start();
277         DO1;
278         t1 = t_read();
279         DO2;
280         t2 = t_read();
281         t2 -= t1;
282 
283         c1 = (t1 > c1 ? c1 : t1);
284         c2 = (t2 > c2 ? c2 : t2);
285     }
286     a1 = c2 - c1 - skew;
287 
288 #undef DO1
289 #undef DO2
290 #define DO1   cbc_decrypt(pt, pt, sizeof(pt), &cbc);
291 #define DO2   DO1 DO1
292 
293     c1 = c2 = (ulong64)-1;
294     for (y1 = 0; y1 < 100; y1++) {
295         t_start();
296         DO1;
297         t1 = t_read();
298         DO2;
299         t2 = t_read();
300         t2 -= t1;
301 
302         c1 = (t1 > c1 ? c1 : t1);
303         c2 = (t2 > c2 ? c2 : t2);
304     }
305     a2 = c2 - c1 - skew;
306     cbc_done(&cbc);
307 
308     results[no_results].id = x;
309     results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
310     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
311     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
312     ++no_results;
313     fprintf(stderr, "."); fflush(stdout);
314 
315 #undef DO2
316 #undef DO1
317    }
318    tally_results(1);
319 }
320 #else
time_cipher_cbc(void)321 static void time_cipher_cbc(void) { fprintf(stderr, "NO CBC\n"); return 0; }
322 #endif
323 
324 #ifdef LTC_CTR_MODE
time_cipher_ctr(void)325 static void time_cipher_ctr(void)
326 {
327   unsigned long x, y1;
328   ulong64  t1, t2, c1, c2, a1, a2;
329   symmetric_CTR ctr;
330   unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
331   int err;
332 
333   fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n");
334   no_results = 0;
335   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
336     ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr);
337 
338     /* sanity check on cipher */
339     if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
340        fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
341        exit(EXIT_FAILURE);
342     }
343 
344 #define DO1   ctr_encrypt(pt, pt, sizeof(pt), &ctr);
345 #define DO2   DO1 DO1
346 
347     c1 = c2 = (ulong64)-1;
348     for (y1 = 0; y1 < 100; y1++) {
349         t_start();
350         DO1;
351         t1 = t_read();
352         DO2;
353         t2 = t_read();
354         t2 -= t1;
355 
356         c1 = (t1 > c1 ? c1 : t1);
357         c2 = (t2 > c2 ? c2 : t2);
358     }
359     a1 = c2 - c1 - skew;
360 
361 #undef DO1
362 #undef DO2
363 #define DO1   ctr_decrypt(pt, pt, sizeof(pt), &ctr);
364 #define DO2   DO1 DO1
365 
366     c1 = c2 = (ulong64)-1;
367     for (y1 = 0; y1 < 100; y1++) {
368         t_start();
369         DO1;
370         t1 = t_read();
371         DO2;
372         t2 = t_read();
373         t2 -= t1;
374 
375         c1 = (t1 > c1 ? c1 : t1);
376         c2 = (t2 > c2 ? c2 : t2);
377     }
378     a2 = c2 - c1 - skew;
379     ctr_done(&ctr);
380 
381     results[no_results].id = x;
382     results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
383     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
384     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
385     ++no_results;
386     fprintf(stderr, "."); fflush(stdout);
387 
388 #undef DO2
389 #undef DO1
390    }
391    tally_results(1);
392 }
393 #else
time_cipher_ctr(void)394 static void time_cipher_ctr(void) { fprintf(stderr, "NO CTR\n"); return 0; }
395 #endif
396 
397 #ifdef LTC_LRW_MODE
time_cipher_lrw(void)398 static void time_cipher_lrw(void)
399 {
400   unsigned long x, y1;
401   ulong64  t1, t2, c1, c2, a1, a2;
402   symmetric_LRW lrw;
403   unsigned char key[MAXBLOCKSIZE] = { 0 }, pt[4096] = { 0 };
404   int err;
405 
406   fprintf(stderr, "\n\nLRW Time Trials for the Symmetric Ciphers:\n");
407   no_results = 0;
408   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
409     if (cipher_descriptor[x].block_length != 16) continue;
410     lrw_start(x, pt, key, cipher_descriptor[x].min_key_length, key, 0, &lrw);
411 
412     /* sanity check on cipher */
413     if ((err = cipher_descriptor[x].test()) != CRYPT_OK) {
414        fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err));
415        exit(EXIT_FAILURE);
416     }
417 
418 #define DO1   lrw_encrypt(pt, pt, sizeof(pt), &lrw);
419 #define DO2   DO1 DO1
420 
421     c1 = c2 = (ulong64)-1;
422     for (y1 = 0; y1 < 100; y1++) {
423         t_start();
424         DO1;
425         t1 = t_read();
426         DO2;
427         t2 = t_read();
428         t2 -= t1;
429 
430         c1 = (t1 > c1 ? c1 : t1);
431         c2 = (t2 > c2 ? c2 : t2);
432     }
433     a1 = c2 - c1 - skew;
434 
435 #undef DO1
436 #undef DO2
437 #define DO1   lrw_decrypt(pt, pt, sizeof(pt), &lrw);
438 #define DO2   DO1 DO1
439 
440     c1 = c2 = (ulong64)-1;
441     for (y1 = 0; y1 < 100; y1++) {
442         t_start();
443         DO1;
444         t1 = t_read();
445         DO2;
446         t2 = t_read();
447         t2 -= t1;
448 
449         c1 = (t1 > c1 ? c1 : t1);
450         c2 = (t2 > c2 ? c2 : t2);
451     }
452     a2 = c2 - c1 - skew;
453 
454     lrw_done(&lrw);
455 
456     results[no_results].id = x;
457     results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length);
458     results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length);
459     results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
460     ++no_results;
461     fprintf(stderr, "."); fflush(stdout);
462 
463 #undef DO2
464 #undef DO1
465    }
466    tally_results(1);
467 }
468 #else
time_cipher_lrw(void)469 static void time_cipher_lrw(void) { fprintf(stderr, "NO LRW\n"); }
470 #endif
471 
472 
time_hash(void)473 static void time_hash(void)
474 {
475   unsigned long x, y1, len;
476   ulong64 t1, t2, c1, c2;
477   hash_state md;
478   int    (*func)(hash_state *, const unsigned char *, unsigned long), err;
479   unsigned char pt[MAXBLOCKSIZE] = { 0 };
480 
481 
482   fprintf(stderr, "\n\nHASH Time Trials for:\n");
483   no_results = 0;
484   for (x = 0; hash_descriptor[x].name != NULL; x++) {
485 
486     /* sanity check on hash */
487     if ((err = hash_descriptor[x].test()) != CRYPT_OK) {
488        fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err));
489        exit(EXIT_FAILURE);
490     }
491 
492     hash_descriptor[x].init(&md);
493 
494 #define DO1   func(&md,pt,len);
495 #define DO2   DO1 DO1
496 
497     func = hash_descriptor[x].process;
498     len  = hash_descriptor[x].blocksize;
499 
500     c1 = c2 = (ulong64)-1;
501     for (y1 = 0; y1 < TIMES; y1++) {
502        t_start();
503        DO1;
504        t1 = t_read();
505        DO2;
506        t2 = t_read() - t1;
507        c1 = (t1 > c1) ? c1 : t1;
508        c2 = (t2 > c2) ? c2 : t2;
509     }
510     t1 = c2 - c1 - skew;
511     t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize);
512     results[no_results].id = x;
513     results[no_results].spd1 = results[no_results].avg = t1;
514     ++no_results;
515     fprintf(stderr, "."); fflush(stdout);
516 #undef DO2
517 #undef DO1
518    }
519    tally_results(2);
520 }
521 
522 /*#warning you need an mp_rand!!!*/
523 #if !defined(USE_LTM) && !defined(USE_TFM) && !defined(USE_GMP) && !defined(EXT_MATH_LIB)
524   #undef LTC_MPI
525   #undef LTC_TEST_MPI
526 #else
527   #define LTC_TEST_MPI
528 #endif
529 
530 #ifdef LTC_MPI
time_mult(void)531 static void time_mult(void)
532 {
533    ulong64 t1, t2;
534    unsigned long x, y;
535    void  *a, *b, *c;
536 
537    fprintf(stderr, "Timing Multiplying:\n");
538    mp_init_multi(&a,&b,&c,NULL);
539    for (x = 128/MP_DIGIT_BIT; x <= (unsigned long)1536/MP_DIGIT_BIT; x += 128/MP_DIGIT_BIT) {
540        mp_rand(a, x);
541        mp_rand(b, x);
542 
543 #define DO1 mp_mul(a, b, c);
544 #define DO2 DO1; DO1;
545 
546        t2 = -1;
547        for (y = 0; y < TIMES; y++) {
548            t_start();
549            t1 = t_read();
550            DO2;
551            t1 = (t_read() - t1)>>1;
552            if (t1 < t2) t2 = t1;
553        }
554        fprintf(stderr, "%4lu bits: %9"PRI64"u cycles\n", x*MP_DIGIT_BIT, t2);
555    }
556    mp_clear_multi(a,b,c,NULL);
557 
558 #undef DO1
559 #undef DO2
560 }
561 
time_sqr(void)562 static void time_sqr(void)
563 {
564    ulong64 t1, t2;
565    unsigned long x, y;
566    void *a, *b;
567 
568    fprintf(stderr, "Timing Squaring:\n");
569    mp_init_multi(&a,&b,NULL);
570    for (x = 128/MP_DIGIT_BIT; x <= (unsigned long)1536/MP_DIGIT_BIT; x += 128/MP_DIGIT_BIT) {
571        mp_rand(a, x);
572 
573 #define DO1 mp_sqr(a, b);
574 #define DO2 DO1; DO1;
575 
576        t2 = -1;
577        for (y = 0; y < TIMES; y++) {
578            t_start();
579            t1 = t_read();
580            DO2;
581            t1 = (t_read() - t1)>>1;
582            if (t1 < t2) t2 = t1;
583        }
584        fprintf(stderr, "%4lu bits: %9"PRI64"u cycles\n", x*MP_DIGIT_BIT, t2);
585    }
586    mp_clear_multi(a,b,NULL);
587 
588 #undef DO1
589 #undef DO2
590 }
591 #else
time_mult(void)592 static void time_mult(void) { fprintf(stderr, "NO MULT\n"); }
time_sqr(void)593 static void time_sqr(void) { fprintf(stderr, "NO SQR\n"); }
594 #endif
595 
time_prng(void)596 static void time_prng(void)
597 {
598    ulong64 t1, t2;
599    unsigned char buf[4096];
600    prng_state tprng;
601    unsigned long x, y;
602    int           err;
603 
604    fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n");
605    for (x = 0; prng_descriptor[x].name != NULL; x++) {
606 
607       /* sanity check on prng */
608       if ((err = prng_descriptor[x].test()) != CRYPT_OK) {
609          fprintf(stderr, "\n\nERROR: PRNG %s failed self-test %s\n", prng_descriptor[x].name, error_to_string(err));
610          exit(EXIT_FAILURE);
611       }
612 
613       prng_descriptor[x].start(&tprng);
614       zeromem(buf, 256);
615       prng_descriptor[x].add_entropy(buf, 256, &tprng);
616       prng_descriptor[x].ready(&tprng);
617       t2 = -1;
618 
619 #define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); }
620 #define DO2 DO1 DO1
621       for (y = 0; y < 10000; y++) {
622          t_start();
623          t1 = t_read();
624          DO2;
625          t1 = (t_read() - t1)>>1;
626          if (t1 < t2) t2 = t1;
627       }
628       fprintf(stderr, "%20s: %5"PRI64"u ", prng_descriptor[x].name, t2>>12);
629 #undef DO2
630 #undef DO1
631 
632 #define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng);
633 #define DO2 DO1 DO1
634       for (y = 0; y < 10000; y++) {
635          t_start();
636          t1 = t_read();
637          DO2;
638          t1 = (t_read() - t1)>>1;
639          if (t1 < t2) t2 = t1;
640       }
641       fprintf(stderr, "%5"PRI64"u\n", t2);
642 #undef DO2
643 #undef DO1
644 
645    }
646 }
647 
648 #if defined(LTC_MDSA) && defined(LTC_TEST_MPI)
649 /* time various DSA operations */
time_dsa(void)650 static void time_dsa(void)
651 {
652    dsa_key       key;
653    ulong64       t1, t2;
654    unsigned long x, y;
655    int           err;
656 static const struct {
657    int group, modulus;
658 } groups[] = {
659 { 20, 96  },
660 { 20, 128 },
661 { 24, 192 },
662 { 28, 256 },
663 #ifndef TFM_DESC
664 { 32, 512 },
665 #endif
666 };
667 
668    for (x = 0; x < (sizeof(groups)/sizeof(groups[0])); x++) {
669        t2 = 0;
670        for (y = 0; y < 4; y++) {
671            t_start();
672            t1 = t_read();
673            if ((err = dsa_generate_pqg(&yarrow_prng, find_prng("yarrow"), groups[x].group, groups[x].modulus, &key)) != CRYPT_OK) {
674               fprintf(stderr, "\n\ndsa_generate_pqg says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
675               exit(EXIT_FAILURE);
676            }
677            if ((err = dsa_generate_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
678               fprintf(stderr, "\n\ndsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
679               exit(EXIT_FAILURE);
680            }
681            t1 = t_read() - t1;
682            t2 += t1;
683 
684 #ifdef LTC_PROFILE
685        t2 <<= 2;
686        break;
687 #endif
688            if (y < 3) {
689               dsa_free(&key);
690            }
691        }
692        t2 >>= 2;
693        fprintf(stderr, "DSA-(%lu, %lu) make_key    took %15"PRI64"u cycles\n", (unsigned long)groups[x].group*8, (unsigned long)groups[x].modulus*8, t2);
694        dsa_free(&key);
695    }
696    fprintf(stderr, "\n\n");
697 }
698 #else
time_dsa(void)699 static void time_dsa(void) { fprintf(stderr, "NO DSA\n"); }
700 #endif
701 
702 
703 #if defined(LTC_MRSA) && defined(LTC_TEST_MPI)
704 /* time various RSA operations */
time_rsa(void)705 static void time_rsa(void)
706 {
707    rsa_key       key;
708    ulong64       t1, t2;
709    unsigned char buf[2][2048] = { 0 };
710    unsigned long x, y, z, zzz;
711    int           err, zz, stat;
712 
713    for (x = 1024; x <= 2048; x += 256) {
714        t2 = 0;
715        for (y = 0; y < 4; y++) {
716            t_start();
717            t1 = t_read();
718            if ((err = rsa_make_key(&yarrow_prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) {
719               fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
720               exit(EXIT_FAILURE);
721            }
722            t1 = t_read() - t1;
723            t2 += t1;
724 
725 #ifdef LTC_PROFILE
726        t2 <<= 2;
727        break;
728 #endif
729 
730            if (y < 3) {
731               rsa_free(&key);
732            }
733        }
734        t2 >>= 2;
735        fprintf(stderr, "RSA-%lu make_key    took %15"PRI64"u cycles\n", x, t2);
736 
737        t2 = 0;
738        for (y = 0; y < 16; y++) {
739            t_start();
740            t1 = t_read();
741            z = sizeof(buf[1]);
742            if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng,
743                                       find_prng("yarrow"), find_hash("sha1"),
744                                       &key)) != CRYPT_OK) {
745               fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
746               exit(EXIT_FAILURE);
747            }
748            t1 = t_read() - t1;
749            t2 += t1;
750 #ifdef LTC_PROFILE
751        t2 <<= 4;
752        break;
753 #endif
754        }
755        t2 >>= 4;
756        fprintf(stderr, "RSA-%lu encrypt_key took %15"PRI64"u cycles\n", x, t2);
757 
758        t2 = 0;
759        for (y = 0; y < 2048; y++) {
760            t_start();
761            t1 = t_read();
762            zzz = sizeof(buf[0]);
763            if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8,  find_hash("sha1"),
764                                       &zz, &key)) != CRYPT_OK) {
765               fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
766               exit(EXIT_FAILURE);
767            }
768            t1 = t_read() - t1;
769            t2 += t1;
770 #ifdef LTC_PROFILE
771        t2 <<= 11;
772        break;
773 #endif
774        }
775        t2 >>= 11;
776        fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);
777 
778        t2 = 0;
779        for (y = 0; y < 256; y++) {
780           t_start();
781           t1 = t_read();
782           z = sizeof(buf[1]);
783           if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
784                                    find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) {
785               fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
786               exit(EXIT_FAILURE);
787            }
788            t1 = t_read() - t1;
789            t2 += t1;
790 #ifdef LTC_PROFILE
791        t2 <<= 8;
792        break;
793 #endif
794         }
795         t2 >>= 8;
796         fprintf(stderr, "RSA-%lu sign_hash took   %15"PRI64"u cycles\n", x, t2);
797 
798        t2 = 0;
799        for (y = 0; y < 2048; y++) {
800           t_start();
801           t1 = t_read();
802           if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) {
803               fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
804               exit(EXIT_FAILURE);
805           }
806           if (stat == 0) {
807              fprintf(stderr, "\n\nrsa_verify_hash for RSA-%lu failed to verify signature(%lu)\n", x, y);
808              exit(EXIT_FAILURE);
809           }
810           t1 = t_read() - t1;
811           t2 += t1;
812 #ifdef LTC_PROFILE
813        t2 <<= 11;
814        break;
815 #endif
816         }
817         t2 >>= 11;
818         fprintf(stderr, "RSA-%lu verify_hash took %15"PRI64"u cycles\n", x, t2);
819        fprintf(stderr, "\n\n");
820        rsa_free(&key);
821   }
822 }
823 #else
time_rsa(void)824 static void time_rsa(void) { fprintf(stderr, "NO RSA\n"); }
825 #endif
826 
827 #if defined(LTC_MKAT) && defined(LTC_TEST_MPI)
828 /* time various KAT operations */
time_katja(void)829 static void time_katja(void)
830 {
831    katja_key key;
832    ulong64 t1, t2;
833    unsigned char buf[2][4096];
834    unsigned long x, y, z, zzz;
835    int           err, zz;
836 
837    for (x = 1024; x <= 2048; x += 256) {
838        t2 = 0;
839        for (y = 0; y < 4; y++) {
840            t_start();
841            t1 = t_read();
842            if ((err = katja_make_key(&yarrow_prng, find_prng("yarrow"), x/8, &key)) != CRYPT_OK) {
843               fprintf(stderr, "\n\nkatja_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
844               exit(EXIT_FAILURE);
845            }
846            t1 = t_read() - t1;
847            t2 += t1;
848 
849            if (y < 3) {
850               katja_free(&key);
851            }
852        }
853        t2 >>= 2;
854        fprintf(stderr, "Katja-%lu make_key    took %15"PRI64"u cycles\n", x, t2);
855 
856        t2 = 0;
857        for (y = 0; y < 16; y++) {
858            t_start();
859            t1 = t_read();
860            z = sizeof(buf[1]);
861            if ((err = katja_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng,
862                                       find_prng("yarrow"), find_hash("sha1"),
863                                       &key)) != CRYPT_OK) {
864               fprintf(stderr, "\n\nkatja_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
865               exit(EXIT_FAILURE);
866            }
867            t1 = t_read() - t1;
868            t2 += t1;
869        }
870        t2 >>= 4;
871        fprintf(stderr, "Katja-%lu encrypt_key took %15"PRI64"u cycles\n", x, t2);
872 
873        t2 = 0;
874        for (y = 0; y < 2048; y++) {
875            t_start();
876            t1 = t_read();
877            zzz = sizeof(buf[0]);
878            if ((err = katja_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8,  find_hash("sha1"),
879                                       &zz, &key)) != CRYPT_OK) {
880               fprintf(stderr, "\n\nkatja_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
881               exit(EXIT_FAILURE);
882            }
883            t1 = t_read() - t1;
884            t2 += t1;
885        }
886        t2 >>= 11;
887        fprintf(stderr, "Katja-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);
888 
889 
890        katja_free(&key);
891   }
892 }
893 #else
time_katja(void)894 static void time_katja(void) { fprintf(stderr, "NO Katja\n"); }
895 #endif
896 
897 #if defined(LTC_MDH) && defined(LTC_TEST_MPI)
898 /* time various DH operations */
time_dh(void)899 static void time_dh(void)
900 {
901    dh_key key;
902    ulong64 t1, t2;
903    unsigned long i, x, y;
904    int           err;
905    static unsigned long sizes[] = {768/8, 1024/8, 1536/8, 2048/8,
906 #ifndef TFM_DESC
907                                    3072/8, 4096/8, 6144/8, 8192/8,
908 #endif
909                                    100000
910    };
911 
912    for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
913        t2 = 0;
914        for (y = 0; y < 16; y++) {
915            if((err = dh_set_pg_groupsize(x, &key)) != CRYPT_OK) {
916               fprintf(stderr, "\n\ndh_set_pg_groupsize says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
917               exit(EXIT_FAILURE);
918            }
919 
920            t_start();
921            t1 = t_read();
922            if ((err = dh_generate_key(&yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) {
923               fprintf(stderr, "\n\ndh_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
924               exit(EXIT_FAILURE);
925            }
926            t1 = t_read() - t1;
927            t2 += t1;
928 
929            dh_free(&key);
930        }
931        t2 >>= 4;
932        fprintf(stderr, "DH-%4lu make_key    took %15"PRI64"u cycles\n", x*8, t2);
933   }
934 }
935 #else
time_dh(void)936 static void time_dh(void) { fprintf(stderr, "NO DH\n"); }
937 #endif
938 
939 #if defined(LTC_MECC) && defined(LTC_TEST_MPI)
940 /* time various ECC operations */
time_ecc(void)941 static void time_ecc(void)
942 {
943    ecc_key key;
944    ulong64 t1, t2;
945    unsigned char buf[2][256] = { 0 };
946    unsigned long i, w, x, y, z;
947    int           err, stat;
948    static unsigned long sizes[] = {
949 #ifdef LTC_ECC112
950 112/8,
951 #endif
952 #ifdef LTC_ECC128
953 128/8,
954 #endif
955 #ifdef LTC_ECC160
956 160/8,
957 #endif
958 #ifdef LTC_ECC192
959 192/8,
960 #endif
961 #ifdef LTC_ECC224
962 224/8,
963 #endif
964 #ifdef LTC_ECC256
965 256/8,
966 #endif
967 #ifdef LTC_ECC384
968 384/8,
969 #endif
970 #ifdef LTC_ECC521
971 521/8,
972 #endif
973 100000};
974 
975    for (x = sizes[i=0]; x < 100000; x = sizes[++i]) {
976        t2 = 0;
977        for (y = 0; y < 256; y++) {
978            t_start();
979            t1 = t_read();
980            if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) {
981               fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
982               exit(EXIT_FAILURE);
983            }
984            t1 = t_read() - t1;
985            t2 += t1;
986 
987 #ifdef LTC_PROFILE
988        t2 <<= 8;
989        break;
990 #endif
991 
992            if (y < 255) {
993               ecc_free(&key);
994            }
995        }
996        t2 >>= 8;
997        fprintf(stderr, "ECC-%lu make_key    took %15"PRI64"u cycles\n", x*8, t2);
998 
999        t2 = 0;
1000        for (y = 0; y < 256; y++) {
1001            t_start();
1002            t1 = t_read();
1003            z = sizeof(buf[1]);
1004            if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"),
1005                                       &key)) != CRYPT_OK) {
1006               fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
1007               exit(EXIT_FAILURE);
1008            }
1009            t1 = t_read() - t1;
1010            t2 += t1;
1011 #ifdef LTC_PROFILE
1012        t2 <<= 8;
1013        break;
1014 #endif
1015        }
1016        t2 >>= 8;
1017        fprintf(stderr, "ECC-%lu encrypt_key took %15"PRI64"u cycles\n", x*8, t2);
1018 
1019        t2 = 0;
1020        for (y = 0; y < 256; y++) {
1021            t_start();
1022            t1 = t_read();
1023            w = 20;
1024            if ((err = ecc_decrypt_key(buf[1], z, buf[0], &w, &key)) != CRYPT_OK) {
1025               fprintf(stderr, "\n\necc_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
1026               exit(EXIT_FAILURE);
1027            }
1028            t1 = t_read() - t1;
1029            t2 += t1;
1030 #ifdef LTC_PROFILE
1031        t2 <<= 8;
1032        break;
1033 #endif
1034        }
1035        t2 >>= 8;
1036        fprintf(stderr, "ECC-%lu decrypt_key took %15"PRI64"u cycles\n", x*8, t2);
1037 
1038        t2 = 0;
1039        for (y = 0; y < 256; y++) {
1040           t_start();
1041           t1 = t_read();
1042           z = sizeof(buf[1]);
1043           if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
1044                                    find_prng("yarrow"), &key)) != CRYPT_OK) {
1045               fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
1046               exit(EXIT_FAILURE);
1047            }
1048            t1 = t_read() - t1;
1049            t2 += t1;
1050 #ifdef LTC_PROFILE
1051        t2 <<= 8;
1052        break;
1053 #endif
1054         }
1055         t2 >>= 8;
1056         fprintf(stderr, "ECC-%lu sign_hash took   %15"PRI64"u cycles\n", x*8, t2);
1057 
1058        t2 = 0;
1059        for (y = 0; y < 256; y++) {
1060           t_start();
1061           t1 = t_read();
1062           if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) {
1063               fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
1064               exit(EXIT_FAILURE);
1065           }
1066           if (stat == 0) {
1067              fprintf(stderr, "\n\necc_verify_hash for ECC-%lu failed to verify signature(%lu)\n", x*8, y);
1068              exit(EXIT_FAILURE);
1069           }
1070           t1 = t_read() - t1;
1071           t2 += t1;
1072 #ifdef LTC_PROFILE
1073        t2 <<= 8;
1074        break;
1075 #endif
1076         }
1077         t2 >>= 8;
1078         fprintf(stderr, "ECC-%lu verify_hash took %15"PRI64"u cycles\n", x*8, t2);
1079 
1080        fprintf(stderr, "\n\n");
1081        ecc_free(&key);
1082   }
1083 }
1084 #else
time_ecc(void)1085 static void time_ecc(void) { fprintf(stderr, "NO ECC\n"); }
1086 #endif
1087 
time_macs_(unsigned long MAC_SIZE)1088 static void time_macs_(unsigned long MAC_SIZE)
1089 {
1090 #if defined(LTC_OMAC) || defined(LTC_XCBC) || defined(LTC_F9_MODE) || defined(LTC_PMAC) || defined(LTC_PELICAN) || defined(LTC_HMAC)
1091    unsigned char *buf, key[16], tag[16];
1092    ulong64 t1, t2;
1093    unsigned long x, z;
1094    int err, cipher_idx, hash_idx;
1095 
1096    fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE);
1097 
1098    buf = XMALLOC(MAC_SIZE*1024);
1099    if (buf == NULL) {
1100       fprintf(stderr, "\n\nout of heap yo\n\n");
1101       exit(EXIT_FAILURE);
1102    }
1103 
1104    cipher_idx = find_cipher("aes");
1105    hash_idx   = find_hash("sha1");
1106 
1107    if (cipher_idx == -1 || hash_idx == -1) {
1108       fprintf(stderr, "Warning the MAC tests requires AES and SHA1 to operate... so sorry\n");
1109       exit(EXIT_FAILURE);
1110    }
1111 
1112    yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng);
1113    yarrow_read(key, 16, &yarrow_prng);
1114 
1115 #ifdef LTC_OMAC
1116    t2 = -1;
1117    for (x = 0; x < 10000; x++) {
1118         t_start();
1119         t1 = t_read();
1120         z = 16;
1121         if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
1122            fprintf(stderr, "\n\nomac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
1123            exit(EXIT_FAILURE);
1124         }
1125         t1 = t_read() - t1;
1126         if (t1 < t2) t2 = t1;
1127    }
1128    fprintf(stderr, "OMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
1129 #endif
1130 
1131 #ifdef LTC_XCBC
1132    t2 = -1;
1133    for (x = 0; x < 10000; x++) {
1134         t_start();
1135         t1 = t_read();
1136         z = 16;
1137         if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
1138            fprintf(stderr, "\n\nxcbc-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
1139            exit(EXIT_FAILURE);
1140         }
1141         t1 = t_read() - t1;
1142         if (t1 < t2) t2 = t1;
1143    }
1144    fprintf(stderr, "XCBC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
1145 #endif
1146 
1147 #ifdef LTC_F9_MODE
1148    t2 = -1;
1149    for (x = 0; x < 10000; x++) {
1150         t_start();
1151         t1 = t_read();
1152         z = 16;
1153         if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
1154            fprintf(stderr, "\n\nF9-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
1155            exit(EXIT_FAILURE);
1156         }
1157         t1 = t_read() - t1;
1158         if (t1 < t2) t2 = t1;
1159    }
1160    fprintf(stderr, "F9-%s\t\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
1161 #endif
1162 
1163 #ifdef LTC_PMAC
1164    t2 = -1;
1165    for (x = 0; x < 10000; x++) {
1166         t_start();
1167         t1 = t_read();
1168         z = 16;
1169         if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
1170            fprintf(stderr, "\n\npmac-%s error... %s\n", cipher_descriptor[cipher_idx].name, error_to_string(err));
1171            exit(EXIT_FAILURE);
1172         }
1173         t1 = t_read() - t1;
1174         if (t1 < t2) t2 = t1;
1175    }
1176    fprintf(stderr, "PMAC-%s\t\t%9"PRI64"u\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024));
1177 #endif
1178 
1179 #ifdef LTC_PELICAN
1180    t2 = -1;
1181    for (x = 0; x < 10000; x++) {
1182         t_start();
1183         t1 = t_read();
1184         z = 16;
1185         if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) {
1186            fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err));
1187            exit(EXIT_FAILURE);
1188         }
1189         t1 = t_read() - t1;
1190         if (t1 < t2) t2 = t1;
1191    }
1192    fprintf(stderr, "PELICAN \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1193 #endif
1194 
1195 #ifdef LTC_HMAC
1196    t2 = -1;
1197    for (x = 0; x < 10000; x++) {
1198         t_start();
1199         t1 = t_read();
1200         z = 16;
1201         if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) {
1202            fprintf(stderr, "\n\nhmac-%s error... %s\n", hash_descriptor[hash_idx].name, error_to_string(err));
1203            exit(EXIT_FAILURE);
1204         }
1205         t1 = t_read() - t1;
1206         if (t1 < t2) t2 = t1;
1207    }
1208    fprintf(stderr, "HMAC-%s\t\t%9"PRI64"u\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024));
1209 #endif
1210 
1211    XFREE(buf);
1212 #else
1213    LTC_UNUSED_PARAM(MAC_SIZE);
1214    fprintf(stderr, "NO MACs\n");
1215 #endif
1216 }
1217 
time_macs(void)1218 static void time_macs(void)
1219 {
1220    time_macs_(1);
1221    time_macs_(4);
1222    time_macs_(32);
1223 }
1224 
time_encmacs_(unsigned long MAC_SIZE)1225 static void time_encmacs_(unsigned long MAC_SIZE)
1226 {
1227 #if defined(LTC_EAX_MODE) || defined(LTC_OCB_MODE) || defined(LTC_OCB3_MODE) || defined(LTC_CCM_MODE) || defined(LTC_GCM_MODE)
1228    unsigned char *buf, IV[16], key[16], tag[16];
1229    ulong64 t1, t2;
1230    unsigned long x, z;
1231    int err, cipher_idx;
1232    symmetric_key skey;
1233 
1234    fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE);
1235 
1236    buf = XMALLOC(MAC_SIZE*1024);
1237    if (buf == NULL) {
1238       fprintf(stderr, "\n\nout of heap yo\n\n");
1239       exit(EXIT_FAILURE);
1240    }
1241 
1242    cipher_idx = find_cipher("aes");
1243 
1244    yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng);
1245    yarrow_read(key, 16, &yarrow_prng);
1246    yarrow_read(IV, 16, &yarrow_prng);
1247 
1248 #ifdef LTC_EAX_MODE
1249    t2 = -1;
1250    for (x = 0; x < 10000; x++) {
1251         t_start();
1252         t1 = t_read();
1253         z = 16;
1254         if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
1255            fprintf(stderr, "\nEAX error... %s\n", error_to_string(err));
1256            exit(EXIT_FAILURE);
1257         }
1258         t1 = t_read() - t1;
1259         if (t1 < t2) t2 = t1;
1260    }
1261    fprintf(stderr, "EAX \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1262 #endif
1263 
1264 #ifdef LTC_OCB_MODE
1265    t2 = -1;
1266    for (x = 0; x < 10000; x++) {
1267         t_start();
1268         t1 = t_read();
1269         z = 16;
1270         if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
1271            fprintf(stderr, "\nOCB error... %s\n", error_to_string(err));
1272            exit(EXIT_FAILURE);
1273         }
1274         t1 = t_read() - t1;
1275         if (t1 < t2) t2 = t1;
1276    }
1277    fprintf(stderr, "OCB \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1278 #endif
1279 
1280 #ifdef LTC_OCB3_MODE
1281    t2 = -1;
1282    for (x = 0; x < 10000; x++) {
1283         t_start();
1284         t1 = t_read();
1285         z = 16;
1286         if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 15, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
1287            fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err));
1288            exit(EXIT_FAILURE);
1289         }
1290         t1 = t_read() - t1;
1291         if (t1 < t2) t2 = t1;
1292    }
1293    fprintf(stderr, "OCB3 \t\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1294 #endif
1295 
1296 #ifdef LTC_CCM_MODE
1297    t2 = -1;
1298    for (x = 0; x < 10000; x++) {
1299         t_start();
1300         t1 = t_read();
1301         z = 16;
1302         if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
1303            fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
1304            exit(EXIT_FAILURE);
1305         }
1306         t1 = t_read() - t1;
1307         if (t1 < t2) t2 = t1;
1308    }
1309    fprintf(stderr, "CCM (no-precomp) \t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1310 
1311    cipher_descriptor[cipher_idx].setup(key, 16, 0, &skey);
1312    t2 = -1;
1313    for (x = 0; x < 10000; x++) {
1314         t_start();
1315         t1 = t_read();
1316         z = 16;
1317         if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) {
1318            fprintf(stderr, "\nCCM error... %s\n", error_to_string(err));
1319            exit(EXIT_FAILURE);
1320         }
1321         t1 = t_read() - t1;
1322         if (t1 < t2) t2 = t1;
1323    }
1324    fprintf(stderr, "CCM (precomp) \t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1325    cipher_descriptor[cipher_idx].done(&skey);
1326 #endif
1327 
1328 #ifdef LTC_GCM_MODE
1329    t2 = -1;
1330    for (x = 0; x < 100; x++) {
1331         t_start();
1332         t1 = t_read();
1333         z = 16;
1334         if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) {
1335            fprintf(stderr, "\nGCM error... %s\n", error_to_string(err));
1336            exit(EXIT_FAILURE);
1337         }
1338         t1 = t_read() - t1;
1339         if (t1 < t2) t2 = t1;
1340    }
1341    fprintf(stderr, "GCM (no-precomp)\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1342 
1343    {
1344    gcm_state gcm
1345 #ifdef LTC_GCM_TABLES_SSE2
1346 __attribute__ ((aligned (16)))
1347 #endif
1348 ;
1349 
1350    if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); }
1351    t2 = -1;
1352    for (x = 0; x < 10000; x++) {
1353         t_start();
1354         t1 = t_read();
1355         z = 16;
1356         if ((err = gcm_reset(&gcm)) != CRYPT_OK) {
1357             fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
1358            exit(EXIT_FAILURE);
1359         }
1360         if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) {
1361             fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
1362            exit(EXIT_FAILURE);
1363         }
1364         if ((err = gcm_add_aad(&gcm, NULL, 0)) != CRYPT_OK) {
1365             fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
1366            exit(EXIT_FAILURE);
1367         }
1368         if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) {
1369             fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
1370            exit(EXIT_FAILURE);
1371         }
1372 
1373         if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) {
1374             fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err));
1375            exit(EXIT_FAILURE);
1376         }
1377         t1 = t_read() - t1;
1378         if (t1 < t2) t2 = t1;
1379    }
1380    fprintf(stderr, "GCM (precomp)\t\t%9"PRI64"u\n", t2/(ulong64)(MAC_SIZE*1024));
1381    }
1382 
1383 #endif
1384    XFREE(buf);
1385 #else
1386    LTC_UNUSED_PARAM(MAC_SIZE);
1387    fprintf(stderr, "NO ENCMACs\n");
1388 #endif
1389 
1390 }
1391 
time_encmacs(void)1392 static void time_encmacs(void)
1393 {
1394    time_encmacs_(1);
1395    time_encmacs_(4);
1396    time_encmacs_(32);
1397 }
1398 
1399 #define LTC_TEST_FN(f)  { f, #f }
main(int argc,char ** argv)1400 int main(int argc, char **argv)
1401 {
1402 int err;
1403 
1404 const struct
1405 {
1406    void (*fn)(void);
1407    const char* name;
1408 } test_functions[] = {
1409    LTC_TEST_FN(time_keysched),
1410    LTC_TEST_FN(time_cipher_ecb),
1411    LTC_TEST_FN(time_cipher_cbc),
1412    LTC_TEST_FN(time_cipher_ctr),
1413    LTC_TEST_FN(time_cipher_lrw),
1414    LTC_TEST_FN(time_hash),
1415    LTC_TEST_FN(time_macs),
1416    LTC_TEST_FN(time_encmacs),
1417    LTC_TEST_FN(time_prng),
1418    LTC_TEST_FN(time_mult),
1419    LTC_TEST_FN(time_sqr),
1420    LTC_TEST_FN(time_rsa),
1421    LTC_TEST_FN(time_dsa),
1422    LTC_TEST_FN(time_ecc),
1423    LTC_TEST_FN(time_dh),
1424    LTC_TEST_FN(time_katja)
1425 };
1426 char *single_test = NULL;
1427 unsigned int i;
1428 
1429 init_timer();
1430 register_all_ciphers();
1431 register_all_hashes();
1432 register_all_prngs();
1433 
1434 #ifdef USE_LTM
1435    ltc_mp = ltm_desc;
1436 #elif defined(USE_TFM)
1437    ltc_mp = tfm_desc;
1438 #elif defined(USE_GMP)
1439    ltc_mp = gmp_desc;
1440 #elif defined(EXT_MATH_LIB)
1441    {
1442       extern ltc_math_descriptor EXT_MATH_LIB;
1443       ltc_mp = EXT_MATH_LIB;
1444    }
1445 #endif
1446 
1447 if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) {
1448    fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err));
1449    exit(EXIT_FAILURE);
1450 }
1451 
1452 /* single test name from commandline */
1453 if (argc > 1) single_test = argv[1];
1454 
1455 for (i = 0; i < sizeof(test_functions)/sizeof(test_functions[0]); ++i) {
1456    if (single_test && strstr(test_functions[i].name, single_test) == NULL) {
1457      continue;
1458    }
1459    test_functions[i].fn();
1460 }
1461 
1462 return EXIT_SUCCESS;
1463 
1464 }
1465 
1466 /* ref:         $Format:%D$ */
1467 /* git commit:  $Format:%H$ */
1468 /* commit time: $Format:%ai$ */
1469