Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/bn/bn_print.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
3
 *
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
8
 */
9
10
#include <stdio.h>
11
#include "internal/ctype.h"
12
#include <limits.h>
13
#include "internal/cryptlib.h"
14
#include <openssl/buffer.h>
15
#include "bn_lcl.h"
16
17
static const char Hex[] = "0123456789ABCDEF";
18
19
/* Must 'OPENSSL_free' the returned data */
20
char *BN_bn2hex(const BIGNUM *a)
21
0
{
22
0
    int i, j, v, z = 0;
23
0
    char *buf;
24
0
    char *p;
25
0
26
0
    if (BN_is_zero(a))
27
0
        return OPENSSL_strdup("0");
28
0
    buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
29
0
    if (buf == NULL) {
30
0
        BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
31
0
        goto err;
32
0
    }
33
0
    p = buf;
34
0
    if (a->neg)
35
0
        *p++ = '-';
36
0
    for (i = a->top - 1; i >= 0; i--) {
37
0
        for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
38
0
            /* strip leading zeros */
39
0
            v = (int)((a->d[i] >> j) & 0xff);
40
0
            if (z || v != 0) {
41
0
                *p++ = Hex[v >> 4];
42
0
                *p++ = Hex[v & 0x0f];
43
0
                z = 1;
44
0
            }
45
0
        }
46
0
    }
47
0
    *p = '\0';
48
0
 err:
49
0
    return buf;
50
0
}
51
52
/* Must 'OPENSSL_free' the returned data */
53
char *BN_bn2dec(const BIGNUM *a)
54
30.3k
{
55
30.3k
    int i = 0, num, ok = 0, n, tbytes;
56
30.3k
    char *buf = NULL;
57
30.3k
    char *p;
58
30.3k
    BIGNUM *t = NULL;
59
30.3k
    BN_ULONG *bn_data = NULL, *lp;
60
30.3k
    int bn_data_num;
61
30.3k
62
30.3k
    /*-
63
30.3k
     * get an upper bound for the length of the decimal integer
64
30.3k
     * num <= (BN_num_bits(a) + 1) * log(2)
65
30.3k
     *     <= 3 * BN_num_bits(a) * 0.101 + log(2) + 1     (rounding error)
66
30.3k
     *     <= 3 * BN_num_bits(a) / 10 + 3 * BN_num_bits / 1000 + 1 + 1
67
30.3k
     */
68
30.3k
    i = BN_num_bits(a) * 3;
69
30.3k
    num = (i / 10 + i / 1000 + 1) + 1;
70
30.3k
    tbytes = num + 3;   /* negative and terminator and one spare? */
71
30.3k
    bn_data_num = num / BN_DEC_NUM + 1;
72
30.3k
    bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
73
30.3k
    buf = OPENSSL_malloc(tbytes);
74
30.3k
    if (buf == NULL || bn_data == NULL) {
75
0
        BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
76
0
        goto err;
77
0
    }
78
30.3k
    if ((t = BN_dup(a)) == NULL)
79
30.3k
        goto err;
80
30.3k
81
30.3k
    p = buf;
82
30.3k
    lp = bn_data;
83
30.3k
    if (BN_is_zero(t)) {
84
0
        *p++ = '0';
85
0
        *p++ = '\0';
86
30.3k
    } else {
87
30.3k
        if (BN_is_negative(t))
88
0
            *p++ = '-';
89
30.3k
90
197k
        while (!BN_is_zero(t)) {
91
166k
            if (lp - bn_data >= bn_data_num)
92
0
                goto err;
93
166k
            *lp = BN_div_word(t, BN_DEC_CONV);
94
166k
            if (*lp == (BN_ULONG)-1)
95
0
                goto err;
96
166k
            lp++;
97
166k
        }
98
30.3k
        lp--;
99
30.3k
        /*
100
30.3k
         * We now have a series of blocks, BN_DEC_NUM chars in length, where
101
30.3k
         * the last one needs truncation. The blocks need to be reversed in
102
30.3k
         * order.
103
30.3k
         */
104
30.3k
        n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT1, *lp);
105
30.3k
        if (n < 0)
106
0
            goto err;
107
30.3k
        p += n;
108
166k
        while (lp != bn_data) {
109
136k
            lp--;
110
136k
            n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT2, *lp);
111
136k
            if (n < 0)
112
0
                goto err;
113
136k
            p += n;
114
136k
        }
