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
79.8k
#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
79.8k
#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
79.8k
{
51
79.8k
  int i, j;
52
79.8k
  unsigned int nbits, nbytes, nlimbs, nread=0;
53
79.8k
  mpi_limb_t a;
54
79.8k
  gcry_mpi_t val = MPI_NULL;
55
79.8k
  unsigned int max_nread = *ret_nread;
56
57
79.8k
  if ( max_nread < 2 )
58
0
    goto leave;
59
79.8k
  nbits = buffer[0] << 8 | buffer[1];
60
79.8k
  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
79.8k
  buffer += 2;
66
79.8k
  nread = 2;
67
68
79.8k
  nbytes = (nbits+7) / 8;
69
79.8k
  nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
70
79.8k
  val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
71
79.8k
  i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
72
79.8k
  i %= BYTES_PER_MPI_LIMB;
73
79.8k
  j= val->nlimbs = nlimbs;
74
79.8k
  val->sign = 0;
75
105k
  for ( ; j > 0; j-- )
76
26.0k
    {
77
26.0k
      a = 0;
78
26.0k
      if (i == 0 && nread + BYTES_PER_MPI_LIMB <= max_nread)
79
18.1k
  {
80
#if BYTES_PER_MPI_LIMB == 4
81
    a = buf_get_be32 (buffer);
82
#elif BYTES_PER_MPI_LIMB == 8
83
18.1k
    a = buf_get_be64 (buffer);
84
#else
85
#     error please implement for this limb size.
86
#endif
87
18.1k
    buffer += BYTES_PER_MPI_LIMB;
88
18.1k
    nread += BYTES_PER_MPI_LIMB;
89
18.1k
    i += BYTES_PER_MPI_LIMB;
90
18.1k
  }
91
43.3k
      for (; i < BYTES_PER_MPI_LIMB; i++ )
92
17.3k
        {
93
17.3k
          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
17.3k
          a <<= 8;
101
17.3k
          a |= *buffer++;
102
17.3k
  }
103
26.0k
      i = 0;
104
26.0k
      val->d[j-1] = a;
105
26.0k
    }
106
107
79.8k
 leave:
108
79.8k
  *ret_nread = nread;
109
79.8k
  return val;
110
79.8k
}
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
68.1k
{
295
68.1k
  unsigned char *p, *buffer, *retbuffer;
296
68.1k
  unsigned int length, tmp;
297
68.1k
  mpi_limb_t alimb;
298
68.1k
  int i;
299
68.1k
  size_t n, n2;
300
301
68.1k
  if (sign)
302
0
    *sign = a->sign;
303
304
68.1k
  *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
305
68.1k
  n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
306
68.1k
  if (n < fill_le)
307
0
    n = fill_le;
308
68.1k
  if (extraalloc < 0)
309
0
    n2 = n + -extraalloc;
310
68.1k
  else
311
68.1k
    n2 = n + extraalloc;
312
313
68.1k
  retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
314
68.1k
                                                : xtrymalloc (n2);
315
68.1k
  if (!retbuffer)
316
0
    return NULL;
317
68.1k
  if (extraalloc < 0)
318
0
    buffer = retbuffer + -extraalloc;
319
68.1k
  else
320
68.1k
    buffer = retbuffer;
321
68.1k
  p = buffer;
322
323
87.0k
  for (i=a->nlimbs-1; i >= 0; i--)
324
18.8k
    {
325
18.8k
      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
18.8k
      buf_put_be64 (p, alimb);
331
18.8k
      p += 8;
332
#else
333
#     error please implement for this limb size.
334
#endif
335
18.8k
    }
336
337
68.1k
  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
93.3k
  for (p=buffer; *nbytes && !*p; p++, --*nbytes)
373
25.1k
    ;
374
68.1k
  if (p != buffer)
375
4.50k
    memmove (buffer, p, *nbytes);
376
68.1k
  return retbuffer;
377
68.1k
}
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
68.1k
{
384
68.1k
  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
68.1k
  else
395
68.1k
    return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
396
68.1k
}
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
79.8k
{
542
79.8k
  const unsigned char *buffer = (const unsigned char*)buffer_arg;
543
79.8k
  struct gcry_mpi *a = NULL;
544
79.8k
  unsigned int len;
545
79.8k
  int secure = (buffer && _gcry_is_secure (buffer));
546
547
79.8k
  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
79.8k
  if (format == GCRYMPI_FMT_SSH)
555
0
    len = 0;
556
79.8k
  else
557
79.8k
    len = buflen;
558
559
79.8k
  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
79.8k
  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
79.8k
  else if (format == GCRYMPI_FMT_PGP)
608
79.8k
    {
609
79.8k
      a = mpi_read_from_buffer (buffer, &len, secure);
610
79.8k
      if (nscanned)
611
79.8k
        *nscanned = len;
612
79.8k
      if (ret_mpi && a)
613
79.8k
        {
614
79.8k
          mpi_normalize (a);
615
79.8k
          *ret_mpi = a;
616
79.8k
  }
617
0
      else if (a)
618
0
        {
619
0
          mpi_free(a);
620
0
          a = NULL;
621
0
        }
622
79.8k
      return a? 0 : GPG_ERR_INV_OBJ;
623
79.8k
    }
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
79.8k
}
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
136k
{
714
136k
  unsigned int nbits = mpi_get_nbits (a);
715
136k
  size_t len;
716
136k
  size_t dummy_nwritten;
717
136k
  int negative;
718
719
136k
  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
136k
  if (a->sign && _gcry_mpi_cmp_ui (a, 0))
728
0
    negative = 1;
729
136k
  else
730
136k
    negative = 0;
731
732
136k
  len = buflen;
733
136k
  *nwritten = 0;
734
136k
  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
136k
  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
136k
  else if (format == GCRYMPI_FMT_PGP)
807
136k
    {
808
136k
      unsigned int n = (nbits + 7)/8;
809
810
      /* The PGP format can only handle unsigned integers.  */
811
136k
      if (negative)
812
0
        return GPG_ERR_INV_ARG;
813
814
136k
      if (buffer && n+2 > len)
815
0
        return GPG_ERR_TOO_SHORT;
816
817
136k
      if (buffer)
818
68.1k
        {
819
68.1k
          unsigned char *tmp;
820
68.1k
          unsigned char *s = buffer;
821
822
68.1k
          s[0] = nbits >> 8;
823
68.1k
          s[1] = nbits;
824
825
68.1k
          tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
826
68.1k
          if (!tmp)
827
0
            return gpg_err_code_from_syserror ();
828
68.1k
          memcpy (s+2, tmp, n);
829
68.1k
          xfree (tmp);
830
68.1k
  }
831
136k
      *nwritten = n+2;
832
136k
      return 0;
833
136k
    }
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
136k
}
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
}