sync
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  *      Copyright (C) 1998 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__)
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
38
39 const char *g10m_revision_string(int);
40 const char *g10c_revision_string(int);
41 const char *g10u_revision_string(int);
42
43 volatile void
44 pull_in_libs(void)
45 {
46     g10m_revision_string(0);
47     g10c_revision_string(0);
48     g10u_revision_string(0);
49 }
50
51
52 #if defined(__linux__) && defined(__alpha__)
53 #warning using trap_unaligned
54 static int
55 setsysinfo(unsigned long op, void *buffer, unsigned long size,
56                      int *start, void *arg, unsigned long flag)
57 {
58     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
59 }
60
61 void
62 trap_unaligned(void)
63 {
64     unsigned int buf[2];
65
66     buf[0] = SSIN_UACPROC;
67     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
68     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
69 }
70 #else
71 void
72 trap_unaligned(void)
73 {  /* dummy */
74 }
75 #endif
76
77
78 void
79 disable_core_dumps()
80 {
81   #ifdef HAVE_SETRLIMIT
82     struct rlimit limit;
83
84     limit.rlim_cur = 0;
85     limit.rlim_max = 0;
86     if( setrlimit( RLIMIT_CORE, &limit ) )
87         log_fatal("can't disable core dumps: %s\n", strerror(errno) );
88   #else
89     log_info("WARNING: Program may create a core file!\n");
90   #endif
91 }
92
93
94
95 u16
96 checksum_u16( unsigned n )
97 {
98     u16 a;
99
100     a  = (n >> 8) & 0xff;
101     if( opt.emulate_bugs & 1 ) {
102        a |= n & 0xff;
103        log_debug("csum_u16 emulated for n=%u\n", n);
104     }
105     else
106        a += n & 0xff;
107     return a;
108 }
109
110 static u16
111 checksum_u16_nobug( unsigned n )
112 {
113     u16 a;
114
115     a  = (n >> 8) & 0xff;
116     a += n & 0xff;
117     return a;
118 }
119
120 u16
121 checksum( byte *p, unsigned n )
122 {
123     u16 a;
124
125     for(a=0; n; n-- )
126         a += *p++;
127     return a;
128 }
129
130 u16
131 checksum_mpi( MPI a )
132 {
133     u16 csum;
134     byte *buffer;
135     unsigned nbytes;
136     unsigned nbits;
137
138     buffer = mpi_get_buffer( a, &nbytes, NULL );
139     /* some versions of gpg encode wrong values for the length of an mpi
140      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
141      * value than the one store with the mpi.  mpi_get_nbit_info() returns
142      * this stored value if it is still available.
143      */
144
145     if( opt.emulate_bugs & 1 )
146         nbits = 0;
147     else
148         nbits = mpi_get_nbit_info(a);
149     if( !nbits )
150        nbits = mpi_get_nbits(a);
151     csum = checksum_u16( nbits );
152     csum += checksum( buffer, nbytes );
153     m_free( buffer );
154     return csum;
155 }
156
157 /****************
158  * This is the correct function
159  */
160 u16
161 checksum_mpi_counted_nbits( MPI a )
162 {
163     u16 csum;
164     byte *buffer;
165     unsigned nbytes;
166     unsigned nbits;
167
168     buffer = mpi_get_buffer( a, &nbytes, NULL );
169     nbits = mpi_get_nbits(a);
170     mpi_set_nbit_info(a,nbits);
171     csum = checksum_u16_nobug( nbits );
172     csum += checksum( buffer, nbytes );
173     m_free( buffer );
174     return csum;
175 }
176
177
178 u32
179 buffer_to_u32( const byte *buffer )
180 {
181     unsigned long a;
182     a =  *buffer << 24;
183     a |= buffer[1] << 16;
184     a |= buffer[2] << 8;
185     a |= buffer[3];
186     return a;
187 }
188