aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c')
-rw-r--r--[-rwxr-xr-x]linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c1300
1 files changed, 650 insertions, 650 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c
index ba0255c..4a90850 100755..100644
--- a/linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c
+++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/mpi/mpicoder.c
@@ -1,650 +1,650 @@
1/* mpicoder.c - Coder for the external representation of MPIs 1/* mpicoder.c - Coder for the external representation of MPIs
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 Free Software Foundation, Inc. 3 * 2003 Free Software Foundation, Inc.
4 * 4 *
5 * This file is part of Libgcrypt. 5 * This file is part of Libgcrypt.
6 * 6 *
7 * Libgcrypt is free software; you can redistribute it and/or modify 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 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 9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
11 * 11 *
12 * Libgcrypt is distributed in the hope that it will be useful, 12 * Libgcrypt is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details. 15 * GNU Lesser General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU Lesser General Public 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 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 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 */ 20 */
21 21
22#include <config.h> 22#include <config.h>
23#include <stdio.h> 23#include <stdio.h>
24#include <string.h> 24#include <string.h>
25#include <stdlib.h> 25#include <stdlib.h>
26#include <assert.h> 26#include <assert.h>
27 27
28#include "mpi-internal.h" 28#include "mpi-internal.h"
29#include "g10lib.h" 29#include "g10lib.h"
30 30
31#define MAX_EXTERN_MPI_BITS 16384 31#define MAX_EXTERN_MPI_BITS 16384
32 32
33 33
34static gcry_mpi_t 34static gcry_mpi_t
35mpi_read_from_buffer (const unsigned char *buffer, unsigned int *ret_nread, 35mpi_read_from_buffer (const unsigned char *buffer, unsigned int *ret_nread,
36 int secure) 36 int secure)
37{ 37{
38 int i, j; 38 int i, j;
39 unsigned int nbits, nbytes, nlimbs, nread=0; 39 unsigned int nbits, nbytes, nlimbs, nread=0;
40 mpi_limb_t a; 40 mpi_limb_t a;
41 gcry_mpi_t val = MPI_NULL; 41 gcry_mpi_t val = MPI_NULL;
42 42
43 if (*ret_nread < 2) 43 if (*ret_nread < 2)
44 goto leave; 44 goto leave;
45 nbits = buffer[0] << 8 | buffer[1]; 45 nbits = buffer[0] << 8 | buffer[1];
46 if (nbits > MAX_EXTERN_MPI_BITS) 46 if (nbits > MAX_EXTERN_MPI_BITS)
47 { 47 {
48 log_error ("mpi too large (%u bits)\n", nbits); 48 log_error ("mpi too large (%u bits)\n", nbits);
49 goto leave; 49 goto leave;
50 } 50 }
51 else if (!nbits) 51 else if (!nbits)
52 { 52 {
53 log_error ("an mpi of size 0 is not allowed\n"); 53 log_error ("an mpi of size 0 is not allowed\n");
54 goto leave; 54 goto leave;
55 } 55 }
56 buffer += 2; 56 buffer += 2;
57 nread = 2; 57 nread = 2;
58 58
59 nbytes = (nbits+7) / 8; 59 nbytes = (nbits+7) / 8;
60 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; 60 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
61 val = secure? mpi_alloc_secure( nlimbs ) 61 val = secure? mpi_alloc_secure( nlimbs )
62 : mpi_alloc( nlimbs ); 62 : mpi_alloc( nlimbs );
63 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; 63 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
64 i %= BYTES_PER_MPI_LIMB; 64 i %= BYTES_PER_MPI_LIMB;
65 j= val->nlimbs = nlimbs; 65 j= val->nlimbs = nlimbs;
66 val->sign = 0; 66 val->sign = 0;
67 for( ; j > 0; j-- ) 67 for( ; j > 0; j-- )
68 { 68 {
69 a = 0; 69 a = 0;
70 for (; i < BYTES_PER_MPI_LIMB; i++ ) 70 for (; i < BYTES_PER_MPI_LIMB; i++ )
71 { 71 {
72 if ( ++nread > *ret_nread ) 72 if ( ++nread > *ret_nread )
73 log_bug ("mpi larger than buffer"); 73 log_bug ("mpi larger than buffer");
74 a <<= 8; 74 a <<= 8;
75 a |= *buffer++; 75 a |= *buffer++;
76 } 76 }
77 i = 0; 77 i = 0;
78 val->d[j-1] = a; 78 val->d[j-1] = a;
79 } 79 }
80 80
81 leave: 81 leave:
82 *ret_nread = nread; 82 *ret_nread = nread;
83 return val; 83 return val;
84} 84}
85 85
86 86
87/**************** 87/****************
88 * Make an mpi from a hex character string. 88 * Make an mpi from a hex character string.
89 */ 89 */
90static int 90static int
91mpi_fromstr(gcry_mpi_t val, const char *str) 91mpi_fromstr(gcry_mpi_t val, const char *str)
92{ 92{
93 int sign=0, prepend_zero=0, i, j, c, c1, c2; 93 int sign=0, prepend_zero=0, i, j, c, c1, c2;
94 unsigned nbits, nbytes, nlimbs; 94 unsigned nbits, nbytes, nlimbs;
95 mpi_limb_t a; 95 mpi_limb_t a;
96 96
97 if( *str == '-' ) { 97 if( *str == '-' ) {
98 sign = 1; 98 sign = 1;
99 str++; 99 str++;
100 } 100 }
101 101
102 /* skip optional hex prefix */ 102 /* skip optional hex prefix */
103 if ( *str == '0' && str[1] == 'x' ) { 103 if ( *str == '0' && str[1] == 'x' ) {
104 str += 2; 104 str += 2;
105 } 105 }
106 106
107 nbits = strlen(str)*4; 107 nbits = strlen(str)*4;
108 if( nbits % 8 ) 108 if( nbits % 8 )
109 prepend_zero = 1; 109 prepend_zero = 1;
110 nbytes = (nbits+7) / 8; 110 nbytes = (nbits+7) / 8;
111 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB; 111 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
112 if( val->alloced < nlimbs ) 112 if( val->alloced < nlimbs )
113 mpi_resize(val, nlimbs ); 113 mpi_resize(val, nlimbs );
114 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB; 114 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
115 i %= BYTES_PER_MPI_LIMB; 115 i %= BYTES_PER_MPI_LIMB;
116 j= val->nlimbs = nlimbs; 116 j= val->nlimbs = nlimbs;
117 val->sign = sign; 117 val->sign = sign;
118 for( ; j > 0; j-- ) { 118 for( ; j > 0; j-- ) {
119 a = 0; 119 a = 0;
120 for(; i < BYTES_PER_MPI_LIMB; i++ ) { 120 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
121 if( prepend_zero ) { 121 if( prepend_zero ) {
122 c1 = '0'; 122 c1 = '0';
123 prepend_zero = 0; 123 prepend_zero = 0;
124 } 124 }
125 else 125 else
126 c1 = *str++; 126 c1 = *str++;
127 assert(c1); 127 assert(c1);
128 c2 = *str++; 128 c2 = *str++;
129 assert(c2); 129 assert(c2);
130 if( c1 >= '0' && c1 <= '9' ) 130 if( c1 >= '0' && c1 <= '9' )
131 c = c1 - '0'; 131 c = c1 - '0';
132 else if( c1 >= 'a' && c1 <= 'f' ) 132 else if( c1 >= 'a' && c1 <= 'f' )
133 c = c1 - 'a' + 10; 133 c = c1 - 'a' + 10;
134 else if( c1 >= 'A' && c1 <= 'F' ) 134 else if( c1 >= 'A' && c1 <= 'F' )
135 c = c1 - 'A' + 10; 135 c = c1 - 'A' + 10;
136 else { 136 else {
137 mpi_clear(val); 137 mpi_clear(val);
138 return 1; 138 return 1;
139 } 139 }
140 c <<= 4; 140 c <<= 4;
141 if( c2 >= '0' && c2 <= '9' ) 141 if( c2 >= '0' && c2 <= '9' )
142 c |= c2 - '0'; 142 c |= c2 - '0';
143 else if( c2 >= 'a' && c2 <= 'f' ) 143 else if( c2 >= 'a' && c2 <= 'f' )
144 c |= c2 - 'a' + 10; 144 c |= c2 - 'a' + 10;
145 else if( c2 >= 'A' && c2 <= 'F' ) 145 else if( c2 >= 'A' && c2 <= 'F' )
146 c |= c2 - 'A' + 10; 146 c |= c2 - 'A' + 10;
147 else { 147 else {
148 mpi_clear(val); 148 mpi_clear(val);
149 return 1; 149 return 1;
150 } 150 }
151 a <<= 8; 151 a <<= 8;
152 a |= c; 152 a |= c;
153 } 153 }
154 i = 0; 154 i = 0;
155 val->d[j-1] = a; 155 val->d[j-1] = a;
156 } 156 }
157 157
158 return 0; 158 return 0;
159} 159}
160 160
161 161
162/* Dump the value of A in a format suitable for debugging to 162/* Dump the value of A in a format suitable for debugging to
163 Libgcrypt's logging stream. Note that one leading space but no 163 Libgcrypt's logging stream. Note that one leading space but no
164 trailing space or linefeed will be printed. It is okay to pass 164 trailing space or linefeed will be printed. It is okay to pass
165 NULL for A. */ 165 NULL for A. */
166void 166void
167gcry_mpi_dump (const gcry_mpi_t a) 167gcry_mpi_dump (const gcry_mpi_t a)
168{ 168{
169 int i; 169 int i;
170 170
171 log_printf (" "); 171 log_printf (" ");
172 if (!a) 172 if (!a)
173 log_printf ("[MPI_NULL]"); 173 log_printf ("[MPI_NULL]");
174 else 174 else
175 { 175 {
176 if (a->sign) 176 if (a->sign)
177 log_printf ( "-"); 177 log_printf ( "-");
178#if BYTES_PER_MPI_LIMB == 2 178#if BYTES_PER_MPI_LIMB == 2
179# define X "4" 179# define X "4"
180#elif BYTES_PER_MPI_LIMB == 4 180#elif BYTES_PER_MPI_LIMB == 4
181# define X "8" 181# define X "8"
182#elif BYTES_PER_MPI_LIMB == 8 182#elif BYTES_PER_MPI_LIMB == 8
183# define X "16" 183# define X "16"
184#elif BYTES_PER_MPI_LIMB == 16 184#elif BYTES_PER_MPI_LIMB == 16
185# define X "32" 185# define X "32"
186#else 186#else
187# error please define the format here 187# error please define the format here
188#endif 188#endif
189 for (i=a->nlimbs; i > 0 ; i-- ) 189 for (i=a->nlimbs; i > 0 ; i-- )
190 { 190 {
191 log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]); 191 log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
192 } 192 }
193#undef X 193#undef X
194 if (!a->nlimbs) 194 if (!a->nlimbs)
195 log_printf ("0"); 195 log_printf ("0");
196 } 196 }
197} 197}
198 198
199/* Convience function used internally. */ 199/* Convience function used internally. */
200void 200void
201_gcry_log_mpidump (const char *text, gcry_mpi_t a) 201_gcry_log_mpidump (const char *text, gcry_mpi_t a)
202{ 202{
203 log_printf ("%s:", text); 203 log_printf ("%s:", text);
204 gcry_mpi_dump (a); 204 gcry_mpi_dump (a);
205 log_printf ("\n"); 205 log_printf ("\n");
206} 206}
207 207
208 208
209/**************** 209/****************
210 * Return an m_alloced buffer with the MPI (msb first). 210 * Return an m_alloced buffer with the MPI (msb first).
211 * NBYTES receives the length of this buffer. Caller must free the 211 * NBYTES receives the length of this buffer. Caller must free the
212 * return string (This function does return a 0 byte buffer with NBYTES 212 * return string (This function does return a 0 byte buffer with NBYTES
213 * set to zero if the value of A is zero. If sign is not NULL, it will 213 * set to zero if the value of A is zero. If sign is not NULL, it will
214 * be set to the sign of the A. 214 * be set to the sign of the A.
215 */ 215 */
216static byte * 216static byte *
217do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure ) 217do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure )
218{ 218{
219 byte *p, *buffer; 219 byte *p, *buffer;
220 mpi_limb_t alimb; 220 mpi_limb_t alimb;
221 int i; 221 int i;
222 size_t n; 222 size_t n;
223 223
224 if( sign ) 224 if( sign )
225 *sign = a->sign; 225 *sign = a->sign;
226 *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; 226 *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
227 n = *nbytes? *nbytes:1; /* allocate at least one byte */ 227 n = *nbytes? *nbytes:1; /* allocate at least one byte */
228 p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n) 228 p = buffer = force_secure || mpi_is_secure(a) ? gcry_xmalloc_secure(n)
229 : gcry_xmalloc(n); 229 : gcry_xmalloc(n);
230 230
231 for(i=a->nlimbs-1; i >= 0; i-- ) { 231 for(i=a->nlimbs-1; i >= 0; i-- ) {
232 alimb = a->d[i]; 232 alimb = a->d[i];
233#if BYTES_PER_MPI_LIMB == 4 233#if BYTES_PER_MPI_LIMB == 4
234 *p++ = alimb >> 24; 234 *p++ = alimb >> 24;
235 *p++ = alimb >> 16; 235 *p++ = alimb >> 16;
236 *p++ = alimb >> 8; 236 *p++ = alimb >> 8;
237 *p++ = alimb ; 237 *p++ = alimb ;
238#elif BYTES_PER_MPI_LIMB == 8 238#elif BYTES_PER_MPI_LIMB == 8
239 *p++ = alimb >> 56; 239 *p++ = alimb >> 56;
240 *p++ = alimb >> 48; 240 *p++ = alimb >> 48;
241 *p++ = alimb >> 40; 241 *p++ = alimb >> 40;
242 *p++ = alimb >> 32; 242 *p++ = alimb >> 32;
243 *p++ = alimb >> 24; 243 *p++ = alimb >> 24;
244 *p++ = alimb >> 16; 244 *p++ = alimb >> 16;
245 *p++ = alimb >> 8; 245 *p++ = alimb >> 8;
246 *p++ = alimb ; 246 *p++ = alimb ;
247#else 247#else
248 #error please implement for this limb size. 248 #error please implement for this limb size.
249#endif 249#endif
250 } 250 }
251 251
252 /* this is sub-optimal but we need to do the shift oepration because 252 /* this is sub-optimal but we need to do the shift oepration because
253 * the caller has to free the returned buffer */ 253 * the caller has to free the returned buffer */
254 for(p=buffer; !*p && *nbytes; p++, --*nbytes ) 254 for(p=buffer; !*p && *nbytes; p++, --*nbytes )
255 ; 255 ;
256 if( p != buffer ) 256 if( p != buffer )
257 memmove(buffer,p, *nbytes); 257 memmove(buffer,p, *nbytes);
258 return buffer; 258 return buffer;
259} 259}
260 260
261 261
262byte * 262byte *
263_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) 263_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
264{ 264{
265 return do_get_buffer( a, nbytes, sign, 0 ); 265 return do_get_buffer( a, nbytes, sign, 0 );
266} 266}
267 267
268byte * 268byte *
269_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign ) 269_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign )
270{ 270{
271 return do_get_buffer( a, nbytes, sign, 1 ); 271 return do_get_buffer( a, nbytes, sign, 1 );
272} 272}
273 273
274/**************** 274/****************
275 * Use BUFFER to update MPI. 275 * Use BUFFER to update MPI.
276 */ 276 */
277void 277void
278_gcry_mpi_set_buffer( gcry_mpi_t a, const byte *buffer, unsigned nbytes, int sign ) 278_gcry_mpi_set_buffer( gcry_mpi_t a, const byte *buffer, unsigned nbytes, int sign )
279{ 279{
280 const byte *p; 280 const byte *p;
281 mpi_limb_t alimb; 281 mpi_limb_t alimb;
282 int nlimbs; 282 int nlimbs;
283 int i; 283 int i;
284 284
285 nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB; 285 nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
286 RESIZE_IF_NEEDED(a, nlimbs); 286 RESIZE_IF_NEEDED(a, nlimbs);
287 a->sign = sign; 287 a->sign = sign;
288 288
289 for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) { 289 for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
290#if BYTES_PER_MPI_LIMB == 4 290#if BYTES_PER_MPI_LIMB == 4
291 alimb = *p-- ; 291 alimb = *p-- ;
292 alimb |= *p-- << 8 ; 292 alimb |= *p-- << 8 ;
293 alimb |= *p-- << 16 ; 293 alimb |= *p-- << 16 ;
294 alimb |= *p-- << 24 ; 294 alimb |= *p-- << 24 ;
295#elif BYTES_PER_MPI_LIMB == 8 295#elif BYTES_PER_MPI_LIMB == 8
296 alimb = (mpi_limb_t)*p-- ; 296 alimb = (mpi_limb_t)*p-- ;
297 alimb |= (mpi_limb_t)*p-- << 8 ; 297 alimb |= (mpi_limb_t)*p-- << 8 ;
298 alimb |= (mpi_limb_t)*p-- << 16 ; 298 alimb |= (mpi_limb_t)*p-- << 16 ;
299 alimb |= (mpi_limb_t)*p-- << 24 ; 299 alimb |= (mpi_limb_t)*p-- << 24 ;
300 alimb |= (mpi_limb_t)*p-- << 32 ; 300 alimb |= (mpi_limb_t)*p-- << 32 ;
301 alimb |= (mpi_limb_t)*p-- << 40 ; 301 alimb |= (mpi_limb_t)*p-- << 40 ;
302 alimb |= (mpi_limb_t)*p-- << 48 ; 302 alimb |= (mpi_limb_t)*p-- << 48 ;
303 alimb |= (mpi_limb_t)*p-- << 56 ; 303 alimb |= (mpi_limb_t)*p-- << 56 ;
304#else 304#else
305 #error please implement for this limb size. 305 #error please implement for this limb size.
306#endif 306#endif
307 a->d[i++] = alimb; 307 a->d[i++] = alimb;
308 } 308 }
309 if( p >= buffer ) { 309 if( p >= buffer ) {
310#if BYTES_PER_MPI_LIMB == 4 310#if BYTES_PER_MPI_LIMB == 4
311 alimb = *p-- ; 311 alimb = *p-- ;
312 if( p >= buffer ) alimb |= *p-- << 8 ; 312 if( p >= buffer ) alimb |= *p-- << 8 ;
313 if( p >= buffer ) alimb |= *p-- << 16 ; 313 if( p >= buffer ) alimb |= *p-- << 16 ;
314 if( p >= buffer ) alimb |= *p-- << 24 ; 314 if( p >= buffer ) alimb |= *p-- << 24 ;
315#elif BYTES_PER_MPI_LIMB == 8 315#elif BYTES_PER_MPI_LIMB == 8
316 alimb = (mpi_limb_t)*p-- ; 316 alimb = (mpi_limb_t)*p-- ;
317 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ; 317 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
318 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ; 318 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
319 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ; 319 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
320 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ; 320 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
321 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ; 321 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
322 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ; 322 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
323 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ; 323 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
324#else 324#else
325 #error please implement for this limb size. 325 #error please implement for this limb size.
326#endif 326#endif
327 a->d[i++] = alimb; 327 a->d[i++] = alimb;
328 } 328 }
329 a->nlimbs = i; 329 a->nlimbs = i;
330 assert( i == nlimbs ); 330 assert( i == nlimbs );
331} 331}
332 332
333 333
334 334
335/* Convert the external representation of an integer stored in BUFFER 335/* Convert the external representation of an integer stored in BUFFER
336 with a length of BUFLEN into a newly create MPI returned in 336 with a length of BUFLEN into a newly create MPI returned in
337 RET_MPI. If NBYTES is not NULL, it will receive the number of 337 RET_MPI. If NBYTES is not NULL, it will receive the number of
338 bytes actually scanned after a successful operation. */ 338 bytes actually scanned after a successful operation. */
339gcry_error_t 339gcry_error_t
340gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, 340gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
341 const void *buffer_arg, size_t buflen, size_t *nscanned ) 341 const void *buffer_arg, size_t buflen, size_t *nscanned )
342{ 342{
343 const unsigned char *buffer = (const unsigned char*)buffer_arg; 343 const unsigned char *buffer = (const unsigned char*)buffer_arg;
344 struct gcry_mpi *a = NULL; 344 struct gcry_mpi *a = NULL;
345 unsigned int len; 345 unsigned int len;
346 int secure = (buffer && gcry_is_secure (buffer)); 346 int secure = (buffer && gcry_is_secure (buffer));
347 347
348 if (format == GCRYMPI_FMT_SSH) 348 if (format == GCRYMPI_FMT_SSH)
349 len = 0; 349 len = 0;
350 else 350 else
351 len = buflen; 351 len = buflen;
352 352
353 if( format == GCRYMPI_FMT_STD ) { 353 if( format == GCRYMPI_FMT_STD ) {
354 const byte *s = buffer; 354 const byte *s = buffer;
355 355
356 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) 356 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
357 /BYTES_PER_MPI_LIMB) 357 /BYTES_PER_MPI_LIMB)
358 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); 358 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
359 if( len ) { /* not zero */ 359 if( len ) { /* not zero */
360 a->sign = *s & 0x80; 360 a->sign = *s & 0x80;
361 if( a->sign ) { 361 if( a->sign ) {
362 /* FIXME: we have to convert from 2compl to magnitude format */ 362 /* FIXME: we have to convert from 2compl to magnitude format */
363 mpi_free(a); 363 mpi_free(a);
364 return gcry_error (GPG_ERR_INTERNAL); 364 return gcry_error (GPG_ERR_INTERNAL);
365 } 365 }
366 else 366 else
367 _gcry_mpi_set_buffer( a, s, len, 0 ); 367 _gcry_mpi_set_buffer( a, s, len, 0 );
368 } 368 }
369 if( ret_mpi ) { 369 if( ret_mpi ) {
370 mpi_normalize ( a ); 370 mpi_normalize ( a );
371 *ret_mpi = a; 371 *ret_mpi = a;
372 } 372 }
373 else 373 else
374 mpi_free(a); 374 mpi_free(a);
375 return gcry_error (GPG_ERR_NO_ERROR); 375 return gcry_error (GPG_ERR_NO_ERROR);
376 } 376 }
377 else if( format == GCRYMPI_FMT_USG ) { 377 else if( format == GCRYMPI_FMT_USG ) {
378 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1) 378 a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
379 /BYTES_PER_MPI_LIMB) 379 /BYTES_PER_MPI_LIMB)
380 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); 380 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
381 381
382 if( len ) /* not zero */ 382 if( len ) /* not zero */
383 _gcry_mpi_set_buffer( a, buffer, len, 0 ); 383 _gcry_mpi_set_buffer( a, buffer, len, 0 );
384 if( ret_mpi ) { 384 if( ret_mpi ) {
385 mpi_normalize ( a ); 385 mpi_normalize ( a );
386 *ret_mpi = a; 386 *ret_mpi = a;
387 } 387 }
388 else 388 else
389 mpi_free(a); 389 mpi_free(a);
390 return gcry_error (GPG_ERR_NO_ERROR); 390 return gcry_error (GPG_ERR_NO_ERROR);
391 } 391 }
392 else if( format == GCRYMPI_FMT_PGP ) { 392 else if( format == GCRYMPI_FMT_PGP ) {
393 a = mpi_read_from_buffer (buffer, &len, secure); 393 a = mpi_read_from_buffer (buffer, &len, secure);
394 if( nscanned ) 394 if( nscanned )
395 *nscanned = len; 395 *nscanned = len;
396 if( ret_mpi && a ) { 396 if( ret_mpi && a ) {
397 mpi_normalize ( a ); 397 mpi_normalize ( a );
398 *ret_mpi = a; 398 *ret_mpi = a;
399 } 399 }
400 else 400 else
401 mpi_free(a); 401 mpi_free(a);
402 return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ); 402 return gcry_error (a ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ);
403 } 403 }
404 else if( format == GCRYMPI_FMT_SSH ) { 404 else if( format == GCRYMPI_FMT_SSH ) {
405 const unsigned char *s = buffer; 405 const unsigned char *s = buffer;
406 size_t n; 406 size_t n;
407 407
408 if( len && len < 4 ) 408 if( len && len < 4 )
409 return gcry_error (GPG_ERR_TOO_SHORT); 409 return gcry_error (GPG_ERR_TOO_SHORT);
410 n = s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; 410 n = s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3];
411 s += 4; 411 s += 4;
412 if (len) 412 if (len)
413 len -= 4; 413 len -= 4;
414 if( len && n > len ) 414 if( len && n > len )
415 return gcry_error (GPG_ERR_TOO_LARGE); /* or should it be 415 return gcry_error (GPG_ERR_TOO_LARGE); /* or should it be
416 too_short */ 416 too_short */
417 417
418 a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1) 418 a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
419 /BYTES_PER_MPI_LIMB) 419 /BYTES_PER_MPI_LIMB)
420 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB); 420 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
421 if( n ) { /* not zero */ 421 if( n ) { /* not zero */
422 a->sign = *s & 0x80; 422 a->sign = *s & 0x80;
423 if( a->sign ) { 423 if( a->sign ) {
424 /* FIXME: we have to convert from 2compl to magnitude format */ 424 /* FIXME: we have to convert from 2compl to magnitude format */
425 mpi_free(a); 425 mpi_free(a);
426 return gcry_error (GPG_ERR_INTERNAL); 426 return gcry_error (GPG_ERR_INTERNAL);
427 } 427 }
428 else 428 else
429 _gcry_mpi_set_buffer( a, s, n, 0 ); 429 _gcry_mpi_set_buffer( a, s, n, 0 );
430 } 430 }
431 if( nscanned ) 431 if( nscanned )
432 *nscanned = n+4; 432 *nscanned = n+4;
433 if( ret_mpi ) { 433 if( ret_mpi ) {
434 mpi_normalize ( a ); 434 mpi_normalize ( a );
435 *ret_mpi = a; 435 *ret_mpi = a;
436 } 436 }
437 else 437 else
438 mpi_free(a); 438 mpi_free(a);
439 return gcry_error (GPG_ERR_NO_ERROR); 439 return gcry_error (GPG_ERR_NO_ERROR);
440 } 440 }
441 else if( format == GCRYMPI_FMT_HEX ) { 441 else if( format == GCRYMPI_FMT_HEX ) {
442 if( buflen ) 442 if( buflen )
443 return gcry_error (GPG_ERR_INV_ARG); /* can only handle C 443 return gcry_error (GPG_ERR_INV_ARG); /* can only handle C
444 strings for now */ 444 strings for now */
445 a = secure? mpi_alloc_secure (0) : mpi_alloc(0); 445 a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
446 if( mpi_fromstr ( a, (const char *)buffer ) ) 446 if( mpi_fromstr ( a, (const char *)buffer ) )
447 return gcry_error (GPG_ERR_INV_OBJ); 447 return gcry_error (GPG_ERR_INV_OBJ);
448 if( ret_mpi ) { 448 if( ret_mpi ) {
449 mpi_normalize ( a ); 449 mpi_normalize ( a );
450 *ret_mpi = a; 450 *ret_mpi = a;
451 } 451 }
452 else 452 else
453 mpi_free(a); 453 mpi_free(a);
454 return gcry_error (GPG_ERR_NO_ERROR); 454 return gcry_error (GPG_ERR_NO_ERROR);
455 } 455 }
456 else 456 else
457 return gcry_error (GPG_ERR_INV_ARG); 457 return gcry_error (GPG_ERR_INV_ARG);
458} 458}
459 459
460/* Convert the big integer A into the external representation 460/* Convert the big integer A into the external representation
461 described by FORMAT and store it in the provided BUFFER which has 461 described by FORMAT and store it in the provided BUFFER which has
462 been allocated by the user with a size of BUFLEN bytes. NWRITTEN 462 been allocated by the user with a size of BUFLEN bytes. NWRITTEN
463 receives the actual length of the external representation unless it 463 receives the actual length of the external representation unless it
464 has been passed as NULL. BUFFER may be NULL to query the required 464 has been passed as NULL. BUFFER may be NULL to query the required
465 length.*/ 465 length.*/
466gcry_error_t 466gcry_error_t
467gcry_mpi_print( enum gcry_mpi_format format, 467gcry_mpi_print( enum gcry_mpi_format format,
468 unsigned char *buffer, size_t buflen, 468 unsigned char *buffer, size_t buflen,
469 size_t *nwritten, struct gcry_mpi *a) 469 size_t *nwritten, struct gcry_mpi *a)
470{ 470{
471 unsigned int nbits = mpi_get_nbits(a); 471 unsigned int nbits = mpi_get_nbits(a);
472 size_t len; 472 size_t len;
473 size_t dummy_nwritten; 473 size_t dummy_nwritten;
474 474
475 if (!nwritten) 475 if (!nwritten)
476 nwritten = &dummy_nwritten; 476 nwritten = &dummy_nwritten;
477 477
478 len = buflen; 478 len = buflen;
479 *nwritten = 0; 479 *nwritten = 0;
480 if( format == GCRYMPI_FMT_STD ) { 480 if( format == GCRYMPI_FMT_STD ) {
481 unsigned char *tmp; 481 unsigned char *tmp;
482 int extra = 0; 482 int extra = 0;
483 unsigned int n; 483 unsigned int n;
484 484
485 if( a->sign ) 485 if( a->sign )
486 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ 486 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
487 487
488 tmp = _gcry_mpi_get_buffer( a, &n, NULL ); 488 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
489 if( n && (*tmp & 0x80) ) { 489 if( n && (*tmp & 0x80) ) {
490 n++; 490 n++;
491 extra=1; 491 extra=1;
492 } 492 }
493 493
494 if (buffer && n > len) { 494 if (buffer && n > len) {
495 /* The provided buffer is too short. */ 495 /* The provided buffer is too short. */
496 gcry_free(tmp); 496 gcry_free(tmp);
497 return gcry_error (GPG_ERR_TOO_SHORT); 497 return gcry_error (GPG_ERR_TOO_SHORT);
498 } 498 }
499 if( buffer ) { 499 if( buffer ) {
500 byte *s = buffer; 500 byte *s = buffer;
501 if( extra ) 501 if( extra )
502 *s++ = 0; 502 *s++ = 0;
503 503
504 memcpy( s, tmp, n-extra ); 504 memcpy( s, tmp, n-extra );
505 } 505 }
506 gcry_free(tmp); 506 gcry_free(tmp);
507 *nwritten = n; 507 *nwritten = n;
508 return gcry_error (GPG_ERR_NO_ERROR); 508 return gcry_error (GPG_ERR_NO_ERROR);
509 } 509 }
510 else if( format == GCRYMPI_FMT_USG ) { 510 else if( format == GCRYMPI_FMT_USG ) {
511 unsigned int n = (nbits + 7)/8; 511 unsigned int n = (nbits + 7)/8;
512 512
513 /* we ignore the sign for this format */ 513 /* we ignore the sign for this format */
514 /* FIXME: for performance reasons we should put this into 514 /* FIXME: for performance reasons we should put this into
515 * mpi_aprint becuase we can then use the buffer directly */ 515 * mpi_aprint becuase we can then use the buffer directly */
516 if (buffer && n > len) 516 if (buffer && n > len)
517 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ 517 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
518 if( buffer ) { 518 if( buffer ) {
519 unsigned char *tmp; 519 unsigned char *tmp;
520 tmp = _gcry_mpi_get_buffer( a, &n, NULL ); 520 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
521 memcpy( buffer, tmp, n ); 521 memcpy( buffer, tmp, n );
522 gcry_free(tmp); 522 gcry_free(tmp);
523 } 523 }
524 *nwritten = n; 524 *nwritten = n;
525 return gcry_error (GPG_ERR_NO_ERROR); 525 return gcry_error (GPG_ERR_NO_ERROR);
526 } 526 }
527 else if( format == GCRYMPI_FMT_PGP ) { 527 else if( format == GCRYMPI_FMT_PGP ) {
528 unsigned int n = (nbits + 7)/8; 528 unsigned int n = (nbits + 7)/8;
529 529
530 if( a->sign ) 530 if( a->sign )
531 return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */ 531 return gcry_error (GPG_ERR_INV_ARG); /* pgp format can only handle unsigned */
532 532
533 if (buffer && n+2 > len) 533 if (buffer && n+2 > len)
534 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ 534 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
535 if( buffer ) { 535 if( buffer ) {
536 unsigned char *tmp; 536 unsigned char *tmp;
537 unsigned char *s = buffer; 537 unsigned char *s = buffer;
538 s[0] = nbits >> 8; 538 s[0] = nbits >> 8;
539 s[1] = nbits; 539 s[1] = nbits;
540 540
541 tmp = _gcry_mpi_get_buffer( a, &n, NULL ); 541 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
542 memcpy( s+2, tmp, n ); 542 memcpy( s+2, tmp, n );
543 gcry_free(tmp); 543 gcry_free(tmp);
544 } 544 }
545 *nwritten = n+2; 545 *nwritten = n+2;
546 return gcry_error (GPG_ERR_NO_ERROR); 546 return gcry_error (GPG_ERR_NO_ERROR);
547 } 547 }
548 else if( format == GCRYMPI_FMT_SSH ) { 548 else if( format == GCRYMPI_FMT_SSH ) {
549 unsigned char *tmp; 549 unsigned char *tmp;
550 int extra = 0; 550 int extra = 0;
551 unsigned int n; 551 unsigned int n;
552 552
553 if( a->sign ) 553 if( a->sign )
554 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */ 554 return gcry_error (GPG_ERR_INTERNAL); /* can't handle it yet */
555 555
556 tmp = _gcry_mpi_get_buffer( a, &n, NULL ); 556 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
557 if( n && (*tmp & 0x80) ) { 557 if( n && (*tmp & 0x80) ) {
558 n++; 558 n++;
559 extra=1; 559 extra=1;
560 } 560 }
561 561
562 if (buffer && n+4 > len) { 562 if (buffer && n+4 > len) {
563 gcry_free(tmp); 563 gcry_free(tmp);
564 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ 564 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
565 } 565 }
566 if( buffer ) { 566 if( buffer ) {
567 byte *s = buffer; 567 byte *s = buffer;
568 *s++ = n >> 24; 568 *s++ = n >> 24;
569 *s++ = n >> 16; 569 *s++ = n >> 16;
570 *s++ = n >> 8; 570 *s++ = n >> 8;
571 *s++ = n; 571 *s++ = n;
572 if( extra ) 572 if( extra )
573 *s++ = 0; 573 *s++ = 0;
574 574
575 memcpy( s, tmp, n-extra ); 575 memcpy( s, tmp, n-extra );
576 } 576 }
577 gcry_free(tmp); 577 gcry_free(tmp);
578 *nwritten = 4+n; 578 *nwritten = 4+n;
579 return gcry_error (GPG_ERR_NO_ERROR); 579 return gcry_error (GPG_ERR_NO_ERROR);
580 } 580 }
581 else if( format == GCRYMPI_FMT_HEX ) { 581 else if( format == GCRYMPI_FMT_HEX ) {
582 byte *tmp; 582 byte *tmp;
583 int i; 583 int i;
584 int extra = 0; 584 int extra = 0;
585 unsigned int n=0; 585 unsigned int n=0;
586 586
587 tmp = _gcry_mpi_get_buffer( a, &n, NULL ); 587 tmp = _gcry_mpi_get_buffer( a, &n, NULL );
588 if( !n || (*tmp & 0x80) ) 588 if( !n || (*tmp & 0x80) )
589 extra=2; 589 extra=2;
590 590
591 if(buffer && 2*n + extra + !!a->sign + 1 > len) { 591 if(buffer && 2*n + extra + !!a->sign + 1 > len) {
592 gcry_free(tmp); 592 gcry_free(tmp);
593 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */ 593 return gcry_error (GPG_ERR_TOO_SHORT); /* the provided buffer is too short */
594 } 594 }
595 if( buffer ) { 595 if( buffer ) {
596 byte *s = buffer; 596 byte *s = buffer;
597 if( a->sign ) 597 if( a->sign )
598 *s++ = '-'; 598 *s++ = '-';
599 if( extra ) { 599 if( extra ) {
600 *s++ = '0'; 600 *s++ = '0';
601 *s++ = '0'; 601 *s++ = '0';
602 } 602 }
603 603
604 for(i=0; i < n; i++ ) { 604 for(i=0; i < n; i++ ) {
605 unsigned int c = tmp[i]; 605 unsigned int c = tmp[i];
606 *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ; 606 *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
607 c &= 15; 607 c &= 15;
608 *s++ = c < 10? '0'+c : 'A'+c-10 ; 608 *s++ = c < 10? '0'+c : 'A'+c-10 ;
609 } 609 }
610 *s++ = 0; 610 *s++ = 0;
611 *nwritten = s - buffer; 611 *nwritten = s - buffer;
612 } 612 }
613 else { 613 else {
614 *nwritten = 2*n + extra + !!a->sign + 1; 614 *nwritten = 2*n + extra + !!a->sign + 1;
615 } 615 }
616 gcry_free(tmp); 616 gcry_free(tmp);
617 return gcry_error (GPG_ERR_NO_ERROR); 617 return gcry_error (GPG_ERR_NO_ERROR);
618 } 618 }
619 else 619 else
620 return gcry_error (GPG_ERR_INV_ARG); 620 return gcry_error (GPG_ERR_INV_ARG);
621} 621}
622 622
623/**************** 623/****************
624 * Like gcry_mpi_print but this function allocates the buffer itself. 624 * Like gcry_mpi_print but this function allocates the buffer itself.
625 * The caller has to supply the address of a pointer. NWRITTEN may be 625 * The caller has to supply the address of a pointer. NWRITTEN may be
626 * NULL. 626 * NULL.
627 */ 627 */
628gcry_error_t 628gcry_error_t
629gcry_mpi_aprint( enum gcry_mpi_format format, 629gcry_mpi_aprint( enum gcry_mpi_format format,
630 unsigned char **buffer, size_t *nwritten, 630 unsigned char **buffer, size_t *nwritten,
631 struct gcry_mpi *a ) 631 struct gcry_mpi *a )
632{ 632{
633 size_t n; 633 size_t n;
634 gcry_error_t rc; 634 gcry_error_t rc;
635 635
636 *buffer = NULL; 636 *buffer = NULL;
637 rc = gcry_mpi_print( format, NULL, 0, &n, a ); 637 rc = gcry_mpi_print( format, NULL, 0, &n, a );
638 if( rc ) 638 if( rc )
639 return rc; 639 return rc;
640 *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n ); 640 *buffer = mpi_is_secure(a) ? gcry_xmalloc_secure( n ) : gcry_xmalloc( n );
641 rc = gcry_mpi_print( format, *buffer, n, &n, a ); 641 rc = gcry_mpi_print( format, *buffer, n, &n, a );
642 if( rc ) { 642 if( rc ) {
643 gcry_free(*buffer); 643 gcry_free(*buffer);
644 *buffer = NULL; 644 *buffer = NULL;
645 } 645 }
646 else if( nwritten ) 646 else if( nwritten )
647 *nwritten = n; 647 *nwritten = n;
648 return rc; 648 return rc;
649} 649}
650 650