Coverage Report

Created: 2018-08-29 13:53

/src/openssl/crypto/evp/encode.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 1995-2018 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 <limits.h>
12
#include "internal/cryptlib.h"
13
#include <openssl/evp.h>
14
#include "evp_locl.h"
15
#include "internal/evp_int.h"
16
17
static unsigned char conv_ascii2bin(unsigned char a,
18
                                    const unsigned char *table);
19
static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
20
                               const unsigned char *f, int dlen);
21
static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
22
                               const unsigned char *f, int n);
23
24
#ifndef CHARSET_EBCDIC
25
0
# define conv_bin2ascii(a, table)       ((table)[(a)&0x3f])
26
#else
27
/*
28
 * We assume that PEM encoded files are EBCDIC files (i.e., printable text
29
 * files). Convert them here while decoding. When encoding, output is EBCDIC
30
 * (text) format again. (No need for conversion in the conv_bin2ascii macro,
31
 * as the underlying textstring data_bin2ascii[] is already EBCDIC)
32
 */
33
# define conv_bin2ascii(a, table)       ((table)[(a)&0x3f])
34
#endif
35
36
/*-
37
 * 64 char lines
38
 * pad input with 0
39
 * left over chars are set to =
40
 * 1 byte  => xx==
41
 * 2 bytes => xxx=
42
 * 3 bytes => xxxx
43
 */
44
#define BIN_PER_LINE    (64/4*3)
45
#define CHUNKS_PER_LINE (64/4)
46
#define CHAR_PER_LINE   (64+1)
47
48
static const unsigned char data_bin2ascii[65] =
49
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
50
51
/* SRP uses a different base64 alphabet */
52
static const unsigned char srpdata_bin2ascii[65] =
53
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
54
55
56
/*-
57
 * 0xF0 is a EOLN
58
 * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
59
 * 0xF2 is EOF
60
 * 0xE0 is ignore at start of line.
61
 * 0xFF is error
62
 */
63
64
#define B64_EOLN                0xF0
65
#define B64_CR                  0xF1
66
89.0M
#define B64_EOF                 0xF2
67
1.51M
#define B64_WS                  0xE0
68
89.0M
#define B64_ERROR               0xFF
69
90.4M
#define B64_NOT_BASE64(a)       (((a)|0x13) == 0xF3)
70
88.9M
#define B64_BASE64(a)           (!B64_NOT_BASE64(a))
71
72
static const unsigned char data_ascii2bin[128] = {
73
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
74
    0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
75
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
76
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
77
    0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
78
    0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
79
    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
80
    0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
81
    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
82
    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
83
    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
84
    0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
85
    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
86
    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
87
    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
88
    0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89
};
90
91
static const unsigned char srpdata_ascii2bin[128] = {
92
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93
    0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF,
94
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
95
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96
    0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
97
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, 0x3E, 0x3F,
98
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
99
    0x08, 0x09, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF,
100
    0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
101
    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
102
    0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
103
    0x21, 0x22, 0x23, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
104
    0xFF, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
105
    0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
106
    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
107
    0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
108
};
109
110
#ifndef CHARSET_EBCDIC
111
static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
112
179M
{
113
179M
    if (a & 0x80)
114
1.66k
        return B64_ERROR;
115
179M
    return table[a];
116
179M
}
117
#else
118
static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
119
{
120
    a = os_toascii[a];
121
    if (a & 0x80)
122
        return B64_ERROR;
123
    return table[a];
124
}
125
#endif
126
127
EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
128
287k
{
129
287k
    return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
130
287k
}
131
132
void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
133
287k
{
134
287k
    OPENSSL_free(ctx);
135
287k
}
136
137
int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, EVP_ENCODE_CTX *sctx)
138
0
{
139
0
    memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
140
0
141
0
    return 1;
142
0
}
143
144
int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
145
0
{
146
0
    return ctx->num;
147
0
}
148
149
void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags)
150
0
{
151
0
    ctx->flags = flags;
152
0
}
153
154
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
155
0
{
156
0
    ctx->length = 48;
157
0
    ctx->num = 0;
158
0
    ctx->line_num = 0;
159
0
    ctx->flags = 0;
160
0
}
161
162
int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
163
                      const unsigned char *in, int inl)
