]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/bn/bn_print.c
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
13 #include "internal/cryptlib.h"
14 #include <openssl/buffer.h>
17 static const char Hex
[] = "0123456789ABCDEF";
19 /* Must 'OPENSSL_free' the returned data */
20 char *BN_bn2hex(const BIGNUM
*a
)
26 if (a
->neg
&& BN_is_zero(a
)) {
27 /* "-0" == 3 bytes including NULL terminator */
28 buf
= OPENSSL_malloc(3);
30 buf
= OPENSSL_malloc(a
->top
* BN_BYTES
* 2 + 2);
33 BNerr(BN_F_BN_BN2HEX
, ERR_R_MALLOC_FAILURE
);
41 for (i
= a
->top
- 1; i
>= 0; i
--) {
42 for (j
= BN_BITS2
- 8; j
>= 0; j
-= 8) {
43 /* strip leading zeros */
44 v
= ((int)(a
->d
[i
] >> (long)j
)) & 0xff;
47 *(p
++) = Hex
[v
& 0x0f];
57 /* Must 'OPENSSL_free' the returned data */
58 char *BN_bn2dec(const BIGNUM
*a
)
60 int i
= 0, num
, ok
= 0;
64 BN_ULONG
*bn_data
= NULL
, *lp
;
67 * get an upper bound for the length of the decimal integer
68 * num <= (BN_num_bits(a) + 1) * log(2)
69 * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error)
70 * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
72 i
= BN_num_bits(a
) * 3;
73 num
= (i
/ 10 + i
/ 1000 + 1) + 1;
74 bn_data
= OPENSSL_malloc((num
/ BN_DEC_NUM
+ 1) * sizeof(BN_ULONG
));
75 buf
= OPENSSL_malloc(num
+ 3);
76 if ((buf
== NULL
) || (bn_data
== NULL
)) {
77 BNerr(BN_F_BN_BN2DEC
, ERR_R_MALLOC_FAILURE
);
80 if ((t
= BN_dup(a
)) == NULL
)
83 #define BUF_REMAIN (num+3 - (size_t)(p - buf))
90 if (BN_is_negative(t
))
94 while (!BN_is_zero(t
)) {
95 *lp
= BN_div_word(t
, BN_DEC_CONV
);
100 * We now have a series of blocks, BN_DEC_NUM chars in length, where
101 * the last one needs truncation. The blocks need to be reversed in
104 BIO_snprintf(p
, BUF_REMAIN
, BN_DEC_FMT1
, *lp
);
107 while (lp
!= bn_data
) {
109 BIO_snprintf(p
, BUF_REMAIN
, BN_DEC_FMT2
, *lp
);
116 OPENSSL_free(bn_data
);
124 int BN_hex2bn(BIGNUM
**bn
, const char *a
)
128 int neg
= 0, h
, m
, i
, j
, k
, c
;
131 if ((a
== NULL
) || (*a
== '\0'))
139 for (i
= 0; i
<= (INT_MAX
/4) && isxdigit((unsigned char)a
[i
]); i
++)
149 /* a is the start of the hex digits, and it is 'i' long */
151 if ((ret
= BN_new()) == NULL
)
158 /* i is the number of hex digits */
159 if (bn_expand(ret
, i
* 4) == NULL
)
162 j
= i
; /* least significant 'hex' */
166 m
= ((BN_BYTES
* 2) <= j
) ? (BN_BYTES
* 2) : j
;
170 k
= OPENSSL_hexchar2int(c
);
172 k
= 0; /* paranoia */
195 int BN_dec2bn(BIGNUM
**bn
, const char *a
)
202 if ((a
== NULL
) || (*a
== '\0'))
209 for (i
= 0; i
<= (INT_MAX
/4) && isdigit((unsigned char)a
[i
]); i
++)
220 * a is the start of the digits, and it is 'i' long. We chop it into
221 * BN_DEC_NUM digits at a time
224 if ((ret
= BN_new()) == NULL
)
231 /* i is the number of digits, a bit of an over expand */
232 if (bn_expand(ret
, i
* 4) == NULL
)
235 j
= BN_DEC_NUM
- (i
% BN_DEC_NUM
);
243 if (++j
== BN_DEC_NUM
) {
244 BN_mul_word(ret
, BN_DEC_CONV
);
262 int BN_asc2bn(BIGNUM
**bn
, const char *a
)
268 if (p
[0] == '0' && (p
[1] == 'X' || p
[1] == 'x')) {
269 if (!BN_hex2bn(bn
, p
+ 2))
272 if (!BN_dec2bn(bn
, p
))
280 # ifndef OPENSSL_NO_STDIO
281 int BN_print_fp(FILE *fp
, const BIGNUM
*a
)
286 if ((b
= BIO_new(BIO_s_file())) == NULL
)
288 BIO_set_fp(b
, fp
, BIO_NOCLOSE
);
289 ret
= BN_print(b
, a
);
295 int BN_print(BIO
*bp
, const BIGNUM
*a
)
300 if ((a
->neg
) && (BIO_write(bp
, "-", 1) != 1))
302 if (BN_is_zero(a
) && (BIO_write(bp
, "0", 1) != 1))
304 for (i
= a
->top
- 1; i
>= 0; i
--) {
305 for (j
= BN_BITS2
- 4; j
>= 0; j
-= 4) {
306 /* strip leading zeros */
307 v
= ((int)(a
->d
[i
] >> (long)j
)) & 0x0f;
309 if (BIO_write(bp
, &(Hex
[v
]), 1) != 1)
320 char *BN_options(void)
323 static char data
[16];
328 BIO_snprintf(data
, sizeof data
, "bn(%d,%d)",
329 (int)sizeof(BN_ULLONG
) * 8, (int)sizeof(BN_ULONG
) * 8);
331 BIO_snprintf(data
, sizeof data
, "bn(%d,%d)",
332 (int)sizeof(BN_ULONG
) * 8, (int)sizeof(BN_ULONG
) * 8);