summaryrefslogtreecommitdiffabout
path: root/pwmanager/libcrypt/crypt/global.c
Unidiff
Diffstat (limited to 'pwmanager/libcrypt/crypt/global.c') (more/less context) (show whitespace changes)
-rw-r--r--pwmanager/libcrypt/crypt/global.c672
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 */
42static unsigned int debug_flags;
43
44static gcry_handler_alloc_t alloc_func;
45static gcry_handler_alloc_t alloc_secure_func;
46static gcry_handler_secure_check_t is_secure_func;
47static gcry_handler_realloc_t realloc_func;
48static gcry_handler_free_t free_func;
49static gcry_handler_no_mem_t outofcore_handler;
50
51static void *outofcore_handler_value = NULL;
52static int no_secure_memory = 0;
53static 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. */
59static void
60global_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
82static const char*
83parse_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
98static const char *
99parse_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 */
121const char *
122gcry_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
153gcry_error_t
154gcry_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. */
285const char *
286gcry_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. */
293const char *
294gcry_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). */
302gcry_err_code_t
303gcry_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. */
311int
312gcry_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. */
320gcry_error_t
321gcry_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. */
328gcry_err_code_t
329gcry_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. */
336void
337gcry_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 */
368void
369gcry_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
378gcry_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
407void *
408gcry_malloc (size_t n)
409{
410 void *mem = NULL;
411
412 _gcry_malloc (n, 0, &mem);
413
414 return mem;
415}
416
417void *
418gcry_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
427int
428gcry_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
437void
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
449void *
450gcry_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
457void
458gcry_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
469void *
470gcry_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
489void *
490gcry_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. */
514char *
515gcry_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
534void *
535gcry_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
548void *
549gcry_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
562void *
563gcry_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
577void *
578gcry_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
585void *
586gcry_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
593char *
594gcry_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
616int
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*/
660void
661gcry_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}