115
30.3k
    }
116
30.3k
    ok = 1;
117
30.3k
 err:
118
30.3k
    OPENSSL_free(bn_data);
119
30.3k
    BN_free(t);
120
30.3k
    if (ok)
121
30.3k
        return buf;
122
0
    OPENSSL_free(buf);
123
0
    return NULL;
124
0
}
125
126
int BN_hex2bn(BIGNUM **bn, const char *a)
127
0
{
128
0
    BIGNUM *ret = NULL;
129
0
    BN_ULONG l = 0;
130
0
    int neg = 0, h, m, i, j, k, c;
131
0
    int num;
132
0
133
0
    if (a == NULL || *a == '\0')
134
0
        return 0;
135
0
136
0
    if (*a == '-') {
137
0
        neg = 1;
138
0
        a++;
139
0
    }
140
0
141
0
    for (i = 0; i <= INT_MAX / 4 && ossl_isxdigit(a[i]); i++)
142
0
        continue;
143
0
144
0
    if (i == 0 || i > INT_MAX / 4)
145
0
        goto err;
146
0
147
0
    num = i + neg;
148
0
    if (bn == NULL)
149
0
        return num;
150
0
151
0
    /* a is the start of the hex digits, and it is 'i' long */
152
0
    if (*bn == NULL) {
153
0
        if ((ret = BN_new()) == NULL)
154
0
            return 0;
155
0
    } else {
156
0
        ret = *bn;
157
0
        BN_zero(ret);
158
0
    }
159
0
160
0
    /* i is the number of hex digits */
161
0
    if (bn_expand(ret, i * 4) == NULL)
162
0
        goto err;
163
0
164
0
    j = i;                      /* least significant 'hex' */
165
0
    m = 0;
166
0
    h = 0;
167
0
    while (j > 0) {
168
0
        m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j;
169
0
        l = 0;
170
0
        for (;;) {
171
0
            c = a[j - m];
172
0
            k = OPENSSL_hexchar2int(c);
173
0
            if (k < 0)
174
0
                k = 0;          /* paranoia */
175
0
            l = (l << 4) | k;
176
0
177
0
            if (--m <= 0) {
178
0
                ret->d[h++] = l;
179
0
                break;
180
0
            }
181
0
        }
182
0
        j -= BN_BYTES * 2;
183
0
    }
184
0
    ret->top = h;
185
0
    bn_correct_top(ret);
186
0
187
0
    *bn = ret;
188
0
    bn_check_top(ret);
189
0
    /* Don't set the negative flag if it's zero. */
190
0
    if (ret->top != 0)
191
0
        ret->neg = neg;
192
0
    return num;
193
0
 err:
194
0
    if (*bn == NULL)
195
0
        BN_free(ret);
196
0
    return 0;
197
0
}
198
199
int BN_dec2bn(BIGNUM **bn, const char *a)
200
0
{
201
0
    BIGNUM *ret = NULL;
202
0
    BN_ULONG l = 0;
203
0
    int neg = 0, i, j;
204
0
    int num;
205
0
206
0
    if (a == NULL || *a == '\0')
207
0
        return 0;
208
0
    if (*a == '-') {
209
0
        neg = 1;
210
0
        a++;
211
0
    }
212
0
213
0
    for (i = 0; i <= INT_MAX / 4 && ossl_isdigit(a[i]); i++)
214
0
        continue;
215
0
216
0
    if (i == 0 || i > INT_MAX / 4)
217
0
        goto err;
218
0
219
0
    num = i + neg;
220
0
    if (bn == NULL)
221
0
        return num;
222
0
223
0
    /*
224
0
     * a is the start of the digits, and it is 'i' long. We chop it into
225
0
     * BN_DEC_NUM digits at a time
226
0
     */
227
0
    if (*bn == NULL) {
228
0
        if ((ret = BN_new()) == NULL)
229
0
            return 0;
230
0
    } else {
231
0
        ret = *bn;
232
0
        BN_zero(ret);
233
0
    }
234
0
235
0
    /* i is the number of digits, a bit of an over expand */
236
0
    if (bn_expand(ret, i * 4) == NULL)
237
0
        goto err;
238
0
239
0
    j = BN_DEC_NUM - i % BN_DEC_NUM;
240
0
    if (j == BN_DEC_NUM)
241
0
        j = 0;
242
0
    l = 0;
243
0
    while (--i >= 0) {
244
0
        l *= 10;
245
0
        l += *a - '0';
246
0
        a++;
247
0
        if (++j == BN_DEC_NUM) {
248
0
            if (!BN_mul_word(ret, BN_DEC_CONV)
249
0
                || !BN_add_word(ret, l))
250
0
                goto err;
251
0
            l = 0;
252
0
            j = 0;
253
0
        }
254
0
    }
255
0
256
0
    bn_correct_top(ret);
257
0
    *bn = ret;
258
0
    bn_check_top(ret);
259
0
    /* Don't set the negative flag if it's zero. */
260
0
    if (ret->top != 0)
261
0
        ret->neg = neg;
262
0
    return num;
263
0
 err:
264
0
    if (*bn == NULL)
265
0
        BN_free(ret);
266
0
    return 0;
267
0
}
268
269
int BN_asc2bn(BIGNUM **bn, const char *a)
270
0
{
271
0
    const char *p = a;
272
0
273
0
    if (*p == '-')
274
0
        p++;
275
0
276
0
    if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
277
0
        if (!BN_hex2bn(bn, p + 2))
278
0
            return 0;
279
0
    } else {
280
0
        if (!BN_dec2bn(bn, p))
281
0
            return 0;
282
0
    }
