* global.c (gcry_control): Add commands
[libgcrypt.git] / src / global.c
1 /* global.c  -  global control functions
2  *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26 #include <ctype.h>
27 #include <assert.h>
28
29 #include "g10lib.h"
30 #include "../cipher/random.h"
31 #include "stdmem.h" /* our own memory allocator */
32 #include "secmem.h" /* our own secmem allocator */
33
34
35 /****************
36  * flag bits: 0 : general cipher debug
37  *            1 : general MPI debug
38  */
39 static unsigned int debug_flags;
40 static int last_ec; /* fixme: make thread safe */
41
42 static void *(*alloc_func)(size_t n) = NULL;
43 static void *(*alloc_secure_func)(size_t n) = NULL;
44 static int   (*is_secure_func)(const void*) = NULL;
45 static void *(*realloc_func)(void *p, size_t n) = NULL;
46 static void (*free_func)(void*) = NULL;
47 static int (*outofcore_handler)( void*, size_t, unsigned int ) = NULL;
48 static void *outofcore_handler_value = NULL;
49 static int no_internal_locking = 0;
50 static int no_secure_memory = 0;
51 static int any_init_done = 0;
52
53 static const char*
54 parse_version_number( const char *s, int *number )
55 {
56     int val = 0;
57
58     if( *s == '0' && isdigit(s[1]) )
59         return NULL; /* leading zeros are not allowed */
60     for ( ; isdigit(*s); s++ ) {
61         val *= 10;
62         val += *s - '0';
63     }
64     *number = val;
65     return val < 0? NULL : s;
66 }
67
68
69 static const char *
70 parse_version_string( const char *s, int *major, int *minor, int *micro )
71 {
72     s = parse_version_number( s, major );
73     if( !s || *s != '.' )
74         return NULL;
75     s++;
76     s = parse_version_number( s, minor );
77     if( !s || *s != '.' )
78         return NULL;
79     s++;
80     s = parse_version_number( s, micro );
81     if( !s )
82         return NULL;
83     return s; /* patchlevel */
84 }
85
86 /****************
87  * Check that the the version of the library is at minimum the requested one
88  * and return the version string; return NULL if the condition is not
89  * satisfied.  If a NULL is passed to this function, no check is done,
90  * but the version string is simply returned.
91  */
92 const char *
93 gcry_check_version( const char *req_version )
94 {
95     const char *ver = VERSION;
96     int my_major, my_minor, my_micro;
97     int rq_major, rq_minor, rq_micro;
98     const char *my_plvl, *rq_plvl;
99
100     if ( !req_version )
101         return ver;
102
103     my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
104     if ( !my_plvl )
105         return NULL;  /* very strange our own version is bogus */
106     rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
107                                                                 &rq_micro );
108     if ( !rq_plvl )
109         return NULL;  /* req version string is invalid */
110
111     if ( my_major > rq_major
112         || (my_major == rq_major && my_minor > rq_minor)
113         || (my_major == rq_major && my_minor == rq_minor
114                                  && my_micro > rq_micro)
115         || (my_major == rq_major && my_minor == rq_minor
116                                  && my_micro == rq_micro
117                                  && strcmp( my_plvl, rq_plvl ) >= 0) ) {
118         return ver;
119     }
120     return NULL;
121 }
122
123
124 int
125 gcry_control( enum gcry_ctl_cmds cmd, ... )
126 {
127     static int init_finished = 0;
128     va_list arg_ptr ;
129
130     va_start( arg_ptr, cmd ) ;
131     switch( cmd ) {
132      #if 0
133       case GCRYCTL_NO_MEM_IS_FATAL:
134         break;
135       case GCRYCTL_SET_FATAL_FNC:
136         break;
137      #endif
138
139       case GCRYCTL_ENABLE_M_GUARD:
140         _gcry_private_enable_m_guard();
141         break;
142
143       case GCRYCTL_DUMP_RANDOM_STATS:
144         _gcry_random_dump_stats();
145         break;
146
147       case GCRYCTL_DUMP_MEMORY_STATS:
148         /*m_print_stats("[fixme: prefix]");*/
149         break;
150
151       case GCRYCTL_DUMP_SECMEM_STATS:
152         _gcry_secmem_dump_stats();
153         break;
154
155       case GCRYCTL_DROP_PRIVS:
156         any_init_done = 1;
157         _gcry_secmem_init( 0 );
158         break;
159
160       case GCRYCTL_DISABLE_SECMEM:
161         any_init_done = 1;
162         no_secure_memory = 1;
163         break;    
164
165       case GCRYCTL_INIT_SECMEM:
166         any_init_done = 1;
167         _gcry_secmem_init( va_arg( arg_ptr, unsigned int ) );
168         break;
169
170       case GCRYCTL_TERM_SECMEM:
171         any_init_done = 1;
172         _gcry_secmem_term();
173         break;
174
175       case GCRYCTL_DISABLE_SECMEM_WARN:
176         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() | 1) );
177         break;
178
179       case GCRYCTL_SUSPEND_SECMEM_WARN:
180         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() | 2) );
181         break;
182
183       case GCRYCTL_RESUME_SECMEM_WARN:
184         _gcry_secmem_set_flags( (_gcry_secmem_get_flags() & ~2) );
185         break;
186
187       case GCRYCTL_USE_SECURE_RNDPOOL:
188         any_init_done = 1;
189         _gcry_secure_random_alloc(); /* put random number into secure memory */
190         break;
191
192       case GCRYCTL_SET_VERBOSITY:
193         _gcry_set_log_verbosity( va_arg( arg_ptr, int ) );
194         break;
195
196       case GCRYCTL_SET_DEBUG_FLAGS:
197         debug_flags |= va_arg( arg_ptr, unsigned int );
198         break;
199
200       case GCRYCTL_CLEAR_DEBUG_FLAGS:
201         debug_flags &= ~va_arg( arg_ptr, unsigned int );
202         break;
203
204       case GCRYCTL_DISABLE_INTERNAL_LOCKING:
205         any_init_done = 1;
206         no_internal_locking = 1;
207         break;
208
209       case GCRYCTL_ANY_INITIALIZATION_P:
210         va_end(arg_ptr);
211         return any_init_done? -1 : 0;
212
213       case GCRYCTL_INITIALIZATION_FINISHED_P:
214         va_end(arg_ptr);
215         return init_finished? -1 : 0;
216
217       case GCRYCTL_INITIALIZATION_FINISHED:
218         /* This is a hook which should be used by an application after
219            all intialization has been done and right before any
220            threads are started.  It is not really needed but the only
221            way to be really sure that all initialization for
222            thread-safety has been done. */
223         if (!init_finished) {
224             any_init_done = 1;
225             /* fixme: we should initialize the various mutexs here */
226             init_finished = 1;
227         }
228         break;
229
230       default:
231         va_end(arg_ptr);
232         return GCRYERR_INV_OP;
233     }
234     va_end(arg_ptr);
235     return 0;
236 }
237
238 int
239 gcry_errno()
240 {
241     return last_ec;
242 }
243
244 const char*
245 gcry_strerror( int ec )
246 {
247     const char *s;
248     static char buf[20];
249
250     if( ec == -1 )
251         ec = gcry_errno();
252   #define X(n,a) case GCRYERR_##n : s = a; break;
253     switch( ec ) {
254       X(SUCCESS,        N_("no error"))
255       X(GENERAL,        N_("general error"))
256
257       X(INV_PK_ALGO,    N_("invalid public key algorithm"))
258       X(INV_MD_ALGO,    N_("invalid hash algorithm"))
259       X(BAD_PUBLIC_KEY ,N_("bad public key"))
260       X(BAD_SECRET_KEY ,N_("bad secret key"))
261       X(BAD_SIGNATURE , N_("bad signature"))
262
263       X(INV_CIPHER_ALGO,N_("invalid cipher algorithm"))
264       X(BAD_MPI,        N_("bad big integer"))
265       X(WRONG_PK_ALGO,  N_("unusable public key algorithm"))
266       X(WEAK_KEY,       N_("weak encryption key"))
267       X(INV_KEYLEN,     N_("invalid key length"))
268       X(INV_ARG,        N_("invalid argument"))
269       X(SELFTEST,       N_("selftest failed"))
270
271       X(INV_OP,         N_("invalid operation code or ctl command"))
272       X(NO_MEM,         N_("out of core"))
273       X(INTERNAL,       N_("internal error"))
274       X(EOF,            N_("EOF"))
275       X(INV_OBJ,        N_("an object is not valid"))
276       X(TOO_SHORT,      N_("provided buffer too short"))
277       X(TOO_LARGE,      N_("object is too large"))
278       X(NO_OBJ,         N_("no object"))
279       X(NOT_IMPL,       N_("not implemented"))
280       X(CONFLICT,       N_("conflict"))
281       X(INV_CIPHER_MODE,N_("invalid cipher mode"))
282
283
284       default:
285         sprintf( buf, "ec=%d", ec );
286         s = buf;
287     }
288   #undef X
289     return s;
290 }
291
292
293 int
294 _gcry_set_lasterr( int ec )
295 {
296     if( ec )
297         last_ec = ec == -1 ? GCRYERR_EOF : ec;
298     return ec;
299 }
300
301
302
303 /****************
304  * NOTE: All 5 functions should be set.  */
305 void
306 gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n),
307                              void *(*new_alloc_secure_func)(size_t n),
308                              int (*new_is_secure_func)(const void*),
309                              void *(*new_realloc_func)(void *p, size_t n),
310                              void (*new_free_func)(void*) )
311 {
312     any_init_done = 1;
313
314     alloc_func        = new_alloc_func;
315     alloc_secure_func = new_alloc_secure_func;
316     is_secure_func    = new_is_secure_func;
317     realloc_func      = new_realloc_func;
318     free_func         = new_free_func;
319 }
320
321
322
323 /****************
324  * Set an optional handler which is called in case the xmalloc functions
325  * ran out of memory.  This handler may do one of these things:
326  *   o free some memory and return true, so that the xmalloc function
327  *     tries again.
328  *   o Do whatever it like and return false, so that the xmalloc functions
329  *     use the default fatal error handler.
330  *   o Terminate the program and don't return.
331  *
332  * The handler function is called with 3 arguments:  The opaque value set with
333  * this function, the requested memory size, and a flag with these bits
334  * currently defined:
335  *      bit 0 set = secure memory has been requested.
336  */
337 void
338 gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
339                                                         void *value )
340 {
341     any_init_done = 1;
342
343     outofcore_handler = f;
344     outofcore_handler_value = value;
345 }
346
347
348
349 void *
350 gcry_malloc( size_t n )
351 {
352     if( alloc_func )
353         return alloc_func( n ) ;
354     return _gcry_private_malloc( n );
355 }
356
357 void *
358 gcry_malloc_secure( size_t n )
359 {
360   if (no_secure_memory)
361     return gcry_malloc (n);
362   if (alloc_secure_func)
363     return alloc_secure_func (n) ;
364   return _gcry_private_malloc_secure (n);
365 }
366
367 int
368 gcry_is_secure( const void *a )
369 {
370   if (no_secure_memory)
371     return 0;
372   if (is_secure_func)
373     return is_secure_func (a) ;
374   return _gcry_private_is_secure (a);
375 }
376
377 void
378 _gcry_check_heap( const void *a )
379 {
380     /* FIXME: implement this*/
381   #if 0
382     if( some_handler )
383         some_handler(a)
384     else
385         _gcry_private_check_heap(a)
386   #endif
387 }
388
389 void *
390 gcry_realloc( void *a, size_t n )
391 {
392     /* FIXME: Make sure that the realloced memory is cleared out */
393
394     if( realloc_func )
395         return realloc_func( a, n ) ;
396     return _gcry_private_realloc( a, n );
397 }
398
399 void
400 gcry_free( void *p )
401 {
402     if( !p )
403         return;
404
405     if( free_func )
406         free_func( p );
407     else
408         _gcry_private_free( p );
409 }
410
411 void *
412 gcry_calloc( size_t n, size_t m )
413 {
414     void *p = gcry_malloc( n*m );
415     if( p )
416         memset( p, 0, n*m );
417     return p;
418 }
419
420 void *
421 gcry_calloc_secure( size_t n, size_t m )
422 {
423     void *p = gcry_malloc_secure( n*m );
424     if( p )
425         memset( p, 0, n*m );
426     return p;
427 }
428
429
430 char *
431 gcry_strdup( const char *string )
432 {
433     void *p = gcry_malloc( strlen(string)+1 );
434     strcpy( p, string );
435     return p;
436 }
437
438
439 void *
440 gcry_xmalloc( size_t n )
441 {
442     void *p;
443
444     while ( !(p = gcry_malloc( n )) ) {
445         if( !outofcore_handler
446             || !outofcore_handler( outofcore_handler_value, n, 0 ) ) {
447             _gcry_fatal_error(GCRYERR_NO_MEM, NULL );
448         }
449     }
450     return p;
451 }
452
453 void *
454 gcry_xrealloc( void *a, size_t n )
455 {
456     void *p;
457
458     while ( !(p = gcry_realloc( a, n )) ) {
459         if( !outofcore_handler
460             || !outofcore_handler( outofcore_handler_value, n, 2 ) ) {
461             _gcry_fatal_error(GCRYERR_NO_MEM, NULL );
462         }
463     }
464     return p;
465 }
466
467 void *
468 gcry_xmalloc_secure( size_t n )
469 {
470     void *p;
471
472     while ( !(p = gcry_malloc_secure( n )) ) {
473         if( !outofcore_handler
474             || !outofcore_handler( outofcore_handler_value, n, 1 ) ) {
475             _gcry_fatal_error(GCRYERR_NO_MEM,
476                              _("out of core in secure memory"));
477         }
478     }
479     return p;
480 }
481
482 void *
483 gcry_xcalloc( size_t n, size_t m )
484 {
485     void *p = gcry_xmalloc( n*m );
486     memset( p, 0, n*m );
487     return p;
488 }
489
490 void *
491 gcry_xcalloc_secure( size_t n, size_t m )
492 {
493     void *p = gcry_xmalloc_secure( n* m );
494     memset( p, 0, n*m );
495     return p;
496 }
497
498 char *
499 gcry_xstrdup( const char *string )
500 {
501     void *p = gcry_xmalloc( strlen(string)+1 );
502     strcpy( p, string );
503     return p;
504 }
505
506
507 int
508 _gcry_get_debug_flag( unsigned int mask )
509 {
510     return debug_flags & mask;
511 }
512
513 int 
514 _gcry_no_internal_locking (void)
515 {
516   return no_internal_locking;
517 }
518