164
0
{
165
0
    int i, j;
166
0
    size_t total = 0;
167
0
168
0
    *outl = 0;
169
0
    if (inl <= 0)
170
0
        return 0;
171
0
    OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
172
0
    if (ctx->length - ctx->num > inl) {
173
0
        memcpy(&(ctx->enc_data[ctx->num]), in, inl);
174
0
        ctx->num += inl;
175
0
        return 1;
176
0
    }
177
0
    if (ctx->num != 0) {
178
0
        i = ctx->length - ctx->num;
179
0
        memcpy(&(ctx->enc_data[ctx->num]), in, i);
180
0
        in += i;
181
0
        inl -= i;
182
0
        j = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->length);
183
0
        ctx->num = 0;
184
0
        out += j;
185
0
        total = j;
186
0
        if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
187
0
            *(out++) = '\n';
188
0
            total++;
189
0
        }
190
0
        *out = '\0';
191
0
    }
192
0
    while (inl >= ctx->length && total <= INT_MAX) {
193
0
        j = evp_encodeblock_int(ctx, out, in, ctx->length);
194
0
        in += ctx->length;
195
0
        inl -= ctx->length;
196
0
        out += j;
197
0
        total += j;
198
0
        if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
199
0
            *(out++) = '\n';
200
0
            total++;
201
0
        }
202
0
        *out = '\0';
203
0
    }
204
0
    if (total > INT_MAX) {
205
0
        /* Too much output data! */
206
0
        *outl = 0;
207
0
        return 0;
208
0
    }
209
0
    if (inl != 0)
210
0
        memcpy(&(ctx->enc_data[0]), in, inl);
211
0
    ctx->num = inl;
212
0
    *outl = total;
213
0
214
0
    return 1;
215
0
}
216
217
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
218
0
{
219
0
    unsigned int ret = 0;
220
0
221
0
    if (ctx->num != 0) {
222
0
        ret = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->num);
223
0
        if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0)
224
0
            out[ret++] = '\n';
225
0
        out[ret] = '\0';
226
0
        ctx->num = 0;
227
0
    }
228
0
    *outl = ret;
229
0
}
230
231
static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
232
                               const unsigned char *f, int dlen)
233
0
{
234
0
    int i, ret = 0;
235
0
    unsigned long l;
236
0
    const unsigned char *table;
237
0
238
0
    if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
239
0
        table = srpdata_bin2ascii;
240
0
    else
241
0
        table = data_bin2ascii;
242
0
243
0
    for (i = dlen; i > 0; i -= 3) {
244
0
        if (i >= 3) {
245
0
            l = (((unsigned long)f[0]) << 16L) |
246
0
                (((unsigned long)f[1]) << 8L) | f[2];
247
0
            *(t++) = conv_bin2ascii(l >> 18L, table);
248
0
            *(t++) = conv_bin2ascii(l >> 12L, table);
249
0
            *(t++) = conv_bin2ascii(l >> 6L, table);
250
0
            *(t++) = conv_bin2ascii(l, table);
251
0
        } else {
252
0
            l = ((unsigned long)f[0]) << 16L;
253
0
            if (i == 2)
254
0
                l |= ((unsigned long)f[1] << 8L);
255
0
256
0
            *(t++) = conv_bin2ascii(l >> 18L, table);
257
0
            *(t++) = conv_bin2ascii(l >> 12L, table);
258
0
            *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L, table);
259
0
            *(t++) = '=';
260
0
        }
261
0
        ret += 4;
262
0
        f += 3;
263
0
    }
264
0
265
0
    *t = '\0';
266
0
    return ret;
