2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
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 3 of
11 * the License, or (at your option) any later version.
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.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* Here lie everything that has to do with large numbers, libgcrypt and
24 * other stuff that didn't fit anywhere else.
27 #include <gnutls_int.h>
29 #include <gnutls_errors.h>
30 #include <gnutls_num.h>
31 #include <gnutls_mpi.h>
33 #include <x509/x509_int.h>
35 /* Functions that refer to the mpi library.
38 #define clearbit(v,n) ((unsigned char)(v) & ~( (unsigned char)(1) << (unsigned)(n)))
41 _gnutls_mpi_randomize (bigint_t r, unsigned int bits,
42 gnutls_rnd_level_t level)
44 size_t size = 1 + (bits / 8);
52 if (size < sizeof (tmpbuf))
58 buf = gnutls_malloc (size);
68 ret = _gnutls_rnd (level, buf, size);
75 /* mask the bits that weren't requested */
84 for (i = 8; i >= rem; i--)
85 buf[0] = clearbit (buf[0], i);
88 ret = _gnutls_mpi_scan (&tmp, buf, size);
103 _gnutls_mpi_set (r, tmp);
104 _gnutls_mpi_release (&tmp);
111 if (buf_release != 0)
117 _gnutls_mpi_release (bigint_t * x)
122 _gnutls_mpi_ops.bigint_release (*x);
126 /* returns %GNUTLS_E_SUCCESS (0) on success
129 _gnutls_mpi_scan (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
132 _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_USG);
133 if (*ret_mpi == NULL)
136 return GNUTLS_E_MPI_SCAN_FAILED;
142 /* returns %GNUTLS_E_SUCCESS (0) on success. Fails if the number is zero.
145 _gnutls_mpi_scan_nz (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
149 ret = _gnutls_mpi_scan (ret_mpi, buffer, nbytes);
153 /* MPIs with 0 bits are illegal
155 if (_gnutls_mpi_cmp_ui (*ret_mpi, 0) == 0)
157 _gnutls_mpi_release (ret_mpi);
158 return GNUTLS_E_MPI_SCAN_FAILED;
165 _gnutls_mpi_scan_pgp (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
168 _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_PGP);
169 if (*ret_mpi == NULL)
172 return GNUTLS_E_MPI_SCAN_FAILED;
178 /* Always has the first bit zero */
180 _gnutls_mpi_dprint_lz (const bigint_t a, gnutls_datum_t * dest)
186 if (dest == NULL || a == NULL)
187 return GNUTLS_E_INVALID_REQUEST;
189 _gnutls_mpi_print_lz (a, NULL, &bytes);
192 buf = gnutls_malloc (bytes);
194 return GNUTLS_E_MEMORY_ERROR;
196 ret = _gnutls_mpi_print_lz (a, buf, &bytes);
209 _gnutls_mpi_dprint (const bigint_t a, gnutls_datum_t * dest)
215 if (dest == NULL || a == NULL)
216 return GNUTLS_E_INVALID_REQUEST;
218 _gnutls_mpi_print (a, NULL, &bytes);
220 buf = gnutls_malloc (bytes);
222 return GNUTLS_E_MEMORY_ERROR;
224 ret = _gnutls_mpi_print (a, buf, &bytes);
236 /* This function will copy the mpi data into a datum,
237 * but will set minimum size to 'size'. That means that
238 * the output value is left padded with zeros.
241 _gnutls_mpi_dprint_size (const bigint_t a, gnutls_datum_t * dest, size_t size)
248 if (dest == NULL || a == NULL)
249 return GNUTLS_E_INVALID_REQUEST;
251 _gnutls_mpi_print (a, NULL, &bytes);
253 buf = gnutls_malloc (MAX (size, bytes));
255 return GNUTLS_E_MEMORY_ERROR;
259 size_t diff = size - bytes;
260 for (i = 0; i < diff; i++)
262 ret = _gnutls_mpi_print (a, &buf[diff], &bytes);
266 ret = _gnutls_mpi_print (a, buf, &bytes);
276 dest->size = MAX (size, bytes);
280 /* this function reads an integer
281 * from asn1 structs. Combines the read and mpi_scan
285 _gnutls_x509_read_int (ASN1_TYPE node, const char *value, bigint_t * ret_mpi)
288 uint8_t *tmpstr = NULL;
292 result = asn1_read_value (node, value, NULL, &tmpstr_size);
293 if (result != ASN1_MEM_ERROR)
296 return _gnutls_asn2err (result);
299 tmpstr = gnutls_malloc (tmpstr_size);
303 return GNUTLS_E_MEMORY_ERROR;
306 result = asn1_read_value (node, value, tmpstr, &tmpstr_size);
307 if (result != ASN1_SUCCESS)
310 gnutls_free (tmpstr);
311 return _gnutls_asn2err (result);
314 result = _gnutls_mpi_scan (ret_mpi, tmpstr, tmpstr_size);
315 gnutls_free (tmpstr);
326 /* Writes the specified integer into the specified node.
329 _gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi,
338 result = _gnutls_mpi_print_lz (mpi, NULL, &s_len);
340 result = _gnutls_mpi_print (mpi, NULL, &s_len);
342 if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
348 tmpstr = gnutls_malloc (s_len);
352 return GNUTLS_E_MEMORY_ERROR;
356 result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len);
358 result = _gnutls_mpi_print (mpi, tmpstr, &s_len);
363 gnutls_free (tmpstr);
364 return GNUTLS_E_MPI_PRINT_FAILED;
367 result = asn1_write_value (node, value, tmpstr, s_len);
369 gnutls_free (tmpstr);
371 if (result != ASN1_SUCCESS)
374 return _gnutls_asn2err (result);