Coverage Report

Created: 2022-12-08 06:09

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