extensions are now working and fixed a lot of bugs
[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 #if defined(__linux__) && defined(__alpha__)
26   #include <asm/sysinfo.h>
27   #include <asm/unistd.h>
28 #endif
29 #include "util.h"
30 #include "main.h"
31 #include "options.h"
32
33 volatile int
34 pull_in_libs(void)
35 {
36     g10m_revision_string(0);
37     g10c_revision_string(0);
38     g10u_revision_string(0);
39 }
40
41
42 #if defined(__linux__) && defined(__alpha__)
43 #warning using trap_unaligned
44 static int
45 setsysinfo(unsigned long op, void *buffer, unsigned long size,
46                      int *start, void *arg, unsigned long flag)
47 {
48     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
49 }
50
51 void
52 trap_unaligned(void)
53 {
54     unsigned int buf[2];
55
56     buf[0] = SSIN_UACPROC;
57     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
58     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
59 }
60 #else
61 void
62 trap_unaligned(void)
63 {  /* dummy */
64 }
65 #endif
66
67
68 u16
69 checksum_u16( unsigned n )
70 {
71     u16 a;
72
73     a  = (n >> 8) & 0xff;
74     if( opt.emulate_bugs & 1 ) {
75        a |= n & 0xff;
76        log_debug("csum_u16 emulated for n=%u\n", n);
77     }
78     else
79        a += n & 0xff;
80     return a;
81 }
82
83 static u16
84 checksum_u16_nobug( unsigned n )
85 {
86     u16 a;
87
88     a  = (n >> 8) & 0xff;
89     a += n & 0xff;
90     return a;
91 }
92
93 u16
94 checksum( byte *p, unsigned n )
95 {
96     u16 a;
97
98     for(a=0; n; n-- )
99         a += *p++;
100     return a;
101 }
102
103 u16
104 checksum_mpi( MPI a )
105 {
106     u16 csum;
107     byte *buffer;
108     unsigned nbytes;
109     unsigned nbits;
110
111     buffer = mpi_get_buffer( a, &nbytes, NULL );
112     /* some versions of gpg encode wrong values for the length of an mpi
113      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
114      * value than the one store with the mpi.  mpi_get_nbit_info() returns
115      * this stored value if it is still available.
116      */
117
118     if( opt.emulate_bugs & 1 )
119         nbits = 0;
120     else
121         nbits = mpi_get_nbit_info(a);
122     if( !nbits )
123        nbits = mpi_get_nbits(a);
124     csum = checksum_u16( nbits );
125     csum += checksum( buffer, nbytes );
126     m_free( buffer );
127     return csum;
128 }
129
130 /****************
131  * This is the correct function
132  */
133 u16
134 checksum_mpi_counted_nbits( MPI a )
135 {
136     u16 csum;
137     byte *buffer;
138     unsigned nbytes;
139     unsigned nbits;
140
141     buffer = mpi_get_buffer( a, &nbytes, NULL );
142     nbits = mpi_get_nbits(a);
143     csum = checksum_u16_nobug( nbits );
144     csum += checksum( buffer, nbytes );
145     m_free( buffer );
146     return csum;
147 }
148