283
0
    /* Don't set the negative flag if it's zero. */
284
0
    if (*a == '-' && (*bn)->top != 0)
285
0
        (*bn)->neg = 1;
286
0
    return 1;
287
0
}
288
289
# ifndef OPENSSL_NO_STDIO
290
int BN_print_fp(FILE *fp, const BIGNUM *a)
291
0
{
292
0
    BIO *b;
293
0
    int ret;
294
0
295
0
    if ((b = BIO_new(BIO_s_file())) == NULL)
296
0
        return 0;
297
0
    BIO_set_fp(b, fp, BIO_NOCLOSE);
298
0
    ret = BN_print(b, a);
299
0
    BIO_free(b);
300
0
    return ret;
301
0
}
302
# endif
303
304
int BN_print(BIO *bp, const BIGNUM *a)
305
0
{
306
0
    int i, j, v, z = 0;
307
0
    int ret = 0;
308
0
309
0
    if ((a->neg) && BIO_write(bp, "-", 1) != 1)
310
0
        goto end;
311
0
    if (BN_is_zero(a) && BIO_write(bp, "0", 1) != 1)
312
0
        goto end;
313
0
    for (i = a->top - 1; i >= 0; i--) {
314
0
        for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
315
0
            /* strip leading zeros */
316
0
            v = (int)((a->d[i] >> j) & 0x0f);
317
0
            if (z || v != 0) {
318
0
                if (BIO_write(bp, &Hex[v], 1) != 1)
319
0
                    goto end;
320
0
                z = 1;
321
0
            }
322
0
        }
323
0
    }
324
0
    ret = 1;
325
0
 end:
326
0
    return ret;
327
0
}
328
329
char *BN_options(void)
330
0
{
331
0
    static int init = 0;
332
0
    static char data[16];
333
0
334
0
    if (!init) {
335
0
        init++;
336
#ifdef BN_LLONG
337
        BIO_snprintf(data, sizeof(data), "bn(%zu,%zu)",
338
                     sizeof(BN_ULLONG) * 8, sizeof(BN_ULONG) * 8);
339
#else
340
        BIO_snprintf(data, sizeof(data), "bn(%zu,%zu)",
341
0
                     sizeof(BN_ULONG) * 8, sizeof(BN_ULONG) * 8);
342
0
#endif
343
0
    }
344
0
    return data;
345
0
}