See ChangeLog: Sat Sep 18 12:16:08 CEST 1999 Werner Koch
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  *      Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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  * GnuPG 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 <errno.h>
26 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
27   #include <asm/sysinfo.h>
28   #include <asm/unistd.h>
29 #endif
30 #ifdef HAVE_SETRLIMIT
31   #include <sys/time.h>
32   #include <sys/resource.h>
33 #endif
34 #include "util.h"
35 #include "main.h"
36 #include "options.h"
37 #include "i18n.h"
38
39
40 const char *g10m_revision_string(int);
41 const char *g10c_revision_string(int);
42 const char *g10u_revision_string(int);
43
44 #ifdef __GNUC__
45 volatile
46 #endif
47          void
48 pull_in_libs(void)
49 {
50     g10m_revision_string(0);
51     g10c_revision_string(0);
52     g10u_revision_string(0);
53 }
54
55
56 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
57 #warning using trap_unaligned
58 static int
59 setsysinfo(unsigned long op, void *buffer, unsigned long size,
60                      int *start, void *arg, unsigned long flag)
61 {
62     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
63 }
64
65 void
66 trap_unaligned(void)
67 {
68     unsigned int buf[2];
69
70     buf[0] = SSIN_UACPROC;
71     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
72     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
73 }
74 #else
75 void
76 trap_unaligned(void)
77 {  /* dummy */
78 }
79 #endif
80
81
82 void
83 disable_core_dumps()
84 {
85  #ifndef HAVE_DOSISH_SYSTEM
86   #ifdef HAVE_SETRLIMIT
87     struct rlimit limit;
88
89     limit.rlim_cur = 0;
90     limit.rlim_max = 0;
91     if( !setrlimit( RLIMIT_CORE, &limit ) )
92         return;
93     if( errno != EINVAL )
94         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
95   #endif
96     if( !opt.quiet )
97         log_info(_("WARNING: program may create a core file!\n"));
98  #endif
99 }
100
101
102
103 u16
104 checksum_u16( unsigned n )
105 {
106     u16 a;
107
108     a  = (n >> 8) & 0xff;
109     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
110        a |= n & 0xff;
111        log_debug("csum_u16 emulated for n=%u\n", n);
112     }
113     else
114        a += n & 0xff;
115     return a;
116 }
117
118 static u16
119 checksum_u16_nobug( unsigned n )
120 {
121     u16 a;
122
123     a  = (n >> 8) & 0xff;
124     a += n & 0xff;
125     return a;
126 }
127
128 u16
129 checksum( byte *p, unsigned n )
130 {
131     u16 a;
132
133     for(a=0; n; n-- )
134         a += *p++;
135     return a;
136 }
137
138 u16
139 checksum_mpi( MPI a )
140 {
141     u16 csum;
142     byte *buffer;
143     unsigned nbytes;
144     unsigned nbits;
145
146     buffer = mpi_get_buffer( a, &nbytes, NULL );
147     /* some versions of gpg encode wrong values for the length of an mpi
148      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
149      * value than the one store with the mpi.  mpi_get_nbit_info() returns
150      * this stored value if it is still available.
151      */
152
153     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM )
154         nbits = 0;
155     else
156         nbits = mpi_get_nbit_info(a);
157     if( !nbits )
158        nbits = mpi_get_nbits(a);
159     csum = checksum_u16( nbits );
160     csum += checksum( buffer, nbytes );
161     m_free( buffer );
162     return csum;
163 }
164
165 /****************
166  * This is the correct function
167  */
168 u16
169 checksum_mpi_counted_nbits( MPI a )
170 {
171     u16 csum;
172     byte *buffer;
173     unsigned nbytes;
174     unsigned nbits;
175
176     buffer = mpi_get_buffer( a, &nbytes, NULL );
177     nbits = mpi_get_nbits(a);
178     mpi_set_nbit_info(a,nbits);
179     csum = checksum_u16_nobug( nbits );
180     csum += checksum( buffer, nbytes );
181     m_free( buffer );
182     return csum;
183 }
184
185
186 u32
187 buffer_to_u32( const byte *buffer )
188 {
189     unsigned long a;
190     a =  *buffer << 24;
191     a |= buffer[1] << 16;
192     a |= buffer[2] << 8;
193     a |= buffer[3];
194     return a;
195 }
196
197
198 static void
199 no_exp_algo(void)
200 {
201     static int did_note = 0;
202
203     if( !did_note ) {
204         did_note = 1;
205         log_info(_("Experimental algorithms should not be used!\n"));
206     }
207 }
208
209 void
210 print_pubkey_algo_note( int algo )
211 {
212     if( algo >= 100 && algo <= 110 )
213         no_exp_algo();
214     else if( is_RSA( algo ) ) {
215         static int did_note = 0;
216
217         if( !did_note ) {
218             did_note = 1;
219             log_info(_("RSA keys are deprecated; please consider "
220                        "creating a new key and use this key in the future\n"));
221         }
222     }
223 }
224
225 void
226 print_cipher_algo_note( int algo )
227 {
228     if( algo >= 100 && algo <= 110 )
229         no_exp_algo();
230     else if(    algo == CIPHER_ALGO_3DES
231              || algo == CIPHER_ALGO_CAST5
232              || algo == CIPHER_ALGO_BLOWFISH
233              || algo == CIPHER_ALGO_TWOFISH
234            )
235         ;
236     else {
237         static int did_note = 0;
238
239         if( !did_note ) {
240             did_note = 1;
241             log_info(_("this cipher algorithm is depreciated; "
242                        "please use a more standard one!\n"));
243         }
244     }
245 }
246
247 void
248 print_digest_algo_note( int algo )
249 {
250     if( algo >= 100 && algo <= 110 )
251         no_exp_algo();
252 }
253
254
255
256 /****************
257  * Map errors retuned by libgcrypt to those used by GnuPG.
258  */
259 int
260 map_gcry_rc( int rc )
261 {
262     switch( rc )  {
263       case 0: return 0;
264       default: return G10ERR_GENERAL;
265     }
266 }
267