Diffstat (limited to 'pwmanager/libcrypt/crypt/global.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/crypt/global.c | 672 |
1 files changed, 672 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/crypt/global.c b/pwmanager/libcrypt/crypt/global.c new file mode 100644 index 0000000..9e7165b --- a/dev/null +++ b/pwmanager/libcrypt/crypt/global.c | |||
@@ -0,0 +1,672 @@ | |||
1 | /* global.c -global control functions | ||
2 | * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 | ||
3 | * 2004 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 | #include <stdio.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <stdarg.h> | ||
27 | #include <ctype.h> | ||
28 | #include <assert.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 | /**************** | ||
39 | * flag bits: 0 : general cipher debug | ||
40 | * 1 : general MPI debug | ||
41 | */ | ||
42 | static unsigned int debug_flags; | ||
43 | |||
44 | static gcry_handler_alloc_t alloc_func; | ||
45 | static gcry_handler_alloc_t alloc_secure_func; | ||
46 | static gcry_handler_secure_check_t is_secure_func; | ||
47 | static gcry_handler_realloc_t realloc_func; | ||
48 | static gcry_handler_free_t free_func; | ||
49 | static gcry_handler_no_mem_t outofcore_handler; | ||
50 | |||
51 | static void *outofcore_handler_value = NULL; | ||
52 | static int no_secure_memory = 0; | ||
53 | static int any_init_done; | ||
54 | |||
55 | /* This is our handmade constructor. It gets called by any function | ||
56 | likely to be called at startup. The suggested way for an | ||
57 | application to make sure that this has been called is by using | ||
58 | gcry_check_version. */ | ||
59 | static void | ||
60 | global_init (void) | ||
61 | { | ||
62 | gcry_err_code_t err = GPG_ERR_NO_ERROR; | ||
63 | |||
64 | if (any_init_done) | ||
65 | return; | ||
66 | any_init_done = 1; | ||
67 | |||
68 | err = ath_init (); | ||
69 | if (! err) | ||
70 | _gcry_cipher_init (); | ||
71 | if (! err) | ||
72 | _gcry_md_init (); | ||
73 | if (! err) | ||
74 | _gcry_pk_init (); | ||
75 | |||
76 | if (err) | ||
77 | /* FIXME? */ | ||
78 | BUG (); | ||
79 | } | ||
80 | |||
81 | |||
82 | static const char* | ||
83 | parse_version_number( const char *s, int *number ) | ||
84 | { | ||
85 | int val = 0; | ||
86 | |||
87 | if( *s == '0' && isdigit(s[1]) ) | ||
88 | return NULL; /* leading zeros are not allowed */ | ||
89 | for ( ; isdigit(*s); s++ ) { | ||
90 | val *= 10; | ||
91 | val += *s - '0'; | ||
92 | } | ||
93 | *number = val; | ||
94 | return val < 0? NULL : s; | ||
95 | } | ||
96 | |||
97 | |||
98 | static const char * | ||
99 | parse_version_string( const char *s, int *major, int *minor, int *micro ) | ||
100 | { | ||
101 | s = parse_version_number( s, major ); | ||
102 | if( !s || *s != '.' ) | ||
103 | return NULL; | ||
104 | s++; | ||
105 | s = parse_version_number( s, minor ); | ||
106 | if( !s || *s != '.' ) | ||
107 | return NULL; | ||
108 | s++; | ||
109 | s = parse_version_number( s, micro ); | ||
110 | if( !s ) | ||
111 | return NULL; | ||
112 | return s; /* patchlevel */ | ||
113 | } | ||
114 | |||
115 | /**************** | ||
116 | * Check that the the version of the library is at minimum the requested one | ||
117 | * and return the version string; return NULL if the condition is not | ||
118 | * satisfied. If a NULL is passed to this function, no check is done, | ||
119 | * but the version string is simply returned. | ||
120 | */ | ||
121 | const char * | ||
122 | gcry_check_version( const char *req_version ) | ||
123 | { | ||
124 | const char *ver = VERSION; | ||
125 | int my_major, my_minor, my_micro; | ||
126 | int rq_major, rq_minor, rq_micro; | ||
127 | const char *my_plvl, *rq_plvl; | ||
128 | |||
129 | global_init (); | ||
130 | if ( !req_version ) | ||
131 | return ver; | ||
132 | |||
133 | my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); | ||
134 | if ( !my_plvl ) | ||
135 | return NULL; /* very strange our own version is bogus */ | ||
136 | rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor, | ||
137 | &rq_micro ); | ||
138 | if ( !rq_plvl ) | ||
139 | return NULL; /* req version string is invalid */ | ||
140 | |||
141 | if ( my_major > rq_major | ||
142 | || (my_major == rq_major && my_minor > rq_minor) | ||
143 | || (my_major == rq_major && my_minor == rq_minor | ||
144 | && my_micro > rq_micro) | ||
145 | || (my_major == rq_major && my_minor == rq_minor | ||
146 | && my_micro == rq_micro | ||
147 | && strcmp( my_plvl, rq_plvl ) >= 0) ) { | ||
148 | return ver; | ||
149 | } | ||
150 | return NULL; | ||
151 | } | ||
152 | |||
153 | gcry_error_t | ||
154 | gcry_control (enum gcry_ctl_cmds cmd, ...) | ||
155 | { | ||
156 | gcry_err_code_t err = GPG_ERR_NO_ERROR; | ||
157 | static int init_finished = 0; | ||
158 | va_list arg_ptr; | ||
159 | |||
160 | va_start (arg_ptr, cmd); | ||
161 | switch (cmd) | ||
162 | { | ||
163 | case GCRYCTL_ENABLE_M_GUARD: | ||
164 | _gcry_private_enable_m_guard (); | ||
165 | break; | ||
166 | |||
167 | case GCRYCTL_ENABLE_QUICK_RANDOM: | ||
168 | _gcry_quick_random_gen (1); | ||
169 | break; | ||
170 | |||
171 | case GCRYCTL_DUMP_RANDOM_STATS: | ||
172 | _gcry_random_dump_stats (); | ||
173 | break; | ||
174 | |||
175 | case GCRYCTL_DUMP_MEMORY_STATS: | ||
176 | /*m_print_stats("[fixme: prefix]");*/ | ||
177 | break; | ||
178 | |||
179 | case GCRYCTL_DUMP_SECMEM_STATS: | ||
180 | _gcry_secmem_dump_stats (); | ||
181 | break; | ||
182 | |||
183 | case GCRYCTL_DROP_PRIVS: | ||
184 | global_init (); | ||
185 | _gcry_secmem_init (0); | ||
186 | break; | ||
187 | |||
188 | case GCRYCTL_DISABLE_SECMEM: | ||
189 | global_init (); | ||
190 | no_secure_memory = 1; | ||
191 | break; | ||
192 | |||
193 | case GCRYCTL_INIT_SECMEM: | ||
194 | global_init (); | ||
195 | _gcry_secmem_init (va_arg (arg_ptr, unsigned int)); | ||
196 | break; | ||
197 | |||
198 | case GCRYCTL_TERM_SECMEM: | ||
199 | global_init (); | ||
200 | _gcry_secmem_term (); | ||
201 | break; | ||
202 | |||
203 | case GCRYCTL_DISABLE_SECMEM_WARN: | ||
204 | _gcry_secmem_set_flags ((_gcry_secmem_get_flags () | ||
205 | | GCRY_SECMEM_FLAG_NO_WARNING)); | ||
206 | break; | ||
207 | |||
208 | case GCRYCTL_SUSPEND_SECMEM_WARN: | ||
209 | _gcry_secmem_set_flags ((_gcry_secmem_get_flags () | ||
210 | | GCRY_SECMEM_FLAG_SUSPEND_WARNING)); | ||
211 | break; | ||
212 | |||
213 | case GCRYCTL_RESUME_SECMEM_WARN: | ||
214 | _gcry_secmem_set_flags ((_gcry_secmem_get_flags () | ||
215 | & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING)); | ||
216 | break; | ||
217 | |||
218 | case GCRYCTL_USE_SECURE_RNDPOOL: | ||
219 | global_init (); | ||
220 | _gcry_secure_random_alloc (); /* put random number into secure memory */ | ||
221 | break; | ||
222 | |||
223 | case GCRYCTL_SET_RANDOM_SEED_FILE: | ||
224 | _gcry_set_random_seed_file (va_arg (arg_ptr, const char *)); | ||
225 | break; | ||
226 | |||
227 | case GCRYCTL_UPDATE_RANDOM_SEED_FILE: | ||
228 | _gcry_update_random_seed_file (); | ||
229 | break; | ||
230 | |||
231 | case GCRYCTL_SET_VERBOSITY: | ||
232 | _gcry_set_log_verbosity (va_arg (arg_ptr, int)); | ||
233 | break; | ||
234 | |||
235 | case GCRYCTL_SET_DEBUG_FLAGS: | ||
236 | debug_flags |= va_arg (arg_ptr, unsigned int); | ||
237 | break; | ||
238 | |||
239 | case GCRYCTL_CLEAR_DEBUG_FLAGS: | ||
240 | debug_flags &= ~va_arg (arg_ptr, unsigned int); | ||
241 | break; | ||
242 | |||
243 | case GCRYCTL_DISABLE_INTERNAL_LOCKING: | ||
244 | global_init (); | ||
245 | break; | ||
246 | |||
247 | case GCRYCTL_ANY_INITIALIZATION_P: | ||
248 | if (any_init_done) | ||
249 | err = GPG_ERR_GENERAL; | ||
250 | break; | ||
251 | |||
252 | case GCRYCTL_INITIALIZATION_FINISHED_P: | ||
253 | if (init_finished) | ||
254 | err = GPG_ERR_GENERAL; | ||
255 | break; | ||
256 | |||
257 | case GCRYCTL_INITIALIZATION_FINISHED: | ||
258 | /* This is a hook which should be used by an application after | ||
259 | all initialization has been done and right before any threads | ||
260 | are started. It is not really needed but the only way to be | ||
261 | really sure that all initialization for thread-safety has | ||
262 | been done. */ | ||
263 | if (! init_finished) | ||
264 | { | ||
265 | global_init (); | ||
266 | _gcry_random_initialize (); | ||
267 | init_finished = 1; | ||
268 | } | ||
269 | break; | ||
270 | |||
271 | case GCRYCTL_SET_THREAD_CBS: | ||
272 | err = ath_install (va_arg (arg_ptr, void *), any_init_done); | ||
273 | break; | ||
274 | |||
275 | default: | ||
276 | err = GPG_ERR_INV_OP; | ||
277 | } | ||
278 | |||
279 | va_end(arg_ptr); | ||
280 | return gcry_error (err); | ||
281 | } | ||
282 | |||
283 | /* Return a pointer to a string containing a description of the error | ||
284 | code in the error value ERR. */ | ||
285 | const char * | ||
286 | gcry_strerror (gcry_error_t err) | ||
287 | { | ||
288 | return gpg_strerror (err); | ||
289 | } | ||
290 | |||
291 | /* Return a pointer to a string containing a description of the error | ||
292 | source in the error value ERR. */ | ||
293 | const char * | ||
294 | gcry_strsource (gcry_error_t err) | ||
295 | { | ||
296 | return gpg_strsource (err); | ||
297 | } | ||
298 | |||
299 | /* Retrieve the error code for the system error ERR. This returns | ||
300 | GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report | ||
301 | this). */ | ||
302 | gcry_err_code_t | ||
303 | gcry_err_code_from_errno (int err) | ||
304 | { | ||
305 | return gpg_err_code_from_errno (err); | ||
306 | } | ||
307 | |||
308 | |||
309 | /* Retrieve the system error for the error code CODE. This returns 0 | ||
310 | if CODE is not a system error code. */ | ||
311 | int | ||
312 | gcry_err_code_to_errno (gcry_err_code_t code) | ||
313 | { | ||
314 | return gpg_err_code_from_errno (code); | ||
315 | } | ||
316 | |||
317 | |||
318 | /* Return an error value with the error source SOURCE and the system | ||
319 | error ERR. */ | ||
320 | gcry_error_t | ||
321 | gcry_err_make_from_errno (gpg_err_source_t source, int err) | ||
322 | { | ||
323 | return gpg_err_make_from_errno (source, err); | ||
324 | } | ||
325 | |||
326 | |||
327 | /* Return an error value with the system error ERR. */ | ||
328 | gcry_err_code_t | ||
329 | gcry_error_from_errno (int err) | ||
330 | { | ||
331 | return gcry_error (gpg_err_code_from_errno (err)); | ||
332 | } | ||
333 | |||
334 | /**************** | ||
335 | * NOTE: All 5 functions should be set. */ | ||
336 | void | ||
337 | gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func, | ||
338 | gcry_handler_alloc_t new_alloc_secure_func, | ||
339 | gcry_handler_secure_check_t new_is_secure_func, | ||
340 | gcry_handler_realloc_t new_realloc_func, | ||
341 | gcry_handler_free_t new_free_func) | ||
342 | { | ||
343 | global_init (); | ||
344 | |||
345 | alloc_func = new_alloc_func; | ||
346 | alloc_secure_func = new_alloc_secure_func; | ||
347 | is_secure_func = new_is_secure_func; | ||
348 | realloc_func = new_realloc_func; | ||
349 | free_func = new_free_func; | ||
350 | } | ||
351 | |||
352 | |||
353 | |||
354 | /**************** | ||
355 | * Set an optional handler which is called in case the xmalloc functions | ||
356 | * ran out of memory. This handler may do one of these things: | ||
357 | * o free some memory and return true, so that the xmalloc function | ||
358 | * tries again. | ||
359 | * o Do whatever it like and return false, so that the xmalloc functions | ||
360 | * use the default fatal error handler. | ||
361 | * o Terminate the program and don't return. | ||
362 | * | ||
363 | * The handler function is called with 3 arguments: The opaque value set with | ||
364 | * this function, the requested memory size, and a flag with these bits | ||
365 | * currently defined: | ||
366 | *bit 0 set = secure memory has been requested. | ||
367 | */ | ||
368 | void | ||
369 | gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ), | ||
370 | void *value ) | ||
371 | { | ||
372 | global_init (); | ||
373 | |||
374 | outofcore_handler = f; | ||
375 | outofcore_handler_value = value; | ||
376 | } | ||
377 | |||
378 | gcry_err_code_t | ||
379 | _gcry_malloc (size_t n, unsigned int flags, void **mem) | ||
380 | { | ||
381 | gcry_err_code_t err = GPG_ERR_NO_ERROR; | ||
382 | void *m = NULL; | ||
383 | |||
384 | if ((flags & GCRY_ALLOC_FLAG_SECURE) && !no_secure_memory) | ||
385 | { | ||
386 | if (alloc_secure_func) | ||
387 | m = (*alloc_secure_func) (n); | ||
388 | else | ||
389 | m = _gcry_private_malloc_secure (n); | ||
390 | } | ||
391 | else | ||
392 | { | ||
393 | if (alloc_func) | ||
394 | m = (*alloc_func) (n); | ||
395 | else | ||
396 | m = _gcry_private_malloc (n); | ||
397 | } | ||
398 | |||
399 | if (! m) | ||
400 | err = gpg_err_code_from_errno (ENOMEM); | ||
401 | else | ||
402 | *mem = m; | ||
403 | |||
404 | return err; | ||
405 | } | ||
406 | |||
407 | void * | ||
408 | gcry_malloc (size_t n) | ||
409 | { | ||
410 | void *mem = NULL; | ||
411 | |||
412 | _gcry_malloc (n, 0, &mem); | ||
413 | |||
414 | return mem; | ||
415 | } | ||
416 | |||
417 | void * | ||
418 | gcry_malloc_secure (size_t n) | ||
419 | { | ||
420 | void *mem = NULL; | ||
421 | |||
422 | _gcry_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem); | ||
423 | |||
424 | return mem; | ||
425 | } | ||
426 | |||
427 | int | ||
428 | gcry_is_secure (const void *a) | ||
429 | { | ||
430 | if (no_secure_memory) | ||
431 | return 0; | ||
432 | if (is_secure_func) | ||
433 | return is_secure_func (a) ; | ||
434 | return _gcry_private_is_secure (a); | ||
435 | } | ||
436 | |||
437 | void | ||
438 | _gcry_check_heap( const void *a ) | ||
439 | { | ||
440 | /* FIXME: implement this*/ | ||
441 | #if 0 | ||
442 | if( some_handler ) | ||
443 | some_handler(a) | ||
444 | else | ||
445 | _gcry_private_check_heap(a) | ||
446 | #endif | ||
447 | } | ||
448 | |||
449 | void * | ||
450 | gcry_realloc (void *a, size_t n) | ||
451 | { | ||
452 | if (realloc_func) | ||
453 | return realloc_func (a, n); | ||
454 | return _gcry_private_realloc (a, n); | ||
455 | } | ||
456 | |||
457 | void | ||
458 | gcry_free( void *p ) | ||
459 | { | ||
460 | if( !p ) | ||
461 | return; | ||
462 | |||
463 | if (free_func) | ||
464 | free_func (p); | ||
465 | else | ||
466 | _gcry_private_free (p); | ||
467 | } | ||
468 | |||
469 | void * | ||
470 | gcry_calloc (size_t n, size_t m) | ||
471 | { | ||
472 | size_t bytes; | ||
473 | void *p; | ||
474 | |||
475 | bytes = n * m; /* size_t is unsigned so the behavior on overflow is | ||
476 | defined. */ | ||
477 | if (m && bytes / m != n) | ||
478 | { | ||
479 | errno = ENOMEM; | ||
480 | return NULL; | ||
481 | } | ||
482 | |||
483 | p = gcry_malloc (bytes); | ||
484 | if (p) | ||
485 | memset (p, 0, bytes); | ||
486 | return p; | ||
487 | } | ||
488 | |||
489 | void * | ||
490 | gcry_calloc_secure (size_t n, size_t m) | ||
491 | { | ||
492 | size_t bytes; | ||
493 | void *p; | ||
494 | |||
495 | bytes = n * m; /* size_t is unsigned so the behavior on overflow is | ||
496 | defined. */ | ||
497 | if (m && bytes / m != n) | ||
498 | { | ||
499 | errno = ENOMEM; | ||
500 | return NULL; | ||
501 | } | ||
502 | |||
503 | p = gcry_malloc_secure (bytes); | ||
504 | if (p) | ||
505 | memset (p, 0, bytes); | ||
506 | return p; | ||
507 | } | ||
508 | |||
509 | |||
510 | /* Create and return a copy of the null-terminated string STRING. If | ||
511 | it is contained in secure memory, the copy will be contained in | ||
512 | secure memory as well. In an out-of-memory condition, NULL is | ||
513 | returned. */ | ||
514 | char * | ||
515 | gcry_strdup (const char *string) | ||
516 | { | ||
517 | char *string_cp = NULL; | ||
518 | size_t string_n = 0; | ||
519 | |||
520 | string_n = strlen (string); | ||
521 | |||
522 | if (gcry_is_secure (string)) | ||
523 | string_cp = gcry_malloc_secure (string_n + 1); | ||
524 | else | ||
525 | string_cp = gcry_malloc (string_n + 1); | ||
526 | |||
527 | if (string_cp) | ||
528 | strcpy (string_cp, string); | ||
529 | |||
530 | return string_cp; | ||
531 | } | ||
532 | |||
533 | |||
534 | void * | ||
535 | gcry_xmalloc( size_t n ) | ||
536 | { | ||
537 | void *p; | ||
538 | |||
539 | while ( !(p = gcry_malloc( n )) ) { | ||
540 | if( !outofcore_handler | ||
541 | || !outofcore_handler( outofcore_handler_value, n, 0 ) ) { | ||
542 | _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); | ||
543 | } | ||
544 | } | ||
545 | return p; | ||
546 | } | ||
547 | |||
548 | void * | ||
549 | gcry_xrealloc( void *a, size_t n ) | ||
550 | { | ||
551 | void *p; | ||
552 | |||
553 | while ( !(p = gcry_realloc( a, n )) ) { | ||
554 | if( !outofcore_handler | ||
555 | || !outofcore_handler( outofcore_handler_value, n, 2 ) ) { | ||
556 | _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); | ||
557 | } | ||
558 | } | ||
559 | return p; | ||
560 | } | ||
561 | |||
562 | void * | ||
563 | gcry_xmalloc_secure( size_t n ) | ||
564 | { | ||
565 | void *p; | ||
566 | |||
567 | while ( !(p = gcry_malloc_secure( n )) ) { | ||
568 | if( !outofcore_handler | ||
569 | || !outofcore_handler( outofcore_handler_value, n, 1 ) ) { | ||
570 | _gcry_fatal_error(gpg_err_code_from_errno (errno), | ||
571 | _("out of core in secure memory")); | ||
572 | } | ||
573 | } | ||
574 | return p; | ||
575 | } | ||
576 | |||
577 | void * | ||
578 | gcry_xcalloc( size_t n, size_t m ) | ||
579 | { | ||
580 | void *p = gcry_xmalloc( n*m ); | ||
581 | memset( p, 0, n*m ); | ||
582 | return p; | ||
583 | } | ||
584 | |||
585 | void * | ||
586 | gcry_xcalloc_secure( size_t n, size_t m ) | ||
587 | { | ||
588 | void *p = gcry_xmalloc_secure( n* m ); | ||
589 | memset( p, 0, n*m ); | ||
590 | return p; | ||
591 | } | ||
592 | |||
593 | char * | ||
594 | gcry_xstrdup (const char *string) | ||
595 | { | ||
596 | char *p; | ||
597 | |||
598 | while ( !(p = gcry_strdup (string)) ) | ||
599 | { | ||
600 | size_t n = strlen (string); | ||
601 | int is_sec = !!gcry_is_secure (string); | ||
602 | |||
603 | if (!outofcore_handler | ||
604 | || !outofcore_handler (outofcore_handler_value, n, is_sec) ) | ||
605 | { | ||
606 | _gcry_fatal_error (gpg_err_code_from_errno (errno), | ||
607 | is_sec? _("out of core in secure memory"):NULL); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | strcpy( p, string ); | ||
612 | return p; | ||
613 | } | ||
614 | |||
615 | |||
616 | int | ||
617 | _gcry_get_debug_flag( unsigned int mask ) | ||
618 | { | ||
619 | return debug_flags & mask; | ||
620 | } | ||
621 | |||
622 | |||
623 | |||
624 | /* It is often useful to get some feedback of long running operations. | ||
625 | This function may be used to register a handler for this. | ||
626 | The callback function CB is used as: | ||
627 | |||
628 | void cb (void *opaque, const char *what, int printchar, | ||
629 | int current, int total); | ||
630 | |||
631 | Where WHAT is a string identifying the the type of the progress | ||
632 | output, PRINTCHAR the character usually printed, CURRENT the amount | ||
633 | of progress currently done and TOTAL the expected amount of | ||
634 | progress. A value of 0 for TOTAL indicates that there is no | ||
635 | estimation available. | ||
636 | |||
637 | Defined values for WHAT: | ||
638 | |||
639 | "need_entropy" X 0 number-of-bytes-required | ||
640 | When running low on entropy | ||
641 | "primegen" '\n' 0 0 | ||
642 | Prime generated | ||
643 | '!' | ||
644 | Need to refresh the prime pool | ||
645 | '<','>' | ||
646 | Number of bits adjusted | ||
647 | '^' | ||
648 | Looking for a generator | ||
649 | '.' | ||
650 | Fermat tests on 10 candidates failed | ||
651 | ':' | ||
652 | Restart with a new random value | ||
653 | '+' | ||
654 | Rabin Miller test passed | ||
655 | "pk_elg" '+','-','.','\n' 0 0 | ||
656 | Only used in debugging mode. | ||
657 | "pk_dsa" | ||
658 | Only used in debugging mode. | ||
659 | */ | ||
660 | void | ||
661 | gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int), | ||
662 | void *cb_data) | ||
663 | { | ||
664 | #if USE_DSA | ||
665 | _gcry_register_pk_dsa_progress (cb, cb_data); | ||
666 | #endif | ||
667 | #if USE_ELGAMAL | ||
668 | _gcry_register_pk_elg_progress (cb, cb_data); | ||
669 | #endif | ||
670 | _gcry_register_primegen_progress (cb, cb_data); | ||
671 | _gcry_register_random_progress (cb, cb_data); | ||
672 | } | ||