Better AES performance.
[libgcrypt.git] / src / global.c
1 /* global.c  -  global control functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *               2004, 2005, 2006  Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser general Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <limits.h>
30 #include <errno.h>
31
32 #include "g10lib.h"
33 #include "cipher.h"
34 #include "stdmem.h" /* our own memory allocator */
35 #include "secmem.h" /* our own secmem allocator */
36 #include "ath.h"
37
38 \f
39
40 /****************
41  * flag bits: 0 : general cipher debug
42  *            1 : general MPI debug
43  */
44 static unsigned int debug_flags;
45
46 /* Controlled by global_init().  */
47 static int any_init_done;
48
49 /* Memory management. */
50
51 static gcry_handler_alloc_t alloc_func;
52 static gcry_handler_alloc_t alloc_secure_func;
53 static gcry_handler_secure_check_t is_secure_func;
54 static gcry_handler_realloc_t realloc_func;
55 static gcry_handler_free_t free_func;
56 static gcry_handler_no_mem_t outofcore_handler;
57 static void *outofcore_handler_value;
58 static int no_secure_memory;
59
60 \f
61
62 /* This is our handmade constructor.  It gets called by any function
63    likely to be called at startup.  The suggested way for an
64    application to make sure that this has been called is by using
65    gcry_check_version. */
66 static void
67 global_init (void)
68 {
69   gcry_error_t err = 0;
70
71   if (any_init_done)
72     return;
73   any_init_done = 1;
74
75   err = ath_init ();
76   if (err)
77     goto fail;
78
79   /* Before we do any other initialization we need to test available
80      hardware features.  */
81   _gcry_detect_hw_features ();
82
83   err = _gcry_cipher_init ();
84   if (err)
85     goto fail;
86   err = _gcry_md_init ();
87   if (err)
88     goto fail;
89   err = _gcry_pk_init ();
90   if (err)
91     goto fail;
92 #if 0
93   /* FIXME? */
94   err = _gcry_ac_init ();
95   if (err)
96     goto fail;
97 #endif
98
99   return;
100
101  fail:
102   /* FIXME: use `err'?  */
103   BUG ();
104 }
105
106 \f
107
108 /* Version number parsing.  */
109
110 /* This function parses the first portion of the version number S and
111    stores it in *NUMBER.  On sucess, this function returns a pointer
112    into S starting with the first character, which is not part of the
113    initial number portion; on failure, NULL is returned.  */
114 static const char*
115 parse_version_number( const char *s, int *number )
116 {
117     int val = 0;
118
119     if( *s == '0' && isdigit(s[1]) )
120         return NULL; /* leading zeros are not allowed */
121     for ( ; isdigit(*s); s++ ) {
122         val *= 10;
123         val += *s - '0';
124     }
125     *number = val;
126     return val < 0? NULL : s;
127 }
128
129 /* This function breaks up the complete string-representation of the
130    version number S, which is of the following struture: <major
131    number>.<minor number>.<micro number><patch level>.  The major,
132    minor and micro number components will be stored in *MAJOR, *MINOR
133    and *MICRO.
134
135    On success, the last component, the patch level, will be returned;
136    in failure, NULL will be returned.  */
137
138 static const char *
139 parse_version_string( const char *s, int *major, int *minor, int *micro )
140 {
141     s = parse_version_number( s, major );
142     if( !s || *s != '.' )
143         return NULL;
144     s++;
145     s = parse_version_number( s, minor );
146     if( !s || *s != '.' )
147         return NULL;
148     s++;
149     s = parse_version_number( s, micro );
150     if( !s )
151         return NULL;
152     return s; /* patchlevel */
153 }
154
155 /* If REQ_VERSION is non-NULL, check that the version of the library
156    is at minimum the requested one.  Returns the string representation
157    of the library version if the condition is satisfied; return NULL
158    if the requested version is newer than that of the library.
159
160    If a NULL is passed to this function, no check is done, but the
161    string representation of the library is simply returned.  */
162 const char *
163 gcry_check_version( const char *req_version )
164 {
165     const char *ver = VERSION;
166     int my_major, my_minor, my_micro;
167     int rq_major, rq_minor, rq_micro;
168     const char *my_plvl, *rq_plvl;
169
170     /* Initialize library.  */
171     global_init ();
172
173     if ( !req_version )
174         /* Caller wants our version number.  */
175         return ver;
176
177     /* Parse own version number.  */
178     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
179     if ( !my_plvl )
180         /* very strange our own version is bogus.  Shouldn't we use
181            assert() here and bail out in case this happens?  -mo.  */
182         return NULL;
183
184   /* Parse requested version number.  */
185     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
186                                                                 &rq_micro );
187     if ( !rq_plvl )
188         /* req version string is invalid, this can happen.  */
189         return NULL;
190
191     /* Compare version numbers.  */
192     if ( my_major > rq_major
193         || (my_major == rq_major && my_minor > rq_minor)
194         || (my_major == rq_major && my_minor == rq_minor
195                                  && my_micro > rq_micro)
196         || (my_major == rq_major && my_minor == rq_minor
197                                  && my_micro == rq_micro
198                                  && strcmp( my_plvl, rq_plvl ) >= 0) ) {
199         return ver;
200     }
201
202     return NULL;
203 }
204
205
206 static void
207 print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
208 {
209   unsigned int hwf;
210   struct {
211     unsigned int flag;
212     const char *desc;
213   } hwflist[] = {
214     { HWF_PADLOCK_RNG, "padlock-rng" },
215     { HWF_PADLOCK_AES, "padlock-aes" },
216     { HWF_PADLOCK_SHA, "padlock-sha" },
217     { 0, NULL} 
218   };
219   int i;
220
221   fnc (fp, "version:%s:\n", VERSION);
222   fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
223   fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
224   fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
225   fnc (fp, "rnd-mod:"
226 #if USE_RNDEGD
227                 "egd:"
228 #endif
229 #if USE_RNDLINUX
230                 "linux:"
231 #endif
232 #if USE_RNDUNIX
233                 "unix:"
234 #endif
235 #if USE_RNDW32
236                 "w32:"
237 #endif
238        "\n");
239   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
240   hwf = _gcry_get_hw_features ();
241   fnc (fp, "hwflist:");
242   for (i=0; hwflist[i].desc; i++)
243   if ( (hwf & hwflist[i].flag) )
244     fnc (fp, "%s:", hwflist[i].desc);
245   fnc (fp, "\n");
246 }
247
248
249 \f
250
251 /* Command dispatcher function, acting as general control
252    function.  */
253 gcry_error_t
254 _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
255 {
256   static int init_finished = 0;
257   gcry_err_code_t err = 0;
258   
259   switch (cmd)
260     {
261     case GCRYCTL_ENABLE_M_GUARD:
262       _gcry_private_enable_m_guard ();
263       break;
264
265     case GCRYCTL_ENABLE_QUICK_RANDOM:
266       _gcry_enable_quick_random_gen ();
267       break;
268
269     case GCRYCTL_FAKED_RANDOM_P:
270       /* Return an error if the RNG is faked one (i.e. enabled by
271          ENABLE_QUICK_RANDOM. */
272       if (_gcry_random_is_faked ())
273         err = GPG_ERR_GENERAL;
274       break;
275
276     case GCRYCTL_DUMP_RANDOM_STATS:
277       _gcry_random_dump_stats ();
278       break;
279
280     case GCRYCTL_DUMP_MEMORY_STATS:
281       /*m_print_stats("[fixme: prefix]");*/
282       break;
283
284     case GCRYCTL_DUMP_SECMEM_STATS:
285       _gcry_secmem_dump_stats ();
286       break;
287
288     case GCRYCTL_DROP_PRIVS:
289       global_init ();
290       _gcry_secmem_init (0);
291       break;
292
293     case GCRYCTL_DISABLE_SECMEM:
294       global_init ();
295       no_secure_memory = 1;
296       break;    
297
298     case GCRYCTL_INIT_SECMEM:
299       global_init ();
300       _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
301       if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
302         err = GPG_ERR_GENERAL;
303       break;
304
305     case GCRYCTL_TERM_SECMEM:
306       global_init ();
307       _gcry_secmem_term ();
308       break;
309
310     case GCRYCTL_DISABLE_SECMEM_WARN:
311       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
312                                | GCRY_SECMEM_FLAG_NO_WARNING));
313       break;
314
315     case GCRYCTL_SUSPEND_SECMEM_WARN:
316       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
317                                | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
318       break;
319
320     case GCRYCTL_RESUME_SECMEM_WARN:
321       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
322                                & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
323       break;
324
325     case GCRYCTL_USE_SECURE_RNDPOOL:
326       global_init ();
327       _gcry_secure_random_alloc (); /* put random number into secure memory */
328       break;
329
330     case GCRYCTL_SET_RANDOM_SEED_FILE:
331       _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
332       break;
333
334     case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
335       _gcry_update_random_seed_file ();
336       break;
337
338     case GCRYCTL_SET_VERBOSITY:
339       _gcry_set_log_verbosity (va_arg (arg_ptr, int));
340       break;
341
342     case GCRYCTL_SET_DEBUG_FLAGS:
343       debug_flags |= va_arg (arg_ptr, unsigned int);
344       break;
345
346     case GCRYCTL_CLEAR_DEBUG_FLAGS:
347       debug_flags &= ~va_arg (arg_ptr, unsigned int);
348       break;
349
350     case GCRYCTL_DISABLE_INTERNAL_LOCKING:
351       global_init ();
352       break;
353
354     case GCRYCTL_ANY_INITIALIZATION_P:
355       if (any_init_done)
356         err = GPG_ERR_GENERAL;
357       break;
358
359     case GCRYCTL_INITIALIZATION_FINISHED_P:
360       if (init_finished)
361         err = GPG_ERR_GENERAL;
362       break;
363
364     case GCRYCTL_INITIALIZATION_FINISHED:
365       /* This is a hook which should be used by an application after
366          all initialization has been done and right before any threads
367          are started.  It is not really needed but the only way to be
368          really sure that all initialization for thread-safety has
369          been done. */
370         if (! init_finished)
371           {
372             global_init ();
373             /* Do only a basic random initialization, i.e. init the
374                mutexes. */
375             _gcry_random_initialize (0);
376             init_finished = 1;
377           }
378         break;
379
380     case GCRYCTL_SET_THREAD_CBS:
381       err = ath_install (va_arg (arg_ptr, void *), any_init_done);
382       if (! err)
383         global_init ();
384       break;
385
386     case GCRYCTL_FAST_POLL:
387       /* We need to do make sure that the random pool is really
388          initialized so that the poll function is not a NOP. */
389       _gcry_random_initialize (1);
390       _gcry_fast_random_poll (); 
391       break;
392
393     case GCRYCTL_SET_RNDEGD_SOCKET:
394 #if USE_RNDEGD
395       err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
396 #else
397       err = gpg_error (GPG_ERR_NOT_SUPPORTED);
398 #endif
399       break;
400
401     case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
402       _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
403       break;
404
405     case GCRYCTL_USE_RANDOM_DAEMON:
406       /* We need to do make sure that the random pool is really
407          initialized so that the poll function is not a NOP. */
408       _gcry_random_initialize (1);
409       _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
410       break;
411       
412       /* This command dumps information pertaining to the
413          configuration of libgcrypt to the given stream.  It may be
414          used before the intialization has been finished but not
415          before a gcry_version_check. */
416     case GCRYCTL_PRINT_CONFIG:
417       {
418         FILE *fp = va_arg (arg_ptr, FILE *);
419         print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
420       }
421       break;
422
423     default:
424       err = GPG_ERR_INV_OP;
425     }
426
427   return gcry_error (err);
428 }
429
430
431 /* Command dispatcher function, acting as general control
432    function.  */
433 gcry_error_t
434 gcry_control (enum gcry_ctl_cmds cmd, ...)
435 {
436   gcry_error_t err;
437   va_list arg_ptr;
438   
439   va_start (arg_ptr, cmd);
440   err = _gcry_vcontrol (cmd, arg_ptr);
441   va_end(arg_ptr);
442   return err;
443 }
444
445
446
447 /* Return a pointer to a string containing a description of the error
448    code in the error value ERR.  */
449 const char *
450 gcry_strerror (gcry_error_t err)
451 {
452   return gpg_strerror (err);
453 }
454
455 /* Return a pointer to a string containing a description of the error
456    source in the error value ERR.  */
457 const char *
458 gcry_strsource (gcry_error_t err)
459 {
460   return gpg_strsource (err);
461 }
462
463 /* Retrieve the error code for the system error ERR.  This returns
464    GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
465    this).  */
466 gcry_err_code_t
467 gcry_err_code_from_errno (int err)
468 {
469   return gpg_err_code_from_errno (err);
470 }
471
472
473 /* Retrieve the system error for the error code CODE.  This returns 0
474    if CODE is not a system error code.  */
475 int
476 gcry_err_code_to_errno (gcry_err_code_t code)
477 {
478   return gpg_err_code_from_errno (code);
479 }
480
481   
482 /* Return an error value with the error source SOURCE and the system
483    error ERR.  */
484 gcry_error_t
485 gcry_err_make_from_errno (gpg_err_source_t source, int err)
486 {
487   return gpg_err_make_from_errno (source, err);
488 }
489
490
491 /* Return an error value with the system error ERR.  */
492 gcry_err_code_t
493 gcry_error_from_errno (int err)
494 {
495   return gcry_error (gpg_err_code_from_errno (err));
496 }
497
498 /****************
499  * NOTE: All 5 functions should be set.  */
500 void
501 gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
502                              gcry_handler_alloc_t new_alloc_secure_func,
503                              gcry_handler_secure_check_t new_is_secure_func,
504                              gcry_handler_realloc_t new_realloc_func,
505                              gcry_handler_free_t new_free_func)
506 {
507   global_init ();
508
509   alloc_func = new_alloc_func;
510   alloc_secure_func = new_alloc_secure_func;
511   is_secure_func = new_is_secure_func;
512   realloc_func = new_realloc_func;
513   free_func = new_free_func;
514 }
515
516
517
518 /****************
519  * Set an optional handler which is called in case the xmalloc functions
520  * ran out of memory.  This handler may do one of these things:
521  *   o free some memory and return true, so that the xmalloc function
522  *     tries again.
523  *   o Do whatever it like and return false, so that the xmalloc functions
524  *     use the default fatal error handler.
525  *   o Terminate the program and don't return.
526  *
527  * The handler function is called with 3 arguments:  The opaque value set with
528  * this function, the requested memory size, and a flag with these bits
529  * currently defined:
530  *      bit 0 set = secure memory has been requested.
531  */
532 void
533 gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
534                                                         void *value )
535 {
536     global_init ();
537
538     outofcore_handler = f;
539     outofcore_handler_value = value;
540 }
541
542 static gcry_err_code_t
543 do_malloc (size_t n, unsigned int flags, void **mem)
544 {
545   gcry_err_code_t err = 0;
546   void *m;
547
548   if ((flags & GCRY_ALLOC_FLAG_SECURE) && !no_secure_memory)
549     {
550       if (alloc_secure_func)
551         m = (*alloc_secure_func) (n);
552       else
553         m = _gcry_private_malloc_secure (n);
554     }
555   else
556     {
557       if (alloc_func)
558         m = (*alloc_func) (n);
559       else
560         m = _gcry_private_malloc (n);
561     }
562
563   if (!m)
564     {
565       /* Make sure that ERRNO has been set in case a user supplied
566          memory handler didn't it correctly. */
567       if (!errno)
568         errno = ENOMEM;
569       err = gpg_err_code_from_errno (errno);
570     }
571   else
572     *mem = m;
573
574   return err;
575 }
576   
577 void *
578 gcry_malloc (size_t n)
579 {
580   void *mem = NULL;
581
582   do_malloc (n, 0, &mem);
583
584   return mem;
585 }
586
587 void *
588 gcry_malloc_secure (size_t n)
589 {
590   void *mem = NULL;
591
592   do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem);
593
594   return mem;
595 }
596
597 int
598 gcry_is_secure (const void *a)
599 {
600   if (no_secure_memory)
601     return 0;
602   if (is_secure_func)
603     return is_secure_func (a) ;
604   return _gcry_private_is_secure (a);
605 }
606
607 void
608 _gcry_check_heap( const void *a )
609 {
610   (void)a;
611   
612     /* FIXME: implement this*/
613 #if 0
614     if( some_handler )
615         some_handler(a)
616     else
617         _gcry_private_check_heap(a)
618 #endif
619 }
620
621 void *
622 gcry_realloc (void *a, size_t n)
623 {
624   void *p;
625
626   if (realloc_func)
627     p = realloc_func (a, n);
628   else
629     p =  _gcry_private_realloc (a, n);
630   if (!p && !errno)
631     errno = ENOMEM;
632   return p;
633 }
634
635 void
636 gcry_free( void *p )
637 {
638   if( !p )
639     return;
640
641   if (free_func)
642     free_func (p);
643   else
644     _gcry_private_free (p);
645 }
646
647 void *
648 gcry_calloc (size_t n, size_t m)
649 {
650   size_t bytes;
651   void *p;
652
653   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
654                     defined. */
655   if (m && bytes / m != n) 
656     {
657       errno = ENOMEM;
658       return NULL;
659     }
660
661   p = gcry_malloc (bytes);
662   if (p)
663     memset (p, 0, bytes);
664   return p;
665 }
666
667 void *
668 gcry_calloc_secure (size_t n, size_t m)
669 {
670   size_t bytes;
671   void *p;
672
673   bytes = n * m; /* size_t is unsigned so the behavior on overflow is
674                     defined. */
675   if (m && bytes / m != n) 
676     {
677       errno = ENOMEM;
678       return NULL;
679     }
680   
681   p = gcry_malloc_secure (bytes);
682   if (p)
683     memset (p, 0, bytes);
684   return p;
685 }
686
687
688 /* Create and return a copy of the null-terminated string STRING.  If
689    it is contained in secure memory, the copy will be contained in
690    secure memory as well.  In an out-of-memory condition, NULL is
691    returned.  */
692 char *
693 gcry_strdup (const char *string)
694 {
695   char *string_cp = NULL;
696   size_t string_n = 0;
697
698   string_n = strlen (string);
699
700   if (gcry_is_secure (string))
701     string_cp = gcry_malloc_secure (string_n + 1);
702   else
703     string_cp = gcry_malloc (string_n + 1);
704   
705   if (string_cp)
706     strcpy (string_cp, string);
707
708   return string_cp;
709 }
710
711
712 void *
713 gcry_xmalloc( size_t n )
714 {
715     void *p;
716
717     while ( !(p = gcry_malloc( n )) ) {
718         if( !outofcore_handler
719             || !outofcore_handler( outofcore_handler_value, n, 0 ) ) {
720             _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
721         }
722     }
723     return p;
724 }
725
726 void *
727 gcry_xrealloc( void *a, size_t n )
728 {
729     void *p;
730
731     while ( !(p = gcry_realloc( a, n )) ) {
732         if( !outofcore_handler
733             || !outofcore_handler( outofcore_handler_value, n,
734                                    gcry_is_secure(a)? 3:2 ) ) {
735             _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
736         }
737     }
738     return p;
739 }
740
741 void *
742 gcry_xmalloc_secure( size_t n )
743 {
744     void *p;
745
746     while ( !(p = gcry_malloc_secure( n )) ) {
747         if( !outofcore_handler
748             || !outofcore_handler( outofcore_handler_value, n, 1 ) ) {
749             _gcry_fatal_error(gpg_err_code_from_errno (errno),
750                              _("out of core in secure memory"));
751         }
752     }
753     return p;
754 }
755
756
757 void *
758 gcry_xcalloc( size_t n, size_t m )
759 {
760   size_t nbytes;
761   void *p;
762
763   nbytes = n * m; 
764   if (m && nbytes / m != n) 
765     {
766       errno = ENOMEM;
767       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
768     }
769
770   p = gcry_xmalloc ( nbytes );
771   memset ( p, 0, nbytes );
772   return p;
773 }
774
775 void *
776 gcry_xcalloc_secure( size_t n, size_t m )
777 {
778   size_t nbytes;
779   void *p;
780
781   nbytes = n * m; 
782   if (m && nbytes / m != n) 
783     {
784       errno = ENOMEM;
785       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
786     }
787
788   p = gcry_xmalloc_secure ( nbytes );
789   memset ( p, 0, nbytes );
790   return p;
791 }
792
793 char *
794 gcry_xstrdup (const char *string)
795 {
796   char *p;
797
798   while ( !(p = gcry_strdup (string)) ) 
799     {
800       size_t n = strlen (string);
801       int is_sec = !!gcry_is_secure (string);
802
803       if (!outofcore_handler
804           || !outofcore_handler (outofcore_handler_value, n, is_sec) ) 
805         {
806           _gcry_fatal_error (gpg_err_code_from_errno (errno),
807                              is_sec? _("out of core in secure memory"):NULL);
808         }
809     }
810
811   return p;
812 }
813
814
815 int
816 _gcry_get_debug_flag( unsigned int mask )
817 {
818     return debug_flags & mask;
819 }
820
821
822 \f
823 /* It is often useful to get some feedback of long running operations.
824    This function may be used to register a handler for this. 
825    The callback function CB is used as:
826
827    void cb (void *opaque, const char *what, int printchar,
828            int current, int total);
829
830    Where WHAT is a string identifying the the type of the progress
831    output, PRINTCHAR the character usually printed, CURRENT the amount
832    of progress currently done and TOTAL the expected amount of
833    progress.  A value of 0 for TOTAL indicates that there is no
834    estimation available.
835
836    Defined values for WHAT:
837
838    "need_entropy"  X    0  number-of-bytes-required
839             When running low on entropy
840    "primegen"      '\n'  0 0
841            Prime generated
842                    '!'
843            Need to refresh the prime pool
844                    '<','>'
845            Number of bits adjusted
846                    '^'
847            Looking for a generator
848                    '.'
849            Fermat tests on 10 candidates failed
850                   ':'
851            Restart with a new random value
852                   '+'
853            Rabin Miller test passed          
854    "pk_elg"        '+','-','.','\n'   0  0
855             Only used in debugging mode.
856    "pk_dsa"       
857             Only used in debugging mode.
858 */
859 void
860 gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
861                            void *cb_data)
862 {
863 #if USE_DSA
864   _gcry_register_pk_dsa_progress (cb, cb_data);
865 #endif
866 #if USE_ELGAMAL
867   _gcry_register_pk_elg_progress (cb, cb_data);
868 #endif
869   _gcry_register_primegen_progress (cb, cb_data);
870   _gcry_register_random_progress (cb, cb_data);
871 }