267
0
}
268
269
int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
270
0
{
271
0
    return evp_encodeblock_int(NULL, t, f, dlen);
272
0
}
273
274
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
275
282k
{
276
282k
    /* Only ctx->num and ctx->flags are used during decoding. */
277
282k
    ctx->num = 0;
278
282k
    ctx->length = 0;
279
282k
    ctx->line_num = 0;
280
282k
    ctx->flags = 0;
281
282k
}
282
283
/*-
284
 * -1 for error
285
 *  0 for last line
286
 *  1 for full line
287
 *
288
 * Note: even though EVP_DecodeUpdate attempts to detect and report end of
289
 * content, the context doesn't currently remember it and will accept more data
290
 * in the next call. Therefore, the caller is responsible for checking and
291
 * rejecting a 0 return value in the middle of content.
292
 *
293
 * Note: even though EVP_DecodeUpdate has historically tried to detect end of
294
 * content based on line length, this has never worked properly. Therefore,
295
 * we now return 0 when one of the following is true:
296
 *   - Padding or B64_EOF was detected and the last block is complete.
297
 *   - Input has zero-length.
298
 * -1 is returned if:
299
 *   - Invalid characters are detected.
300
 *   - There is extra trailing padding, or data after padding.
301
 *   - B64_EOF is detected after an incomplete base64 block.
302
 */
303
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
304
                     const unsigned char *in, int inl)
305
282k
{
306
282k
    int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
307
282k
    unsigned char *d;
308
282k
    const unsigned char *table;
309
282k
310
282k
    n = ctx->num;
311
282k
    d = ctx->enc_data;
312
282k
313
282k
    if (n > 0 && d[n - 1] == '=') {
314
0
        eof++;
315
0
        if (n > 1 && d[n - 2] == '=')
316
0
            eof++;
317
0
    }
318
282k
319
282k
     /* Legacy behaviour: an empty input chunk signals end of input. */
320
282k
    if (inl == 0) {
321
2.59k
        rv = 0;
322
2.59k
        goto end;
323
2.59k
    }
324
279k
325
279k
    if ((ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
326
0
        table = srpdata_ascii2bin;
327
279k
    else
328
279k
        table = data_ascii2bin;
329
279k
330
89.2M
    for (i = 0; i < inl; i++) {
331
89.0M
        tmp = *(in++);
332
89.0M
        v = conv_ascii2bin(tmp, table);
333
89.0M
        if (v == B64_ERROR) {
334
3.86k
            rv = -1;
335
3.86k
            goto end;
336
3.86k
        }
337
89.0M
338
89.0M
        if (tmp == '=') {
339
54.4k
            eof++;
340
88.9M
        } else if (eof > 0 && B64_BASE64(v)) {
341
685
            /* More data after padding. */
342
685
            rv = -1;
343
685
            goto end;
344
685
        }
345
89.0M
346
89.0M
        if (eof > 2) {
347
472
            rv = -1;
348
472
            goto end;
349
472
        }
350
89.0M
351
89.0M
        if (v == B64_EOF) {
352
79.9k
            seof = 1;
353
79.9k
            goto tail;
354
79.9k
        }
355
88.9M
356
88.9M
        /* Only save valid base64 characters. */
357
88.9M
        if (B64_BASE64(v)) {
358
87.9M
            if (n >= 64) {
359
0
                /*
360
0
                 * We increment n once per loop, and empty the buffer as soon as
361
0
                 * we reach 64 characters, so this can only happen if someone's
362
0
                 * manually messed with the ctx. Refuse to write any more data.
363
0
                 */
364
0
                rv = -1;
365
0
                goto end;
366
0
            }
367
87.9M
            OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
368
87.9M
            d[n++] = tmp;
369
87.9M
        }
370
88.9M
371
88.9M
        if (n == 64) {
372
1.24M
            decoded_len = evp_decodeblock_int(ctx, out, d, n);
373
1.24M
            n = 0;
374
1.24M
            if (decoded_len < 0 || eof > decoded_len) {
375
0
                rv = -1;
376
0
                goto end;
377
0
            }
378
1.24M
            ret += decoded_len - eof;
379
1.24M
            out += decoded_len - eof;
380
1.24M
        }
381
88.9M
    }
382
279k
383
279k
    /*
384
279k
     * Legacy behaviour: if the current line is a full base64-block (i.e., has
385
279k
     * 0 mod 4 base64 characters), it is processed immediately. We keep this
386
279k
     * behaviour as applications may not be calling EVP_DecodeFinal properly.
387
279k
     */
388
279k
tail:
389
274k
    if (n > 0) {
390
267k
        if ((n & 3) == 0) {
391
261k
            decoded_len = evp_decodeblock_int(ctx, out, d, n);
392
261k
            n = 0;
393
261k
            if (decoded_len < 0 || eof > decoded_len) {
394
0
                rv = -1;
395
0
                goto end;
396
0
            }
397
261k
            ret += (decoded_len - eof);
398
261k
        } else if (seof) {
399
2.27k
            /* EOF in the middle of a base64 block. */
400
2.27k
            rv = -1;
401
2.27k
            goto end;
402
2.27k
        }
403
272k
    }
404
272k
405
272k
    rv = seof || (n == 0 && eof) ? 0 : 1;
406
282k
end:
407
282k
    /* Legacy behaviour. This should probably rather be zeroed on error. */
408
282k
    *outl = ret;
409
282k
    ctx->num = n;
410
282k
    return rv;
411
272k
}
412
413
static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
414
                               const unsigned char *f, int n)
415
1.51M
{
416
1.51M
    int i, ret = 0, a, b, c, d;
417
1.51M
    unsigned long l;
418
1.51M
    const unsigned char *table;
419
1.51M
420
1.51M
    if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
421
0
        table = srpdata_ascii2bin;
422
1.51M
    else
423
1.51M
        table = data_ascii2bin;
424
1.51M
425
1.51M
    /* trim white space from the start of the line. */
426
1.51M
    while ((conv_ascii2bin(*f, table) == B64_WS) && (n > 0)) {
427
0
        f++;
428
0
        n--;
429
0
    }
430
1.51M
431
1.51M
    /*
432
1.51M
     * strip off stuff at the end of the line ascii2bin values B64_WS,
433
1.51M
     * B64_EOLN, B64_EOLN and B64_EOF
434
1.51M
     */
435
1.51M
    while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1], table))))
