OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
bn_print.c
Go to the documentation of this file.
1 /* crypto/bn/bn_print.c */
2 /* Copyright (C) 1995-1998 Eric Young ([email protected])
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young ([email protected]).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to. The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson ([email protected]).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  * must display the following acknowledgement:
33  * "This product includes cryptographic software written by
34  * Eric Young ([email protected])"
35  * The word 'cryptographic' can be left out if the rouines from the library
36  * being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  * the apps directory (application code) you must include an acknowledgement:
39  * "This product includes software written by Tim Hudson ([email protected])"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed. i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 #include <ctype.h>
61 #include "cryptlib.h"
62 #include <openssl/buffer.h>
63 #include "bn_lcl.h"
64 
65 static const char Hex[]="0123456789ABCDEF";
66 
67 /* Must 'OPENSSL_free' the returned data */
68 char *BN_bn2hex(const BIGNUM *a)
69  {
70  int i,j,v,z=0;
71  char *buf;
72  char *p;
73 
74  buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2);
75  if (buf == NULL)
76  {
78  goto err;
79  }
80  p=buf;
81  if (a->neg) *(p++)='-';
82  if (BN_is_zero(a)) *(p++)='0';
83  for (i=a->top-1; i >=0; i--)
84  {
85  for (j=BN_BITS2-8; j >= 0; j-=8)
86  {
87  /* strip leading zeros */
88  v=((int)(a->d[i]>>(long)j))&0xff;
89  if (z || (v != 0))
90  {
91  *(p++)=Hex[v>>4];
92  *(p++)=Hex[v&0x0f];
93  z=1;
94  }
95  }
96  }
97  *p='\0';
98 err:
99  return(buf);
100  }
101 
102 /* Must 'OPENSSL_free' the returned data */
103 char *BN_bn2dec(const BIGNUM *a)
104  {
105  int i=0,num, ok = 0;
106  char *buf=NULL;
107  char *p;
108  BIGNUM *t=NULL;
109  BN_ULONG *bn_data=NULL,*lp;
110 
111  /* get an upper bound for the length of the decimal integer
112  * num <= (BN_num_bits(a) + 1) * log(2)
113  * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
114  * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
115  */
116  i=BN_num_bits(a)*3;
117  num=(i/10+i/1000+1)+1;
118  bn_data=(BN_ULONG *)OPENSSL_malloc((num/BN_DEC_NUM+1)*sizeof(BN_ULONG));
119  buf=(char *)OPENSSL_malloc(num+3);
120  if ((buf == NULL) || (bn_data == NULL))
121  {
123  goto err;
124  }
125  if ((t=BN_dup(a)) == NULL) goto err;
126 
127 #define BUF_REMAIN (num+3 - (size_t)(p - buf))
128  p=buf;
129  lp=bn_data;
130  if (BN_is_zero(t))
131  {
132  *(p++)='0';
133  *(p++)='\0';
134  }
135  else
136  {
137  if (BN_is_negative(t))
138  *p++ = '-';
139 
140  i=0;
141  while (!BN_is_zero(t))
142  {
143  *lp=BN_div_word(t,BN_DEC_CONV);
144  lp++;
145  }
146  lp--;
147  /* We now have a series of blocks, BN_DEC_NUM chars
148  * in length, where the last one needs truncation.
149  * The blocks need to be reversed in order. */
150  BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT1,*lp);
151  while (*p) p++;
152  while (lp != bn_data)
153  {
154  lp--;
155  BIO_snprintf(p,BUF_REMAIN,BN_DEC_FMT2,*lp);
156  while (*p) p++;
157  }
158  }
159  ok = 1;
160 err:
161  if (bn_data != NULL) OPENSSL_free(bn_data);
162  if (t != NULL) BN_free(t);
163  if (!ok && buf)
164  {
165  OPENSSL_free(buf);
166  buf = NULL;
167  }
168 
169  return(buf);
170  }
171 
172 int BN_hex2bn(BIGNUM **bn, const char *a)
173  {
174  BIGNUM *ret=NULL;
175  BN_ULONG l=0;
176  int neg=0,h,m,i,j,k,c;
177  int num;
178 
179  if ((a == NULL) || (*a == '\0')) return(0);
180 
181  if (*a == '-') { neg=1; a++; }
182 
183  for (i=0; isxdigit((unsigned char) a[i]); i++)
184  ;
185 
186  num=i+neg;
187  if (bn == NULL) return(num);
188 
189  /* a is the start of the hex digits, and it is 'i' long */
190  if (*bn == NULL)
191  {
192  if ((ret=BN_new()) == NULL) return(0);
193  }
194  else
195  {
196  ret= *bn;
197  BN_zero(ret);
198  }
199 
200  /* i is the number of hex digests; */
201  if (bn_expand(ret,i*4) == NULL) goto err;
202 
203  j=i; /* least significant 'hex' */
204  m=0;
205  h=0;
206  while (j > 0)
207  {
208  m=((BN_BYTES*2) <= j)?(BN_BYTES*2):j;
209  l=0;
210  for (;;)
211  {
212  c=a[j-m];
213  if ((c >= '0') && (c <= '9')) k=c-'0';
214  else if ((c >= 'a') && (c <= 'f')) k=c-'a'+10;
215  else if ((c >= 'A') && (c <= 'F')) k=c-'A'+10;
216  else k=0; /* paranoia */
217  l=(l<<4)|k;
218 
219  if (--m <= 0)
220  {
221  ret->d[h++]=l;
222  break;
223  }
224  }
225  j-=(BN_BYTES*2);
226  }
227  ret->top=h;
228  bn_correct_top(ret);
229  ret->neg=neg;
230 
231  *bn=ret;
232  bn_check_top(ret);
233  return(num);
234 err:
235  if (*bn == NULL) BN_free(ret);
236  return(0);
237  }
238 
239 int BN_dec2bn(BIGNUM **bn, const char *a)
240  {
241  BIGNUM *ret=NULL;
242  BN_ULONG l=0;
243  int neg=0,i,j;
244  int num;
245 
246  if ((a == NULL) || (*a == '\0')) return(0);
247  if (*a == '-') { neg=1; a++; }
248 
249  for (i=0; isdigit((unsigned char) a[i]); i++)
250  ;
251 
252  num=i+neg;
253  if (bn == NULL) return(num);
254 
255  /* a is the start of the digits, and it is 'i' long.
256  * We chop it into BN_DEC_NUM digits at a time */
257  if (*bn == NULL)
258  {
259  if ((ret=BN_new()) == NULL) return(0);
260  }
261  else
262  {
263  ret= *bn;
264  BN_zero(ret);
265  }
266 
267  /* i is the number of digests, a bit of an over expand; */
268  if (bn_expand(ret,i*4) == NULL) goto err;
269 
270  j=BN_DEC_NUM-(i%BN_DEC_NUM);
271  if (j == BN_DEC_NUM) j=0;
272  l=0;
273  while (*a)
274  {
275  l*=10;
276  l+= *a-'0';
277  a++;
278  if (++j == BN_DEC_NUM)
279  {
280  BN_mul_word(ret,BN_DEC_CONV);
281  BN_add_word(ret,l);
282  l=0;
283  j=0;
284  }
285  }
286  ret->neg=neg;
287 
288  bn_correct_top(ret);
289  *bn=ret;
290  bn_check_top(ret);
291  return(num);
292 err:
293  if (*bn == NULL) BN_free(ret);
294  return(0);
295  }
296 
297 int BN_asc2bn(BIGNUM **bn, const char *a)
298  {
299  const char *p = a;
300  if (*p == '-')
301  p++;
302 
303  if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x'))
304  {
305  if (!BN_hex2bn(bn, p + 2))
306  return 0;
307  }
308  else
309  {
310  if (!BN_dec2bn(bn, p))
311  return 0;
312  }
313  if (*a == '-')
314  (*bn)->neg = 1;
315  return 1;
316  }
317 
318 #ifndef OPENSSL_NO_BIO
319 #ifndef OPENSSL_NO_FP_API
320 int BN_print_fp(FILE *fp, const BIGNUM *a)
321  {
322  BIO *b;
323  int ret;
324 
325  if ((b=BIO_new(BIO_s_file())) == NULL)
326  return(0);
327  BIO_set_fp(b,fp,BIO_NOCLOSE);
328  ret=BN_print(b,a);
329  BIO_free(b);
330  return(ret);
331  }
332 #endif
333 
334 int BN_print(BIO *bp, const BIGNUM *a)
335  {
336  int i,j,v,z=0;
337  int ret=0;
338 
339  if ((a->neg) && (BIO_write(bp,"-",1) != 1)) goto end;
340  if (BN_is_zero(a) && (BIO_write(bp,"0",1) != 1)) goto end;
341  for (i=a->top-1; i >=0; i--)
342  {
343  for (j=BN_BITS2-4; j >= 0; j-=4)
344  {
345  /* strip leading zeros */
346  v=((int)(a->d[i]>>(long)j))&0x0f;
347  if (z || (v != 0))
348  {
349  if (BIO_write(bp,&(Hex[v]),1) != 1)
350  goto end;
351  z=1;
352  }
353  }
354  }
355  ret=1;
356 end:
357  return(ret);
358  }
359 #endif
360 
361 char *BN_options(void)
362  {
363  static int init=0;
364  static char data[16];
365 
366  if (!init)
367  {
368  init++;
369 #ifdef BN_LLONG
370  BIO_snprintf(data,sizeof data,"bn(%d,%d)",
371  (int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
372 #else
373  BIO_snprintf(data,sizeof data,"bn(%d,%d)",
374  (int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
375 #endif
376  }
377  return(data);
378  }