Coverage Report

Created: 2023-03-26 08:33

/src/gnutls/lib/mpi.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
3
 *
4
 * Author: Nikos Mavrogiannopoulos
5
 *
6
 * This file is part of GnuTLS.
7
 *
8
 * The GnuTLS is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public License
10
 * as published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
20
 *
21
 */
22
23
/* Here lie everything that has to do with large numbers, libgcrypt and
24
 * other stuff that didn't fit anywhere else.
25
 */
26
27
#include "gnutls_int.h"
28
#include <libtasn1.h>
29
#include "errors.h"
30
#include <num.h>
31
#include <mpi.h>
32
#include <random.h>
33
#include <x509/x509_int.h>
34
35
/* Functions that refer to the mpi library.
36
 */
37
38
/* Returns a random number r, 0 < r < p */
39
bigint_t
40
_gnutls_mpi_random_modp(bigint_t r, bigint_t p, gnutls_rnd_level_t level)
41
0
{
42
0
  size_t size;
43
0
  int ret;
44
0
  bigint_t tmp;
45
0
  uint8_t tmpbuf[512];
46
0
  uint8_t *buf;
47
0
  int buf_release = 0;
48
49
0
  size = ((_gnutls_mpi_get_nbits(p) + 64) / 8) + 1;
50
51
0
  if (size < sizeof(tmpbuf)) {
52
0
    buf = tmpbuf;
53
0
  } else {
54
0
    buf = gnutls_malloc(size);
55
0
    if (buf == NULL) {
56
0
      gnutls_assert();
57
0
      goto cleanup;
58
0
    }
59
0
    buf_release = 1;
60
0
  }
61
62
0
  ret = gnutls_rnd(level, buf, size);
63
0
  if (ret < 0) {
64
0
    gnutls_assert();
65
0
    goto cleanup;
66
0
  }
67
68
0
  ret = _gnutls_mpi_init_scan(&tmp, buf, size);
69
0
  if (ret < 0) {
70
0
    gnutls_assert();
71
0
    goto cleanup;
72
0
  }
73
74
0
  ret = _gnutls_mpi_modm(tmp, tmp, p);
75
0
  if (ret < 0) {
76
0
    gnutls_assert();
77
0
    goto cleanup;
78
0
  }
79
80
0
  if (_gnutls_mpi_cmp_ui(tmp, 0) == 0) {
81
0
    ret = _gnutls_mpi_add_ui(tmp, tmp, 1);
82
0
    if (ret < 0) {
83
0
      gnutls_assert();
84
0
      goto cleanup;
85
0
    }
86
0
  }
87
88
0
  if (buf_release != 0) {
89
0
    gnutls_free(buf);
90
0
  }
91
92
0
  if (r != NULL) {
93
0
    ret = _gnutls_mpi_set(r, tmp);
94
0
    if (ret < 0)
95
0
      goto cleanup;
96
97
0
    _gnutls_mpi_release(&tmp);
98
0
    return r;
99
0
  }
100
101
0
  return tmp;
102
103
0
 cleanup:
104
0
  if (buf_release != 0)
105
0
    gnutls_free(buf);
106
0
  return NULL;
107
0
}
108
109
/* returns %GNUTLS_E_SUCCESS (0) on success
110
 */