436
0
        n--;
437
1.51M
438
1.51M
    if (n % 4 != 0)
439
3.40k
        return -1;
440
1.50M
441
23.4M
    for (i = 0; i < n; i += 4) {
442
21.9M
        a = conv_ascii2bin(*(f++), table);
443
21.9M
        b = conv_ascii2bin(*(f++), table);
444
21.9M
        c = conv_ascii2bin(*(f++), table);
445
21.9M
        d = conv_ascii2bin(*(f++), table);
446
21.9M
        if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
447
0
            return -1;
448
21.9M
        l = ((((unsigned long)a) << 18L) |
449
21.9M
             (((unsigned long)b) << 12L) |
450
21.9M
             (((unsigned long)c) << 6L) | (((unsigned long)d)));
451
21.9M
        *(t++) = (unsigned char)(l >> 16L) & 0xff;
452
21.9M
        *(t++) = (unsigned char)(l >> 8L) & 0xff;
453
21.9M
        *(t++) = (unsigned char)(l) & 0xff;
454
21.9M
        ret += 3;
455
21.9M
    }
456
1.50M
    return ret;
457
1.50M
}
458
459
int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
460
0
{
461
0
    return evp_decodeblock_int(NULL, t, f, n);
462
0
}
463
464
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
465
274k
{
466
274k
    int i;
467
274k
468
274k
    *outl = 0;
469
274k
    if (ctx->num != 0) {
470
3.40k
        i = evp_decodeblock_int(ctx, out, ctx->enc_data, ctx->num);
471
3.40k
        if (i < 0)
472
3.40k
            return -1;
473
0
        ctx->num = 0;
474
0
        *outl = i;
475
0
        return 1;
476
0
    } else
477
271k
        return 1;
478
274k
}