Line data Source code
1 : /* mpicoder.c - Coder for the external representation of MPIs
2 : * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3 : * 2008 Free Software Foundation, Inc.
4 : * Copyright (C) 2013, 2014 g10 Code GmbH
5 : *
6 : * This file is part of Libgcrypt.
7 : *
8 : * Libgcrypt is free software; you can redistribute it and/or modify
9 : * it under the terms of the GNU Lesser General Public License as
10 : * published by the Free Software Foundation; either version 2.1 of
11 : * the License, or (at your option) any later version.
12 : *
13 : * Libgcrypt is distributed in the hope that it will be useful,
14 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : * GNU Lesser General Public License for more details.
17 : *
18 : * You should have received a copy of the GNU Lesser General Public
19 : * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include <config.h>
23 : #include <stdio.h>
24 : #include <string.h>
25 : #include <stdlib.h>
26 :
27 : #include "mpi-internal.h"
28 : #include "g10lib.h"
29 :
30 : #define MAX_EXTERN_MPI_BITS 16384
31 :
32 : /* Helper used to scan PGP style MPIs. Returns NULL on failure. */
33 : static gcry_mpi_t
34 12 : mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
35 : int secure)
36 : {
37 : int i, j;
38 12 : unsigned int nbits, nbytes, nlimbs, nread=0;
39 : mpi_limb_t a;
40 12 : gcry_mpi_t val = MPI_NULL;
41 :
42 12 : if ( *ret_nread < 2 )
43 0 : goto leave;
44 12 : nbits = buffer[0] << 8 | buffer[1];
45 12 : if ( nbits > MAX_EXTERN_MPI_BITS )
46 : {
47 : /* log_debug ("mpi too large (%u bits)\n", nbits); */
48 0 : goto leave;
49 : }
50 12 : buffer += 2;
51 12 : nread = 2;
52 :
53 12 : nbytes = (nbits+7) / 8;
54 12 : nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
55 12 : val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
56 12 : i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
57 12 : i %= BYTES_PER_MPI_LIMB;
58 12 : j= val->nlimbs = nlimbs;
59 12 : val->sign = 0;
60 23 : for ( ; j > 0; j-- )
61 : {
62 11 : a = 0;
63 29 : for (; i < BYTES_PER_MPI_LIMB; i++ )
64 : {
65 18 : if ( ++nread > *ret_nread )
66 : {
67 : /* log_debug ("mpi larger than buffer"); */
68 0 : mpi_free (val);
69 0 : val = NULL;
70 0 : goto leave;
71 : }
72 18 : a <<= 8;
73 18 : a |= *buffer++;
74 : }
75 11 : i = 0;
76 11 : val->d[j-1] = a;
77 : }
78 :
79 : leave:
80 12 : *ret_nread = nread;
81 12 : return val;
82 : }
83 :
84 :
85 : /****************
86 : * Fill the mpi VAL from the hex string in STR.
87 : */
88 : static int
89 17184 : mpi_fromstr (gcry_mpi_t val, const char *str)
90 : {
91 17184 : int sign = 0;
92 17184 : int prepend_zero = 0;
93 : int i, j, c, c1, c2;
94 : unsigned int nbits, nbytes, nlimbs;
95 : mpi_limb_t a;
96 :
97 17184 : if ( *str == '-' )
98 : {
99 4216 : sign = 1;
100 4216 : str++;
101 : }
102 :
103 : /* Skip optional hex prefix. */
104 17184 : if ( *str == '0' && str[1] == 'x' )
105 17001 : str += 2;
106 :
107 17184 : nbits = 4 * strlen (str);
108 17184 : if ((nbits % 8))
109 99 : prepend_zero = 1;
110 :
111 17184 : nbytes = (nbits+7) / 8;
112 17184 : nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
113 :
114 17184 : if ( val->alloced < nlimbs )
115 17184 : mpi_resize (val, nlimbs);
116 :
117 17184 : i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
118 17184 : i %= BYTES_PER_MPI_LIMB;
119 17184 : j = val->nlimbs = nlimbs;
120 17184 : val->sign = sign;
121 74851 : for (; j > 0; j--)
122 : {
123 57667 : a = 0;
124 483798 : for (; i < BYTES_PER_MPI_LIMB; i++)
125 : {
126 426131 : if (prepend_zero)
127 : {
128 99 : c1 = '0';
129 99 : prepend_zero = 0;
130 : }
131 : else
132 426032 : c1 = *str++;
133 :
134 426131 : if (!c1)
135 : {
136 0 : mpi_clear (val);
137 0 : return 1; /* Error. */
138 : }
139 426131 : c2 = *str++;
140 426131 : if (!c2)
141 : {
142 0 : mpi_clear (val);
143 0 : return 1; /* Error. */
144 : }
145 426131 : if ( c1 >= '0' && c1 <= '9' )
146 247001 : c = c1 - '0';
147 179130 : else if ( c1 >= 'a' && c1 <= 'f' )
148 39444 : c = c1 - 'a' + 10;
149 139686 : else if ( c1 >= 'A' && c1 <= 'F' )
150 139686 : c = c1 - 'A' + 10;
151 : else
152 : {
153 0 : mpi_clear (val);
154 0 : return 1; /* Error. */
155 : }
156 426131 : c <<= 4;
157 426131 : if ( c2 >= '0' && c2 <= '9' )
158 260055 : c |= c2 - '0';
159 166076 : else if( c2 >= 'a' && c2 <= 'f' )
160 39052 : c |= c2 - 'a' + 10;
161 127024 : else if( c2 >= 'A' && c2 <= 'F' )
162 127024 : c |= c2 - 'A' + 10;
163 : else
164 : {
165 0 : mpi_clear(val);
166 0 : return 1; /* Error. */
167 : }
168 426131 : a <<= 8;
169 426131 : a |= c;
170 : }
171 57667 : i = 0;
172 57667 : val->d[j-1] = a;
173 : }
174 :
175 17184 : return 0; /* Okay. */
176 : }
177 :
178 :
179 : /* Return an allocated buffer with the MPI (msb first). NBYTES
180 : receives the length of this buffer. If FILL_LE is not 0, the
181 : returned value is stored as little endian and right padded with
182 : zeroes so that the returned buffer has at least FILL_LE bytes.
183 :
184 : If EXTRAALLOC > 0 the returned buffer has these number of bytes
185 : extra allocated at the end; if EXTRAALLOC < 0 the returned buffer
186 : has the absolute value of EXTRAALLOC allocated at the begin of the
187 : buffer (the are not initialized) and the MPI is stored right after
188 : this. This feature is useful to allow the caller to prefix the
189 : returned value. EXTRAALLOC is _not_ included in the value stored
190 : at NBYTES.
191 :
192 : Caller must free the return string. This function returns an
193 : allocated buffer with NBYTES set to zero if the value of A is zero.
194 : If sign is not NULL, it will be set to the sign of the A. On error
195 : NULL is returned and ERRNO set appropriately. */
196 : static unsigned char *
197 9704 : do_get_buffer (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
198 : unsigned int *nbytes, int *sign, int force_secure)
199 : {
200 : unsigned char *p, *buffer, *retbuffer;
201 : unsigned int length, tmp;
202 : mpi_limb_t alimb;
203 : int i;
204 : size_t n, n2;
205 :
206 9704 : if (sign)
207 0 : *sign = a->sign;
208 :
209 9704 : *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
210 9704 : n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
211 9704 : if (n < fill_le)
212 0 : n = fill_le;
213 9704 : if (extraalloc < 0)
214 0 : n2 = n + -extraalloc;
215 : else
216 9704 : n2 = n + extraalloc;
217 :
218 9704 : retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
219 : : xtrymalloc (n2);
220 9704 : if (!retbuffer)
221 0 : return NULL;
222 9704 : if (extraalloc < 0)
223 0 : buffer = retbuffer + -extraalloc;
224 : else
225 9704 : buffer = retbuffer;
226 9704 : p = buffer;
227 :
228 85597 : for (i=a->nlimbs-1; i >= 0; i--)
229 : {
230 75893 : alimb = a->d[i];
231 : #if BYTES_PER_MPI_LIMB == 4
232 : *p++ = alimb >> 24;
233 : *p++ = alimb >> 16;
234 : *p++ = alimb >> 8;
235 : *p++ = alimb ;
236 : #elif BYTES_PER_MPI_LIMB == 8
237 75893 : *p++ = alimb >> 56;
238 75893 : *p++ = alimb >> 48;
239 75893 : *p++ = alimb >> 40;
240 75893 : *p++ = alimb >> 32;
241 75893 : *p++ = alimb >> 24;
242 75893 : *p++ = alimb >> 16;
243 75893 : *p++ = alimb >> 8;
244 75893 : *p++ = alimb ;
245 : #else
246 : # error please implement for this limb size.
247 : #endif
248 : }
249 :
250 9704 : if (fill_le)
251 : {
252 4144 : length = *nbytes;
253 : /* Reverse buffer and pad with zeroes. */
254 70448 : for (i=0; i < length/2; i++)
255 : {
256 66304 : tmp = buffer[i];
257 66304 : buffer[i] = buffer[length-1-i];
258 66304 : buffer[length-1-i] = tmp;
259 : }
260 : /* Pad with zeroes. */
261 4144 : for (p = buffer + length; length < fill_le; length++)
262 0 : *p++ = 0;
263 4144 : *nbytes = length;
264 :
265 4144 : return retbuffer;
266 : }
267 :
268 : /* This is sub-optimal but we need to do the shift operation because
269 : the caller has to free the returned buffer. */
270 5560 : for (p=buffer; *nbytes && !*p; p++, --*nbytes)
271 : ;
272 5560 : if (p != buffer)
273 2065 : memmove (buffer, p, *nbytes);
274 5560 : return retbuffer;
275 : }
276 :
277 :
278 : byte *
279 6596 : _gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
280 : unsigned int *r_nbytes, int *sign)
281 : {
282 6596 : return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
283 : }
284 :
285 : byte *
286 3108 : _gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
287 : unsigned int *r_nbytes, int *sign)
288 : {
289 3108 : return do_get_buffer (a, fill_le, extraalloc, r_nbytes, sign, 0);
290 : }
291 :
292 : byte *
293 0 : _gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
294 : unsigned int *r_nbytes, int *sign)
295 : {
296 0 : return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 1);
297 : }
298 :
299 :
300 : /*
301 : * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to
302 : * SIGN.
303 : */
304 : void
305 54852 : _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
306 : unsigned int nbytes, int sign)
307 : {
308 54852 : const unsigned char *buffer = (const unsigned char*)buffer_arg;
309 : const unsigned char *p;
310 : mpi_limb_t alimb;
311 : int nlimbs;
312 : int i;
313 :
314 54852 : if (mpi_is_immutable (a))
315 : {
316 0 : mpi_immutable_failed ();
317 0 : return;
318 : }
319 :
320 54852 : nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
321 54852 : RESIZE_IF_NEEDED(a, nlimbs);
322 54852 : a->sign = sign;
323 :
324 417909 : for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
325 : {
326 : #if BYTES_PER_MPI_LIMB == 4
327 : alimb = *p-- ;
328 : alimb |= *p-- << 8 ;
329 : alimb |= *p-- << 16 ;
330 : alimb |= *p-- << 24 ;
331 : #elif BYTES_PER_MPI_LIMB == 8
332 308205 : alimb = (mpi_limb_t)*p-- ;
333 308205 : alimb |= (mpi_limb_t)*p-- << 8 ;
334 308205 : alimb |= (mpi_limb_t)*p-- << 16 ;
335 308205 : alimb |= (mpi_limb_t)*p-- << 24 ;
336 308205 : alimb |= (mpi_limb_t)*p-- << 32 ;
337 308205 : alimb |= (mpi_limb_t)*p-- << 40 ;
338 308205 : alimb |= (mpi_limb_t)*p-- << 48 ;
339 308205 : alimb |= (mpi_limb_t)*p-- << 56 ;
340 : #else
341 : # error please implement for this limb size.
342 : #endif
343 308205 : a->d[i++] = alimb;
344 : }
345 54852 : if ( p >= buffer )
346 : {
347 : #if BYTES_PER_MPI_LIMB == 4
348 : alimb = *p--;
349 : if (p >= buffer)
350 : alimb |= *p-- << 8;
351 : if (p >= buffer)
352 : alimb |= *p-- << 16;
353 : if (p >= buffer)
354 : alimb |= *p-- << 24;
355 : #elif BYTES_PER_MPI_LIMB == 8
356 54852 : alimb = (mpi_limb_t)*p--;
357 54852 : if (p >= buffer)
358 48960 : alimb |= (mpi_limb_t)*p-- << 8;
359 54852 : if (p >= buffer)
360 48642 : alimb |= (mpi_limb_t)*p-- << 16;
361 54852 : if (p >= buffer)
362 46356 : alimb |= (mpi_limb_t)*p-- << 24;
363 54852 : if (p >= buffer)
364 18431 : alimb |= (mpi_limb_t)*p-- << 32;
365 54852 : if (p >= buffer)
366 16456 : alimb |= (mpi_limb_t)*p-- << 40;
367 54852 : if (p >= buffer)
368 15566 : alimb |= (mpi_limb_t)*p-- << 48;
369 54852 : if (p >= buffer)
370 15396 : alimb |= (mpi_limb_t)*p-- << 56;
371 : #else
372 : # error please implement for this limb size.
373 : #endif
374 54852 : a->d[i++] = alimb;
375 : }
376 54852 : a->nlimbs = i;
377 54852 : gcry_assert (i == nlimbs);
378 : }
379 :
380 :
381 : static void
382 27 : onecompl (gcry_mpi_t a)
383 : {
384 : mpi_ptr_t ap;
385 : mpi_size_t n;
386 : unsigned int i;
387 27 : unsigned int nbits = mpi_get_nbits (a);
388 :
389 27 : if (mpi_is_immutable (a))
390 : {
391 0 : mpi_immutable_failed ();
392 27 : return;
393 : }
394 :
395 27 : mpi_normalize (a);
396 27 : ap = a->d;
397 27 : n = a->nlimbs;
398 :
399 60 : for( i = 0; i < n; i++ )
400 33 : ap[i] ^= (mpi_limb_t)(-1);
401 :
402 27 : a->sign = 0;
403 27 : mpi_clear_highbit (a, nbits-1);
404 : }
405 :
406 :
407 : /* Perform a two's complement operation on buffer P of size N bytes. */
408 : static void
409 60 : twocompl (unsigned char *p, unsigned int n)
410 : {
411 : int i;
412 :
413 60 : for (i=n-1; i >= 0 && !p[i]; i--)
414 : ;
415 60 : if (i >= 0)
416 : {
417 60 : if ((p[i] & 0x01))
418 44 : p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
419 16 : else if ((p[i] & 0x02))
420 12 : p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
421 4 : else if ((p[i] & 0x04))
422 0 : p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
423 4 : else if ((p[i] & 0x08))
424 0 : p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
425 4 : else if ((p[i] & 0x10))
426 0 : p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
427 4 : else if ((p[i] & 0x20))
428 0 : p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
429 4 : else if ((p[i] & 0x40))
430 0 : p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
431 : else
432 4 : p[i] = 0x80;
433 :
434 324 : for (i--; i >= 0; i--)
435 264 : p[i] ^= 0xff;
436 : }
437 60 : }
438 :
439 :
440 : /* Convert the external representation of an integer stored in BUFFER
441 : with a length of BUFLEN into a newly create MPI returned in
442 : RET_MPI. If NBYTES is not NULL, it will receive the number of
443 : bytes actually scanned after a successful operation. */
444 : gcry_err_code_t
445 58709 : _gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
446 : const void *buffer_arg, size_t buflen, size_t *nscanned)
447 : {
448 58709 : const unsigned char *buffer = (const unsigned char*)buffer_arg;
449 58709 : struct gcry_mpi *a = NULL;
450 : unsigned int len;
451 58709 : int secure = (buffer && _gcry_is_secure (buffer));
452 :
453 58709 : if (format == GCRYMPI_FMT_SSH)
454 23 : len = 0;
455 : else
456 58686 : len = buflen;
457 :
458 58709 : if (format == GCRYMPI_FMT_STD)
459 : {
460 118 : const unsigned char *s = buffer;
461 :
462 118 : a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
463 : /BYTES_PER_MPI_LIMB)
464 118 : : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
465 118 : if (len)
466 : {
467 117 : _gcry_mpi_set_buffer (a, s, len, 0);
468 117 : a->sign = !!(*s & 0x80);
469 117 : if (a->sign)
470 : {
471 16 : onecompl (a);
472 16 : mpi_add_ui (a, a, 1);
473 16 : a->sign = 1;
474 : }
475 : }
476 118 : if (ret_mpi)
477 : {
478 118 : mpi_normalize ( a );
479 118 : *ret_mpi = a;
480 : }
481 : else
482 0 : mpi_free(a);
483 118 : if (nscanned)
484 23 : *nscanned = len;
485 118 : return 0;
486 : }
487 58591 : else if (format == GCRYMPI_FMT_USG)
488 : {
489 41372 : a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
490 : /BYTES_PER_MPI_LIMB)
491 41372 : : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
492 :
493 41372 : if (len)
494 41370 : _gcry_mpi_set_buffer (a, buffer, len, 0);
495 41372 : if (ret_mpi)
496 : {
497 41372 : mpi_normalize ( a );
498 41372 : *ret_mpi = a;
499 : }
500 : else
501 0 : mpi_free(a);
502 41372 : if (nscanned)
503 1124 : *nscanned = len;
504 41372 : return 0;
505 : }
506 17219 : else if (format == GCRYMPI_FMT_PGP)
507 : {
508 12 : a = mpi_read_from_buffer (buffer, &len, secure);
509 12 : if (nscanned)
510 12 : *nscanned = len;
511 12 : if (ret_mpi && a)
512 : {
513 12 : mpi_normalize (a);
514 12 : *ret_mpi = a;
515 : }
516 0 : else if (a)
517 : {
518 0 : mpi_free(a);
519 0 : a = NULL;
520 : }
521 12 : return a? 0 : GPG_ERR_INV_OBJ;
522 : }
523 17207 : else if (format == GCRYMPI_FMT_SSH)
524 : {
525 23 : const unsigned char *s = buffer;
526 : size_t n;
527 :
528 : /* This test is not strictly necessary and an assert (!len)
529 : would be sufficient. We keep this test in case we later
530 : allow the BUFLEN argument to act as a sanitiy check. Same
531 : below. */
532 23 : if (len && len < 4)
533 0 : return GPG_ERR_TOO_SHORT;
534 :
535 23 : n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
536 23 : s += 4;
537 23 : if (len)
538 0 : len -= 4;
539 23 : if (len && n > len)
540 0 : return GPG_ERR_TOO_LARGE;
541 :
542 23 : a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
543 : /BYTES_PER_MPI_LIMB)
544 23 : : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
545 23 : if (n)
546 : {
547 22 : _gcry_mpi_set_buffer( a, s, n, 0 );
548 22 : a->sign = !!(*s & 0x80);
549 22 : if (a->sign)
550 : {
551 11 : onecompl (a);
552 11 : mpi_add_ui (a, a, 1);
553 11 : a->sign = 1;
554 : }
555 : }
556 23 : if (nscanned)
557 23 : *nscanned = n+4;
558 23 : if (ret_mpi)
559 : {
560 23 : mpi_normalize ( a );
561 23 : *ret_mpi = a;
562 : }
563 : else
564 0 : mpi_free(a);
565 23 : return 0;
566 : }
567 17184 : else if (format == GCRYMPI_FMT_HEX)
568 : {
569 : /* We can only handle C strings for now. */
570 17184 : if (buflen)
571 0 : return GPG_ERR_INV_ARG;
572 :
573 17184 : a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
574 17184 : if (mpi_fromstr (a, (const char *)buffer))
575 : {
576 0 : mpi_free (a);
577 0 : return GPG_ERR_INV_OBJ;
578 : }
579 17184 : if (ret_mpi)
580 : {
581 17184 : mpi_normalize ( a );
582 17184 : *ret_mpi = a;
583 : }
584 : else
585 0 : mpi_free(a);
586 17184 : if (nscanned)
587 23 : *nscanned = strlen ((const char*)buffer);
588 17184 : return 0;
589 : }
590 : else
591 0 : return GPG_ERR_INV_ARG;
592 : }
593 :
594 :
595 : /* Convert the big integer A into the external representation
596 : described by FORMAT and store it in the provided BUFFER which has
597 : been allocated by the user with a size of BUFLEN bytes. NWRITTEN
598 : receives the actual length of the external representation unless it
599 : has been passed as NULL. BUFFER may be NULL to query the required
600 : length. */
601 : gcry_err_code_t
602 6288 : _gcry_mpi_print (enum gcry_mpi_format format,
603 : unsigned char *buffer, size_t buflen,
604 : size_t *nwritten, struct gcry_mpi *a)
605 : {
606 6288 : unsigned int nbits = mpi_get_nbits (a);
607 : size_t len;
608 : size_t dummy_nwritten;
609 : int negative;
610 :
611 6288 : if (!nwritten)
612 1298 : nwritten = &dummy_nwritten;
613 :
614 : /* Libgcrypt does no always care to set clear the sign if the value
615 : is 0. For printing this is a bit of a surprise, in particular
616 : because if some of the formats don't support negative numbers but
617 : should be able to print a zero. Thus we need this extra test
618 : for a negative number. */
619 6288 : if (a->sign && _gcry_mpi_cmp_ui (a, 0))
620 115 : negative = 1;
621 : else
622 6173 : negative = 0;
623 :
624 6288 : len = buflen;
625 6288 : *nwritten = 0;
626 6288 : if (format == GCRYMPI_FMT_STD)
627 : {
628 : unsigned char *tmp;
629 2120 : int extra = 0;
630 : unsigned int n;
631 :
632 2120 : tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
633 2120 : if (!tmp)
634 0 : return gpg_err_code_from_syserror ();
635 :
636 2120 : if (negative)
637 : {
638 38 : twocompl (tmp, n);
639 38 : if (!(*tmp & 0x80))
640 : {
641 : /* Need to extend the sign. */
642 6 : n++;
643 6 : extra = 2;
644 : }
645 : }
646 2082 : else if (n && (*tmp & 0x80))
647 : {
648 : /* Positive but the high bit of the returned buffer is set.
649 : Thus we need to print an extra leading 0x00 so that the
650 : output is interpreted as a positive number. */
651 948 : n++;
652 948 : extra = 1;
653 : }
654 :
655 2120 : if (buffer && n > len)
656 : {
657 : /* The provided buffer is too short. */
658 0 : xfree (tmp);
659 0 : return GPG_ERR_TOO_SHORT;
660 : }
661 2120 : if (buffer)
662 : {
663 1060 : unsigned char *s = buffer;
664 :
665 1060 : if (extra == 1)
666 474 : *s++ = 0;
667 586 : else if (extra)
668 3 : *s++ = 0xff;
669 1060 : memcpy (s, tmp, n-!!extra);
670 : }
671 2120 : xfree (tmp);
672 2120 : *nwritten = n;
673 2120 : return 0;
674 : }
675 4168 : else if (format == GCRYMPI_FMT_USG)
676 : {
677 4021 : unsigned int n = (nbits + 7)/8;
678 :
679 : /* Note: We ignore the sign for this format. */
680 : /* FIXME: for performance reasons we should put this into
681 : mpi_aprint because we can then use the buffer directly. */
682 :
683 4021 : if (buffer && n > len)
684 0 : return GPG_ERR_TOO_SHORT;
685 4021 : if (buffer)
686 : {
687 : unsigned char *tmp;
688 :
689 2230 : tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
690 2230 : if (!tmp)
691 0 : return gpg_err_code_from_syserror ();
692 2230 : memcpy (buffer, tmp, n);
693 2230 : xfree (tmp);
694 : }
695 4021 : *nwritten = n;
696 4021 : return 0;
697 : }
698 147 : else if (format == GCRYMPI_FMT_PGP)
699 : {
700 39 : unsigned int n = (nbits + 7)/8;
701 :
702 : /* The PGP format can only handle unsigned integers. */
703 39 : if (negative)
704 11 : return GPG_ERR_INV_ARG;
705 :
706 28 : if (buffer && n+2 > len)
707 0 : return GPG_ERR_TOO_SHORT;
708 :
709 28 : if (buffer)
710 : {
711 : unsigned char *tmp;
712 14 : unsigned char *s = buffer;
713 :
714 14 : s[0] = nbits >> 8;
715 14 : s[1] = nbits;
716 :
717 14 : tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
718 14 : if (!tmp)
719 0 : return gpg_err_code_from_syserror ();
720 14 : memcpy (s+2, tmp, n);
721 14 : xfree (tmp);
722 : }
723 28 : *nwritten = n+2;
724 28 : return 0;
725 : }
726 108 : else if (format == GCRYMPI_FMT_SSH)
727 : {
728 : unsigned char *tmp;
729 50 : int extra = 0;
730 : unsigned int n;
731 :
732 50 : tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
733 50 : if (!tmp)
734 0 : return gpg_err_code_from_syserror ();
735 :
736 50 : if (negative)
737 : {
738 22 : twocompl (tmp, n);
739 22 : if (!(*tmp & 0x80))
740 : {
741 : /* Need to extend the sign. */
742 6 : n++;
743 6 : extra = 2;
744 : }
745 : }
746 28 : else if (n && (*tmp & 0x80))
747 : {
748 8 : n++;
749 8 : extra=1;
750 : }
751 :
752 50 : if (buffer && n+4 > len)
753 : {
754 0 : xfree(tmp);
755 0 : return GPG_ERR_TOO_SHORT;
756 : }
757 :
758 50 : if (buffer)
759 : {
760 25 : unsigned char *s = buffer;
761 :
762 25 : *s++ = n >> 24;
763 25 : *s++ = n >> 16;
764 25 : *s++ = n >> 8;
765 25 : *s++ = n;
766 25 : if (extra == 1)
767 4 : *s++ = 0;
768 21 : else if (extra)
769 3 : *s++ = 0xff;
770 25 : memcpy (s, tmp, n-!!extra);
771 : }
772 50 : xfree (tmp);
773 50 : *nwritten = 4+n;
774 50 : return 0;
775 : }
776 58 : else if (format == GCRYMPI_FMT_HEX)
777 : {
778 : unsigned char *tmp;
779 : int i;
780 58 : int extra = 0;
781 58 : unsigned int n = 0;
782 :
783 58 : tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
784 58 : if (!tmp)
785 0 : return gpg_err_code_from_syserror ();
786 58 : if (!n || (*tmp & 0x80))
787 22 : extra = 2;
788 :
789 58 : if (buffer && 2*n + extra + negative + 1 > len)
790 : {
791 0 : xfree(tmp);
792 0 : return GPG_ERR_TOO_SHORT;
793 : }
794 58 : if (buffer)
795 : {
796 29 : unsigned char *s = buffer;
797 :
798 29 : if (negative)
799 11 : *s++ = '-';
800 29 : if (extra)
801 : {
802 11 : *s++ = '0';
803 11 : *s++ = '0';
804 : }
805 :
806 305 : for (i=0; i < n; i++)
807 : {
808 276 : unsigned int c = tmp[i];
809 :
810 276 : *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
811 276 : c &= 15;
812 276 : *s++ = c < 10? '0'+c : 'A'+c-10 ;
813 : }
814 29 : *s++ = 0;
815 29 : *nwritten = s - buffer;
816 : }
817 : else
818 : {
819 29 : *nwritten = 2*n + extra + negative + 1;
820 : }
821 58 : xfree (tmp);
822 58 : return 0;
823 : }
824 : else
825 0 : return GPG_ERR_INV_ARG;
826 : }
827 :
828 :
829 : /*
830 : * Like gcry_mpi_print but this function allocates the buffer itself.
831 : * The caller has to supply the address of a pointer. NWRITTEN may be
832 : * NULL.
833 : */
834 : gcry_err_code_t
835 129 : _gcry_mpi_aprint (enum gcry_mpi_format format,
836 : unsigned char **buffer, size_t *nwritten,
837 : struct gcry_mpi *a)
838 : {
839 : size_t n;
840 : gcry_err_code_t rc;
841 :
842 129 : *buffer = NULL;
843 129 : rc = _gcry_mpi_print (format, NULL, 0, &n, a);
844 129 : if (rc)
845 11 : return rc;
846 :
847 118 : *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
848 118 : if (!*buffer)
849 0 : return gpg_err_code_from_syserror ();
850 : /* If the returned buffer will have a length of 0, we nevertheless
851 : allocated 1 byte (malloc needs it anyway) and store a 0. */
852 118 : if (!n)
853 6 : **buffer = 0;
854 118 : rc = _gcry_mpi_print( format, *buffer, n, &n, a );
855 118 : if (rc)
856 : {
857 0 : xfree (*buffer);
858 0 : *buffer = NULL;
859 : }
860 118 : else if (nwritten)
861 81 : *nwritten = n;
862 118 : return rc;
863 : }
864 :
865 :
866 : /* Turn VALUE into an octet string and store it in an allocated buffer
867 : at R_FRAME or - if R_RAME is NULL - copy it into the caller
868 : provided buffer SPACE; either SPACE or R_FRAME may be used. If
869 : SPACE if not NULL, the caller must provide a buffer of at least
870 : NBYTES. If the resulting octet string is shorter than NBYTES pad
871 : it to the left with zeroes. If VALUE does not fit into NBYTES
872 : return an error code. */
873 : gpg_err_code_t
874 1154 : _gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
875 : gcry_mpi_t value, size_t nbytes)
876 : {
877 : gpg_err_code_t rc;
878 : size_t nframe, noff, n;
879 : unsigned char *frame;
880 :
881 1154 : if (!r_frame == !space)
882 0 : return GPG_ERR_INV_ARG; /* Only one may be used. */
883 :
884 1154 : if (r_frame)
885 1070 : *r_frame = NULL;
886 :
887 1154 : rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
888 1154 : if (rc)
889 0 : return rc;
890 1154 : if (nframe > nbytes)
891 0 : return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
892 :
893 1154 : noff = (nframe < nbytes)? nbytes - nframe : 0;
894 1154 : n = nframe + noff;
895 1154 : if (space)
896 84 : frame = space;
897 : else
898 : {
899 1070 : frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
900 1070 : if (!frame)
901 : {
902 0 : rc = gpg_err_code_from_syserror ();
903 0 : return rc;
904 : }
905 : }
906 1154 : if (noff)
907 197 : memset (frame, 0, noff);
908 1154 : nframe += noff;
909 1154 : rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
910 1154 : if (rc)
911 : {
912 0 : xfree (frame);
913 0 : return rc;
914 : }
915 :
916 1154 : if (r_frame)
917 1070 : *r_frame = frame;
918 1154 : return 0;
919 : }
|