diff options
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.c | 1300 |
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 | ||
34 | static gcry_mpi_t | 34 | static gcry_mpi_t |
35 | mpi_read_from_buffer (const unsigned char *buffer, unsigned int *ret_nread, | 35 | mpi_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 | */ |
90 | static int | 90 | static int |
91 | mpi_fromstr(gcry_mpi_t val, const char *str) | 91 | mpi_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. */ |
166 | void | 166 | void |
167 | gcry_mpi_dump (const gcry_mpi_t a) | 167 | gcry_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. */ |
200 | void | 200 | void |
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 | */ |
216 | static byte * | 216 | static byte * |
217 | do_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign, int force_secure ) | 217 | do_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 | ||
262 | byte * | 262 | byte * |
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 | ||
268 | byte * | 268 | byte * |
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 | */ |
277 | void | 277 | void |
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. */ |
339 | gcry_error_t | 339 | gcry_error_t |
340 | gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format, | 340 | gcry_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.*/ |
466 | gcry_error_t | 466 | gcry_error_t |
467 | gcry_mpi_print( enum gcry_mpi_format format, | 467 | gcry_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 | */ |
628 | gcry_error_t | 628 | gcry_error_t |
629 | gcry_mpi_aprint( enum gcry_mpi_format format, | 629 | gcry_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 | ||