guile: Fix `priorities' test to use `run-test'.
[gnutls.git] / lib / gnutls_mpi.c
blobb2cde7a3bec853596d5ccecacc1daf974571b2e1
1 /*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2010 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>
24 /* Here lie everything that has to do with large numbers, libgcrypt and
25 * other stuff that didn't fit anywhere else.
28 #include <gnutls_int.h>
29 #include <libtasn1.h>
30 #include <gnutls_errors.h>
31 #include <gnutls_num.h>
32 #include <gnutls_mpi.h>
33 #include <random.h>
34 #include <x509/x509_int.h>
36 /* Functions that refer to the mpi library.
39 #define clearbit(v,n) ((unsigned char)(v) & ~( (unsigned char)(1) << (unsigned)(n)))
41 bigint_t
42 _gnutls_mpi_randomize (bigint_t r, unsigned int bits,
43 gnutls_rnd_level_t level)
45 size_t size = 1 + (bits / 8);
46 int ret;
47 int rem, i;
48 bigint_t tmp;
49 char tmpbuf[512];
50 opaque *buf;
51 int buf_release = 0;
53 if (size < sizeof (tmpbuf))
55 buf = tmpbuf;
57 else
59 buf = gnutls_malloc (size);
60 if (buf == NULL)
62 gnutls_assert ();
63 goto cleanup;
65 buf_release = 1;
69 ret = gnutls_rnd (level, buf, size);
70 if (ret < 0)
72 gnutls_assert ();
73 goto cleanup;
76 /* mask the bits that weren't requested */
77 rem = bits % 8;
79 if (rem == 0)
81 buf[0] = 0;
83 else
85 for (i = 8; i >= rem; i--)
86 buf[0] = clearbit (buf[0], i);
89 ret = _gnutls_mpi_scan (&tmp, buf, size);
90 if (ret < 0)
92 gnutls_assert ();
93 goto cleanup;
96 if (buf_release != 0)
98 gnutls_free (buf);
99 buf = NULL;
102 if (r != NULL)
104 _gnutls_mpi_set (r, tmp);
105 _gnutls_mpi_release (&tmp);
106 return r;
109 return tmp;
111 cleanup:
112 if (buf_release != 0)
113 gnutls_free (buf);
114 return NULL;
117 void
118 _gnutls_mpi_release (bigint_t * x)
120 if (*x == NULL)
121 return;
123 _gnutls_mpi_ops.bigint_release (*x);
124 *x = NULL;
127 /* returns %GNUTLS_E_SUCCESS (0) on success
130 _gnutls_mpi_scan (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
132 *ret_mpi =
133 _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_USG);
134 if (*ret_mpi == NULL)
136 gnutls_assert ();
137 return GNUTLS_E_MPI_SCAN_FAILED;
140 return 0;
143 /* returns %GNUTLS_E_SUCCESS (0) on success. Fails if the number is zero.
146 _gnutls_mpi_scan_nz (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
148 int ret;
150 ret = _gnutls_mpi_scan (ret_mpi, buffer, nbytes);
151 if (ret < 0)
152 return ret;
154 /* MPIs with 0 bits are illegal
156 if (_gnutls_mpi_get_nbits (*ret_mpi) == 0)
158 _gnutls_mpi_release (ret_mpi);
159 return GNUTLS_E_MPI_SCAN_FAILED;
162 return 0;
166 _gnutls_mpi_scan_pgp (bigint_t * ret_mpi, const void *buffer, size_t nbytes)
168 *ret_mpi =
169 _gnutls_mpi_ops.bigint_scan (buffer, nbytes, GNUTLS_MPI_FORMAT_PGP);
170 if (*ret_mpi == NULL)
172 gnutls_assert ();
173 return GNUTLS_E_MPI_SCAN_FAILED;
176 return 0;
179 /* Always has the first bit zero */
181 _gnutls_mpi_dprint_lz (const bigint_t a, gnutls_datum_t * dest)
183 int ret;
184 opaque *buf = NULL;
185 size_t bytes = 0;
187 if (dest == NULL || a == NULL)
188 return GNUTLS_E_INVALID_REQUEST;
190 _gnutls_mpi_print_lz (a, NULL, &bytes);
192 if (bytes != 0)
193 buf = gnutls_malloc (bytes);
194 if (buf == NULL)
195 return GNUTLS_E_MEMORY_ERROR;
197 ret = _gnutls_mpi_print_lz (a, buf, &bytes);
198 if (ret < 0)
200 gnutls_free (buf);
201 return ret;
204 dest->data = buf;
205 dest->size = bytes;
206 return 0;
210 _gnutls_mpi_dprint (const bigint_t a, gnutls_datum_t * dest)
212 int ret;
213 opaque *buf = NULL;
214 size_t bytes = 0;
216 if (dest == NULL || a == NULL)
217 return GNUTLS_E_INVALID_REQUEST;
219 _gnutls_mpi_print (a, NULL, &bytes);
220 if (bytes != 0)
221 buf = gnutls_malloc (bytes);
222 if (buf == NULL)
223 return GNUTLS_E_MEMORY_ERROR;
225 ret = _gnutls_mpi_print (a, buf, &bytes);
226 if (ret < 0)
228 gnutls_free (buf);
229 return ret;
232 dest->data = buf;
233 dest->size = bytes;
234 return 0;
237 /* This function will copy the mpi data into a datum,
238 * but will set minimum size to 'size'. That means that
239 * the output value is left padded with zeros.
242 _gnutls_mpi_dprint_size (const bigint_t a, gnutls_datum_t * dest, size_t size)
244 int ret;
245 opaque *buf = NULL;
246 size_t bytes = 0;
247 unsigned int i;
249 if (dest == NULL || a == NULL)
250 return GNUTLS_E_INVALID_REQUEST;
252 _gnutls_mpi_print (a, NULL, &bytes);
253 if (bytes != 0)
254 buf = gnutls_malloc (MAX (size, bytes));
255 if (buf == NULL)
256 return GNUTLS_E_MEMORY_ERROR;
258 if (bytes <= size)
260 size_t diff = size - bytes;
261 for (i = 0; i < diff; i++)
262 buf[i] = 0;
263 ret = _gnutls_mpi_print (a, &buf[diff], &bytes);
265 else
267 ret = _gnutls_mpi_print (a, buf, &bytes);
270 if (ret < 0)
272 gnutls_free (buf);
273 return ret;
276 dest->data = buf;
277 dest->size = MAX (size, bytes);
278 return 0;
281 /* this function reads an integer
282 * from asn1 structs. Combines the read and mpi_scan
283 * steps.
286 _gnutls_x509_read_int (ASN1_TYPE node, const char *value, bigint_t * ret_mpi)
288 int result;
289 opaque *tmpstr = NULL;
290 int tmpstr_size;
292 tmpstr_size = 0;
293 result = asn1_read_value (node, value, NULL, &tmpstr_size);
294 if (result != ASN1_MEM_ERROR)
296 gnutls_assert ();
297 return _gnutls_asn2err (result);
300 tmpstr = gnutls_malloc (tmpstr_size);
301 if (tmpstr == NULL)
303 gnutls_assert ();
304 return GNUTLS_E_MEMORY_ERROR;
307 result = asn1_read_value (node, value, tmpstr, &tmpstr_size);
308 if (result != ASN1_SUCCESS)
310 gnutls_assert ();
311 gnutls_free (tmpstr);
312 return _gnutls_asn2err (result);
315 result = _gnutls_mpi_scan (ret_mpi, tmpstr, tmpstr_size);
316 gnutls_free (tmpstr);
318 if (result < 0)
320 gnutls_assert ();
321 return result;
324 return 0;
327 /* Writes the specified integer into the specified node.
330 _gnutls_x509_write_int (ASN1_TYPE node, const char *value, bigint_t mpi,
331 int lz)
333 opaque *tmpstr;
334 size_t s_len;
335 int result;
337 s_len = 0;
338 if (lz)
339 result = _gnutls_mpi_print_lz (mpi, NULL, &s_len);
340 else
341 result = _gnutls_mpi_print (mpi, NULL, &s_len);
343 if (result != GNUTLS_E_SHORT_MEMORY_BUFFER)
345 gnutls_assert ();
346 return result;
349 tmpstr = gnutls_malloc (s_len);
350 if (tmpstr == NULL)
352 gnutls_assert ();
353 return GNUTLS_E_MEMORY_ERROR;
356 if (lz)
357 result = _gnutls_mpi_print_lz (mpi, tmpstr, &s_len);
358 else
359 result = _gnutls_mpi_print (mpi, tmpstr, &s_len);
361 if (result != 0)
363 gnutls_assert ();
364 gnutls_free (tmpstr);
365 return GNUTLS_E_MPI_PRINT_FAILED;
368 result = asn1_write_value (node, value, tmpstr, s_len);
370 gnutls_free (tmpstr);
372 if (result != ASN1_SUCCESS)
374 gnutls_assert ();
375 return _gnutls_asn2err (result);
378 return 0;