]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/evp/encode.c
PROV: add RSA signature implementation
[thirdparty/openssl.git] / crypto / evp / encode.c
CommitLineData
62867571 1/*
28428130 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
0f113f3e 3 *
4a8b0c55 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
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
d02b48c6
RE
8 */
9
10#include <stdio.h>
2bd5d70c 11#include <limits.h>
b39fc560 12#include "internal/cryptlib.h"
ec577822 13#include <openssl/evp.h>
25f2138b 14#include "crypto/evp.h"
706457b7 15#include "evp_local.h"
d02b48c6 16
3fd59700
MC
17static unsigned char conv_ascii2bin(unsigned char a,
18 const unsigned char *table);
19static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
20 const unsigned char *f, int dlen);
21static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
22 const unsigned char *f, int n);
23
a53955d8 24#ifndef CHARSET_EBCDIC
3fd59700 25# define conv_bin2ascii(a, table) ((table)[(a)&0x3f])
a53955d8 26#else
0f113f3e
MC
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)
a53955d8 32 */
3fd59700 33# define conv_bin2ascii(a, table) ((table)[(a)&0x3f])
a53955d8 34#endif
d02b48c6 35
1d97c843
TH
36/*-
37 * 64 char lines
d02b48c6
RE
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
3fd59700
MC
48static const unsigned char data_bin2ascii[65] =
49 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
50
51/* SRP uses a different base64 alphabet */
52static const unsigned char srpdata_bin2ascii[65] =
53 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
54
d02b48c6 55
1d97c843
TH
56/*-
57 * 0xF0 is a EOLN
d02b48c6
RE
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
0f113f3e
MC
64#define B64_EOLN 0xF0
65#define B64_CR 0xF1
66#define B64_EOF 0xF2
67#define B64_WS 0xE0
68#define B64_ERROR 0xFF
69#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
2cdce3e3 70#define B64_BASE64(a) (!B64_NOT_BASE64(a))
0f113f3e
MC
71
72static 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};
d02b48c6 90
3fd59700
MC
91static 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
b785504a 110#ifndef CHARSET_EBCDIC
3fd59700 111static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
b785504a
EK
112{
113 if (a & 0x80)
114 return B64_ERROR;
3fd59700 115 return table[a];
b785504a
EK
116}
117#else
3fd59700 118static unsigned char conv_ascii2bin(unsigned char a, const unsigned char *table)
b785504a
EK
119{
120 a = os_toascii[a];
121 if (a & 0x80)
122 return B64_ERROR;
3fd59700 123 return table[a];
b785504a
EK
124}
125#endif
126
a0be4fd1
RL
127EVP_ENCODE_CTX *EVP_ENCODE_CTX_new(void)
128{
43ecb9c3 129 return OPENSSL_zalloc(sizeof(EVP_ENCODE_CTX));
a0be4fd1
RL
130}
131
132void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx)
133{
134 OPENSSL_free(ctx);
135}
c1054bb4 136
9fdcc21f 137int EVP_ENCODE_CTX_copy(EVP_ENCODE_CTX *dctx, const EVP_ENCODE_CTX *sctx)
c1054bb4
JZ
138{
139 memcpy(dctx, sctx, sizeof(EVP_ENCODE_CTX));
140
141 return 1;
142}
143
a0be4fd1
RL
144int EVP_ENCODE_CTX_num(EVP_ENCODE_CTX *ctx)
145{
146 return ctx->num;
147}
148
c0804614
MC
149void evp_encode_ctx_set_flags(EVP_ENCODE_CTX *ctx, unsigned int flags)
150{
151 ctx->flags = flags;
152}
153
6b691a5c 154void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
0f113f3e
MC
155{
156 ctx->length = 48;
157 ctx->num = 0;
158 ctx->line_num = 0;
c0804614 159 ctx->flags = 0;
0f113f3e 160}
d02b48c6 161
cf3404fc 162int EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
0f113f3e
MC
163 const unsigned char *in, int inl)
164{
165 int i, j;
2bd5d70c 166 size_t total = 0;
0f113f3e
MC
167
168 *outl = 0;
b86d7dca 169 if (inl <= 0)
cf3404fc 170 return 0;
0f113f3e 171 OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
ee1e3cac 172 if (ctx->length - ctx->num > inl) {
0f113f3e
MC
173 memcpy(&(ctx->enc_data[ctx->num]), in, inl);
174 ctx->num += inl;
cf3404fc 175 return 1;
0f113f3e
MC
176 }
177 if (ctx->num != 0) {
178 i = ctx->length - ctx->num;
179 memcpy(&(ctx->enc_data[ctx->num]), in, i);
180 in += i;
181 inl -= i;
3fd59700 182 j = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->length);
0f113f3e
MC
183 ctx->num = 0;
184 out += j;
c0804614
MC
185 total = j;
186 if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
187 *(out++) = '\n';
188 total++;
189 }
0f113f3e 190 *out = '\0';
0f113f3e 191 }
2bd5d70c 192 while (inl >= ctx->length && total <= INT_MAX) {
3fd59700 193 j = evp_encodeblock_int(ctx, out, in, ctx->length);
0f113f3e
MC
194 in += ctx->length;
195 inl -= ctx->length;
196 out += j;
c0804614
MC
197 total += j;
198 if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0) {
199 *(out++) = '\n';
200 total++;
201 }
0f113f3e 202 *out = '\0';
0f113f3e 203 }
2bd5d70c
MC
204 if (total > INT_MAX) {
205 /* Too much output data! */
206 *outl = 0;
cf3404fc 207 return 0;
2bd5d70c 208 }
0f113f3e
MC
209 if (inl != 0)
210 memcpy(&(ctx->enc_data[0]), in, inl);
211 ctx->num = inl;
212 *outl = total;
cf3404fc
MC
213
214 return 1;
0f113f3e 215}
d02b48c6 216
6b691a5c 217void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
0f113f3e
MC
218{
219 unsigned int ret = 0;
220
221 if (ctx->num != 0) {
3fd59700 222 ret = evp_encodeblock_int(ctx, out, ctx->enc_data, ctx->num);
c0804614
MC
223 if ((ctx->flags & EVP_ENCODE_CTX_NO_NEWLINES) == 0)
224 out[ret++] = '\n';
0f113f3e
MC
225 out[ret] = '\0';
226 ctx->num = 0;
227 }
228 *outl = ret;
229}
d02b48c6 230
3fd59700
MC
231static int evp_encodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
232 const unsigned char *f, int dlen)
0f113f3e
MC
233{
234 int i, ret = 0;
235 unsigned long l;
3fd59700
MC
236 const unsigned char *table;
237
238 if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
239 table = srpdata_bin2ascii;
240 else
241 table = data_bin2ascii;
0f113f3e
MC
242
243 for (i = dlen; i > 0; i -= 3) {
244 if (i >= 3) {
245 l = (((unsigned long)f[0]) << 16L) |
246 (((unsigned long)f[1]) << 8L) | f[2];
3fd59700
MC
247 *(t++) = conv_bin2ascii(l >> 18L, table);
248 *(t++) = conv_bin2ascii(l >> 12L, table);
249 *(t++) = conv_bin2ascii(l >> 6L, table);
250 *(t++) = conv_bin2ascii(l, table);
0f113f3e
MC
251 } else {
252 l = ((unsigned long)f[0]) << 16L;
253 if (i == 2)
254 l |= ((unsigned long)f[1] << 8L);
255
3fd59700
MC
256 *(t++) = conv_bin2ascii(l >> 18L, table);
257 *(t++) = conv_bin2ascii(l >> 12L, table);
258 *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L, table);
0f113f3e
MC
259 *(t++) = '=';
260 }
261 ret += 4;
262 f += 3;
263 }
264
265 *t = '\0';
26a7d938 266 return ret;
0f113f3e 267}
d02b48c6 268
3fd59700
MC
269int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
270{
271 return evp_encodeblock_int(NULL, t, f, dlen);
272}
273
6b691a5c 274void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
0f113f3e 275{
c0804614 276 /* Only ctx->num and ctx->flags are used during decoding. */
0f113f3e 277 ctx->num = 0;
3cdd1e94 278 ctx->length = 0;
0f113f3e 279 ctx->line_num = 0;
c0804614 280 ctx->flags = 0;
0f113f3e 281}
d02b48c6 282
1d97c843
TH
283/*-
284 * -1 for error
d02b48c6
RE
285 * 0 for last line
286 * 1 for full line
3cdd1e94
EK
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.
d02b48c6 302 */
6b691a5c 303int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
0f113f3e
MC
304 const unsigned char *in, int inl)
305{
3cdd1e94 306 int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len;
0f113f3e 307 unsigned char *d;
3fd59700 308 const unsigned char *table;
0f113f3e
MC
309
310 n = ctx->num;
311 d = ctx->enc_data;
0f113f3e 312
3cdd1e94
EK
313 if (n > 0 && d[n - 1] == '=') {
314 eof++;
315 if (n > 1 && d[n - 2] == '=')
316 eof++;
317 }
318
319 /* Legacy behaviour: an empty input chunk signals end of input. */
320 if (inl == 0) {
0f113f3e
MC
321 rv = 0;
322 goto end;
323 }
324
3fd59700
MC
325 if ((ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
326 table = srpdata_ascii2bin;
327 else
328 table = data_ascii2bin;
329
0f113f3e 330 for (i = 0; i < inl; i++) {
0f113f3e 331 tmp = *(in++);
3fd59700 332 v = conv_ascii2bin(tmp, table);
3cdd1e94 333 if (v == B64_ERROR) {
0f113f3e
MC
334 rv = -1;
335 goto end;
336 }
337
0f113f3e 338 if (tmp == '=') {
0f113f3e 339 eof++;
3cdd1e94
EK
340 } else if (eof > 0 && B64_BASE64(v)) {
341 /* More data after padding. */
342 rv = -1;
343 goto end;
0f113f3e
MC
344 }
345
3cdd1e94
EK
346 if (eof > 2) {
347 rv = -1;
348 goto end;
0f113f3e
MC
349 }
350
3cdd1e94
EK
351 if (v == B64_EOF) {
352 seof = 1;
353 goto tail;
0f113f3e
MC
354 }
355
3cdd1e94
EK
356 /* Only save valid base64 characters. */
357 if (B64_BASE64(v)) {
358 if (n >= 64) {
359 /*
360 * We increment n once per loop, and empty the buffer as soon as
361 * we reach 64 characters, so this can only happen if someone's
362 * manually messed with the ctx. Refuse to write any more data.
363 */
364 rv = -1;
0f113f3e 365 goto end;
3cdd1e94
EK
366 }
367 OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
368 d[n++] = tmp;
369 }
0f113f3e 370
3cdd1e94 371 if (n == 64) {
3fd59700 372 decoded_len = evp_decodeblock_int(ctx, out, d, n);
3cdd1e94
EK
373 n = 0;
374 if (decoded_len < 0 || eof > decoded_len) {
375 rv = -1;
0f113f3e
MC
376 goto end;
377 }
3cdd1e94
EK
378 ret += decoded_len - eof;
379 out += decoded_len - eof;
0f113f3e
MC
380 }
381 }
3cdd1e94
EK
382
383 /*
384 * Legacy behaviour: if the current line is a full base64-block (i.e., has
385 * 0 mod 4 base64 characters), it is processed immediately. We keep this
386 * behaviour as applications may not be calling EVP_DecodeFinal properly.
387 */
388tail:
389 if (n > 0) {
390 if ((n & 3) == 0) {
3fd59700 391 decoded_len = evp_decodeblock_int(ctx, out, d, n);
4fe1cbdf
VD
392 n = 0;
393 if (decoded_len < 0 || eof > decoded_len) {
394 rv = -1;
395 goto end;
396 }
397 ret += (decoded_len - eof);
3cdd1e94
EK
398 } else if (seof) {
399 /* EOF in the middle of a base64 block. */
400 rv = -1;
401 goto end;
402 }
403 }
404
405 rv = seof || (n == 0 && eof) ? 0 : 1;
406end:
407 /* Legacy behaviour. This should probably rather be zeroed on error. */
0f113f3e
MC
408 *outl = ret;
409 ctx->num = n;
26a7d938 410 return rv;
0f113f3e 411}
d02b48c6 412
3fd59700
MC
413static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t,
414 const unsigned char *f, int n)
0f113f3e
MC
415{
416 int i, ret = 0, a, b, c, d;
417 unsigned long l;
3fd59700
MC
418 const unsigned char *table;
419
420 if (ctx != NULL && (ctx->flags & EVP_ENCODE_CTX_USE_SRP_ALPHABET) != 0)
421 table = srpdata_ascii2bin;
422 else
423 table = data_ascii2bin;
0f113f3e
MC
424
425 /* trim white space from the start of the line. */
3fd59700 426 while ((conv_ascii2bin(*f, table) == B64_WS) && (n > 0)) {
0f113f3e
MC
427 f++;
428 n--;
429 }
430
431 /*
432 * strip off stuff at the end of the line ascii2bin values B64_WS,
433 * B64_EOLN, B64_EOLN and B64_EOF
434 */
3fd59700 435 while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1], table))))
0f113f3e
MC
436 n--;
437
438 if (n % 4 != 0)
26a7d938 439 return -1;
0f113f3e
MC
440
441 for (i = 0; i < n; i += 4) {
3fd59700
MC
442 a = conv_ascii2bin(*(f++), table);
443 b = conv_ascii2bin(*(f++), table);
444 c = conv_ascii2bin(*(f++), table);
445 d = conv_ascii2bin(*(f++), table);
0f113f3e 446 if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80))
26a7d938 447 return -1;
0f113f3e
MC
448 l = ((((unsigned long)a) << 18L) |
449 (((unsigned long)b) << 12L) |
450 (((unsigned long)c) << 6L) | (((unsigned long)d)));
451 *(t++) = (unsigned char)(l >> 16L) & 0xff;
452 *(t++) = (unsigned char)(l >> 8L) & 0xff;
453 *(t++) = (unsigned char)(l) & 0xff;
454 ret += 3;
455 }
26a7d938 456 return ret;
0f113f3e 457}
d02b48c6 458
3fd59700
MC
459int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
460{
461 return evp_decodeblock_int(NULL, t, f, n);
462}
463
6b691a5c 464int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
0f113f3e
MC
465{
466 int i;
467
468 *outl = 0;
469 if (ctx->num != 0) {
3fd59700 470 i = evp_decodeblock_int(ctx, out, ctx->enc_data, ctx->num);
0f113f3e 471 if (i < 0)
26a7d938 472 return -1;
0f113f3e
MC
473 ctx->num = 0;
474 *outl = i;
208fb891 475 return 1;
0f113f3e 476 } else
208fb891 477 return 1;
0f113f3e 478}