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