111
int _gnutls_mpi_init_scan(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
112
0
{
113
0
  bigint_t r;
114
0
  int ret;
115
116
0
  ret = _gnutls_mpi_init(&r);
117
0
  if (ret < 0)
118
0
    return gnutls_assert_val(ret);
119
120
0
  ret = _gnutls_mpi_scan(r, buffer, nbytes);
121
0
  if (ret < 0) {
122
0
    gnutls_assert();
123
0
    _gnutls_mpi_release(&r);
124
0
    return ret;
125
0
  }
126
127
0
  *ret_mpi = r;
128
129
0
  return 0;
130
0
}
131
132
/* returns %GNUTLS_E_SUCCESS (0) on success. Fails if the number is zero.
133
 */
134
int
135
_gnutls_mpi_init_scan_nz(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
136
0
{
137
0
  int ret;
138
139
0
  ret = _gnutls_mpi_init_scan(ret_mpi, buffer, nbytes);
140
0
  if (ret < 0)
141
0
    return ret;
142
143
  /* MPIs with 0 bits are illegal
144
   */
145
0
  if (_gnutls_mpi_cmp_ui(*ret_mpi, 0) == 0) {
146
0
    _gnutls_mpi_release(ret_mpi);
147
0
    return GNUTLS_E_MPI_SCAN_FAILED;
148
0
  }
149
150
0
  return 0;
151
0
}
152
153
int
154
_gnutls_mpi_init_scan_le(bigint_t * ret_mpi, const void *buffer, size_t nbytes)
155
0
{
156
0
  bigint_t r;
157
0
  int ret;
158
159
0
  ret = _gnutls_mpi_init(&r);
160
0
  if (ret < 0)
161
0
    return gnutls_assert_val(ret);
162
163
0
  ret = _gnutls_mpi_scan_le(r, buffer, nbytes);
164
0
  if (ret < 0) {
165
0
    gnutls_assert();
166
0
    _gnutls_mpi_release(&r);
167
0
    return ret;
168
0
  }
169
170
0
  *ret_mpi = r;
171
172
0
  return 0;
173
0
}
174
175
int _gnutls_mpi_dprint_le(const bigint_t a, gnutls_datum_t * dest)
176
0
{
177
0
  int ret;
178
0
  uint8_t *buf = NULL;
179
0
  size_t bytes = 0;
180
181
0
  if (dest == NULL || a == NULL)
182
0
    return GNUTLS_E_INVALID_REQUEST;
183
184
0
  _gnutls_mpi_print_le(a, NULL, &bytes);
185
0
  if (bytes != 0)
186
0
    buf = gnutls_malloc(bytes);
187
0
  if (buf == NULL)
188
0
    return GNUTLS_E_MEMORY_ERROR;
189
190
0
  ret = _gnutls_mpi_print_le(a, buf, &bytes);
191
0
  if (ret < 0) {
192
0
    gnutls_free(buf);
193
0
    return ret;
194
0
  }
195
196
0
  dest->data = buf;
197
0
  dest->size = bytes;
198
0
  return 0;
199
0
}
200
201
/* Always has the first bit zero */
202
int _gnutls_mpi_dprint_lz(const bigint_t a, gnutls_datum_t * dest)
203
0
{
204
0
  int ret;
205
0
  uint8_t *buf = NULL;
206
0
  size_t bytes = 0;
207
208
0
  if (dest == NULL || a == NULL)
209
0
    return GNUTLS_E_INVALID_REQUEST;
210
211
0
  _gnutls_mpi_print_lz(a, NULL, &bytes);
212
213
0
  if (bytes != 0)
214
0
    buf = gnutls_malloc(bytes);
215
0
  if (buf == NULL)
216
0
    return GNUTLS_E_MEMORY_ERROR;
217
218
0
  ret = _gnutls_mpi_print_lz(a, buf, &bytes);
219
0
  if (ret < 0) {
220
0
    gnutls_free(buf);
221
0
    return ret;
222
0
  }
223
224
0
  dest->data = buf;
225
0
  dest->size = bytes;
226
0
  return 0;
227
0
}
228
229
int _gnutls_mpi_dprint(const bigint_t a, gnutls_datum_t * dest)
230
0
{
231
0
  int ret;
232
0
  uint8_t *buf = NULL;
233
0
  size_t bytes = 0;
234
235
0
  if (dest == NULL || a == NULL)
236
0
    return GNUTLS_E_INVALID_REQUEST;
237
238
0
  _gnutls_mpi_print(a, NULL, &bytes);
239
0
  if (bytes != 0)
240
0
    buf = gnutls_malloc(bytes);
241
0
  if (buf == NULL)
242
0
    return GNUTLS_E_MEMORY_ERROR;
243
244
0
  ret = _gnutls_mpi_print(a, buf, &bytes);
245
0
  if (ret < 0) {
246
0
    gnutls_free(buf);
247
0
    return ret;
248
0
  }
249
250
0
  dest->data = buf;
251
0
  dest->size = bytes;
252
0
  return 0;
253
0
}
254
255
/* This function will copy the mpi data into a datum,
256
 * but will set minimum size to 'size'. That means that
257
 * the output value is left padded with zeros.
258
 */
259
int
260
_gnutls_mpi_dprint_size(const bigint_t a, gnutls_datum_t * dest, size_t size)
261
0
{
262
0
  int ret;
263
0
  uint8_t *buf = NULL;
264
0
  size_t bytes = 0;
265
0
  unsigned int i;
266
267
0
  if (dest == NULL || a == NULL)
268
0
    return GNUTLS_E_INVALID_REQUEST;
269
270
0
  _gnutls_mpi_print(a, NULL, &bytes);
271
0
  if (bytes != 0)
272
0
    buf = gnutls_malloc(MAX(size, bytes));
273
0
  if (buf == NULL)
274
0
    return GNUTLS_E_MEMORY_ERROR;
275
276
0
  if (bytes <= size) {
277
0
    size_t diff = size - bytes;
278
0
    for (i = 0; i < diff; i++)
279
0
      buf[i] = 0;
280
0
    ret = _gnutls_mpi_print(a, &buf[diff], &bytes);
281
0
  } else {
282
0
    ret = _gnutls_mpi_print(a, buf, &bytes);
283
0
  }
284
285
0
  if (ret < 0) {
286
0
    gnutls_free(buf);
287
0
    return ret;
288
0
  }
289
290
0
  dest->data = buf;
291
0
  dest->size = MAX(size, bytes);
292
0
  return 0;
293
0
}
294
295
/* like _gnutls_mpi_dprint_size, but prints into preallocated byte buffer */
296
int _gnutls_mpi_bprint_size(const bigint_t a, uint8_t * buf, size_t size)
297
0
{
298
0
  int result;
299
0
  size_t bytes = 0;
300
301
0
  result = _gnutls_mpi_print(a, NULL, &bytes);
302
0
  if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
303
0
    return gnutls_assert_val(result);
304
305
0
  if (bytes <= size) {
306
0
    unsigned i;
307
0
    size_t diff = size - bytes;
308
309
0
    for (i = 0; i < diff; i++)
310
0
      buf[i] = 0;
311
0
    result = _gnutls_mpi_print(a, &buf[diff], &bytes);
312
0
  } else {
313
0
    result = _gnutls_mpi_print(a, buf, &bytes);
314
0
  }
315
316
0
  return result;
317
0
}
318
319
/* Flags for __gnutls_x509_read_int() and __gnutls_x509_write_int */
320
0
#define GNUTLS_X509_INT_OVERWRITE (1 << 0)
321
0
#define GNUTLS_X509_INT_LE    (1 << 1)
322
0
#define GNUTLS_X509_INT_LZ    (1 << 2)  /* write only */
323
324
/* this function reads an integer
325
 * from asn1 structs. Combines the read and mpi_scan
326
 * steps.
327
 */
328
static int
329
__gnutls_x509_read_int(asn1_node node, const char *value,
330
           bigint_t * ret_mpi, unsigned int flags)
331
0
{
332
0
  int result;
333
0
  uint8_t *tmpstr = NULL;
334
0
  int tmpstr_size;
335
336
0
  tmpstr_size = 0;
337
0
  result = asn1_read_value(node, value, NULL, &tmpstr_size);
338
0
  if (result != ASN1_MEM_ERROR) {
339
0
    gnutls_assert();
340
0
    return _gnutls_asn2err(result);
341
0
  }
342
343
0
  tmpstr = gnutls_malloc(tmpstr_size);
344
0
  if (tmpstr == NULL) {
345
0
    gnutls_assert();
346
0
    return GNUTLS_E_MEMORY_ERROR;
347
0
  }
348
349
0
  result = asn1_read_value(node, value, tmpstr, &tmpstr_size);
350
0
  if (result != ASN1_SUCCESS) {
351
0
    gnutls_assert();
352
0
    gnutls_free(tmpstr);
353
0
    return _gnutls_asn2err(result);
354
0
  }
355
356
0
  if (flags & GNUTLS_X509_INT_LE)
357
0
    result = _gnutls_mpi_init_scan_le(ret_mpi, tmpstr, tmpstr_size);
358
0
  else
359
0
    result = _gnutls_mpi_init_scan(ret_mpi, tmpstr, tmpstr_size);
360
361
0
  if (flags & GNUTLS_X509_INT_OVERWRITE)
362
0
    zeroize_key(tmpstr, tmpstr_size);
363
0
  gnutls_free(tmpstr);
364
365
0
  if (result < 0) {
366
0
    gnutls_assert();
367
0
    return result;
368
0
  }
369
370
0
  return 0;
371
0
}
372
373
int _gnutls_x509_read_int(asn1_node node, const char *value, bigint_t * ret_mpi)
374
0
{
375
0
  return __gnutls_x509_read_int(node, value, ret_mpi, 0);
376
0
}
377
378
int
379
_gnutls_x509_read_key_int(asn1_node node, const char *value, bigint_t * ret_mpi)
380
0
{
381
0
  return __gnutls_x509_read_int(node, value, ret_mpi,
382
0
              GNUTLS_X509_INT_OVERWRITE);
383
0
}
384
385
int
386
_gnutls_x509_read_key_int_le(asn1_node node, const char *value,
387
           bigint_t * ret_mpi)
388
0
{
389
0
  return __gnutls_x509_read_int(node, value, ret_mpi,
390
0
              GNUTLS_X509_INT_OVERWRITE |
391
0
              GNUTLS_X509_INT_LE);
392
0
}
393
394
/* Writes the specified integer into the specified node.
395
 */
396
static int
397
__gnutls_x509_write_int(asn1_node node, const char *value, bigint_t mpi,
398
      unsigned int flags)
399
0
{
400
0
  uint8_t *tmpstr;
401
0
  size_t s_len;
402
0
  int result;
403
404
0
  s_len = 0;
405
0
  if (flags & GNUTLS_X509_INT_LZ)
406
0
    result = _gnutls_mpi_print_lz(mpi, NULL, &s_len);
407
0
  else if (GNUTLS_X509_INT_LE)
408
0
    result = _gnutls_mpi_print_le(mpi, NULL, &s_len);
409
0
  else
410
0
    result = _gnutls_mpi_print(mpi, NULL, &s_len);
411
412
0
  if (result != GNUTLS_E_SHORT_MEMORY_BUFFER) {
413
0
    gnutls_assert();
414
0
    return result;
415
0
  }
416
417
0
  tmpstr = gnutls_malloc(s_len);
418
0
  if (tmpstr == NULL) {
419
0
    gnutls_assert();
420
0
    return GNUTLS_E_MEMORY_ERROR;
421
0
  }
422
423
0
  if (flags & GNUTLS_X509_INT_LZ)
424
0
    result = _gnutls_mpi_print_lz(mpi, tmpstr, &s_len);
425
0
  else if (GNUTLS_X509_INT_LE)
426
0
    result = _gnutls_mpi_print_le(mpi, tmpstr, &s_len);
427
0
  else
428
0
    result = _gnutls_mpi_print(mpi, tmpstr, &s_len);
429
430
0
  if (result != 0) {
431
0
    gnutls_assert();
432
0
    gnutls_free(tmpstr);
433
0
    return GNUTLS_E_MPI_PRINT_FAILED;
434
0
  }
435
436
0
  result = asn1_write_value(node, value, tmpstr, s_len);
437
438
0
  if (flags & GNUTLS_X509_INT_OVERWRITE)
439
0
    zeroize_key(tmpstr, s_len);
440
441
0
  gnutls_free(tmpstr);
442
443
0
  if (result != ASN1_SUCCESS) {
444
0
    gnutls_assert();
445
0
    return _gnutls_asn2err(result);
446
0
  }
447
448
0
  return 0;
449
0
}
450
451
int
452
_gnutls_x509_write_int(asn1_node node, const char *value, bigint_t mpi, int lz)
453
0
{
454
0
  return __gnutls_x509_write_int(node, value, mpi,
455
0
               lz ? GNUTLS_X509_INT_LZ : 0);
456
0
}
457
458
int
459
_gnutls_x509_write_key_int(asn1_node node, const char *value, bigint_t mpi,
460
         int lz)
461
0
{
462
0
  return __gnutls_x509_write_int(node, value, mpi,
463
0
               (lz ? GNUTLS_X509_INT_LZ : 0) |
464
0
               GNUTLS_X509_INT_OVERWRITE);
465
0
}
466
467
int
468
_gnutls_x509_write_key_int_le(asn1_node node, const char *value, bigint_t mpi)
469
0
{
470
0
  return __gnutls_x509_write_int(node, value, mpi,
471
0
               GNUTLS_X509_INT_OVERWRITE |
472
0
               GNUTLS_X509_INT_LE);
473
0
}