1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/base64.h>
58 
59 #include <assert.h>
60 #include <limits.h>
61 #include <string.h>
62 
63 #include <openssl/type_check.h>
64 
65 #include "../internal.h"
66 
67 
68 /* Encoding. */
69 
70 static const unsigned char data_bin2ascii[65] =
71     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
72 
73 #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
74 
75 OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0,
76                        data_length_must_be_multiple_of_base64_chunk_size);
77 
EVP_EncodedLength(size_t * out_len,size_t len)78 int EVP_EncodedLength(size_t *out_len, size_t len) {
79   if (len + 2 < len) {
80     return 0;
81   }
82   len += 2;
83   len /= 3;
84 
85   if (((len << 2) >> 2) != len) {
86     return 0;
87   }
88   len <<= 2;
89 
90   if (len + 1 < len) {
91     return 0;
92   }
93   len++;
94 
95   *out_len = len;
96   return 1;
97 }
98 
EVP_EncodeInit(EVP_ENCODE_CTX * ctx)99 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
100   OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
101 }
102 
EVP_EncodeUpdate(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len,const uint8_t * in,size_t in_len)103 void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
104                       const uint8_t *in, size_t in_len) {
105   size_t total = 0;
106 
107   *out_len = 0;
108   if (in_len == 0) {
109     return;
110   }
111 
112   assert(ctx->data_used < sizeof(ctx->data));
113 
114   if (sizeof(ctx->data) - ctx->data_used > in_len) {
115     OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len);
116     ctx->data_used += (unsigned)in_len;
117     return;
118   }
119 
120   if (ctx->data_used != 0) {
121     const size_t todo = sizeof(ctx->data) - ctx->data_used;
122     OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo);
123     in += todo;
124     in_len -= todo;
125 
126     size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data));
127     ctx->data_used = 0;
128 
129     out += encoded;
130     *(out++) = '\n';
131     *out = '\0';
132 
133     total = encoded + 1;
134   }
135 
136   while (in_len >= sizeof(ctx->data)) {
137     size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data));
138     in += sizeof(ctx->data);
139     in_len -= sizeof(ctx->data);
140 
141     out += encoded;
142     *(out++) = '\n';
143     *out = '\0';
144 
145     if (total + encoded + 1 < total) {
146       *out_len = 0;
147       return;
148     }
149 
150     total += encoded + 1;
151   }
152 
153   if (in_len != 0) {
154     OPENSSL_memcpy(ctx->data, in, in_len);
155   }
156 
157   ctx->data_used = (unsigned)in_len;
158 
159   if (total > INT_MAX) {
160     /* We cannot signal an error, but we can at least avoid making *out_len
161      * negative. */
162     total = 0;
163   }
164   *out_len = (int)total;
165 }
166 
EVP_EncodeFinal(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len)167 void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
168   if (ctx->data_used == 0) {
169     *out_len = 0;
170     return;
171   }
172 
173   size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used);
174   out[encoded++] = '\n';
175   out[encoded] = '\0';
176   ctx->data_used = 0;
177 
178   /* ctx->data_used is bounded by sizeof(ctx->data), so this does not
179    * overflow. */
180   assert(encoded <= INT_MAX);
181   *out_len = (int)encoded;
182 }
183 
EVP_EncodeBlock(uint8_t * dst,const uint8_t * src,size_t src_len)184 size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
185   uint32_t l;
186   size_t remaining = src_len, ret = 0;
187 
188   while (remaining) {
189     if (remaining >= 3) {
190       l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
191       *(dst++) = conv_bin2ascii(l >> 18L);
192       *(dst++) = conv_bin2ascii(l >> 12L);
193       *(dst++) = conv_bin2ascii(l >> 6L);
194       *(dst++) = conv_bin2ascii(l);
195       remaining -= 3;
196     } else {
197       l = ((uint32_t)src[0]) << 16L;
198       if (remaining == 2) {
199         l |= ((uint32_t)src[1] << 8L);
200       }
201 
202       *(dst++) = conv_bin2ascii(l >> 18L);
203       *(dst++) = conv_bin2ascii(l >> 12L);
204       *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
205       *(dst++) = '=';
206       remaining = 0;
207     }
208     ret += 4;
209     src += 3;
210   }
211 
212   *dst = '\0';
213   return ret;
214 }
215 
216 
217 /* Decoding. */
218 
EVP_DecodedLength(size_t * out_len,size_t len)219 int EVP_DecodedLength(size_t *out_len, size_t len) {
220   if (len % 4 != 0) {
221     return 0;
222   }
223 
224   *out_len = (len / 4) * 3;
225   return 1;
226 }
227 
EVP_DecodeInit(EVP_ENCODE_CTX * ctx)228 void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
229   OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
230 }
231 
232 /* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
233  * else 0xff if they are invalid. As a special case, the padding character
234  * ('=') is mapped to zero. */
235 static const uint8_t kBase64ASCIIToBinData[128] = {
236     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
237     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
238     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
239     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
240     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
241     0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
242     0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
243     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
244     0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
245     0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
246     0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
247 };
248 
base64_ascii_to_bin(uint8_t a)249 static uint8_t base64_ascii_to_bin(uint8_t a) {
250   if (a >= 128) {
251     return 0xFF;
252   }
253 
254   return kBase64ASCIIToBinData[a];
255 }
256 
257 /* base64_decode_quad decodes a single “quad” (i.e. four characters) of base64
258  * data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the
259  * number of bytes written, which will be less than three if the quad ended
260  * with padding.  It returns one on success or zero on error. */
base64_decode_quad(uint8_t * out,size_t * out_num_bytes,const uint8_t * in)261 static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes,
262                               const uint8_t *in) {
263   const uint8_t a = base64_ascii_to_bin(in[0]);
264   const uint8_t b = base64_ascii_to_bin(in[1]);
265   const uint8_t c = base64_ascii_to_bin(in[2]);
266   const uint8_t d = base64_ascii_to_bin(in[3]);
267   if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) {
268     return 0;
269   }
270 
271   const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 |
272                      ((uint32_t)c) << 6 | (uint32_t)d;
273 
274   const unsigned padding_pattern = (in[0] == '=') << 3 |
275                                    (in[1] == '=') << 2 |
276                                    (in[2] == '=') << 1 |
277                                    (in[3] == '=');
278 
279   switch (padding_pattern) {
280     case 0:
281       /* The common case of no padding. */
282       *out_num_bytes = 3;
283       out[0] = v >> 16;
284       out[1] = v >> 8;
285       out[2] = v;
286       break;
287 
288     case 1: /* xxx= */
289       *out_num_bytes = 2;
290       out[0] = v >> 16;
291       out[1] = v >> 8;
292       break;
293 
294     case 3: /* xx== */
295       *out_num_bytes = 1;
296       out[0] = v >> 16;
297       break;
298 
299     default:
300       return 0;
301   }
302 
303   return 1;
304 }
305 
EVP_DecodeUpdate(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len,const uint8_t * in,size_t in_len)306 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
307                      const uint8_t *in, size_t in_len) {
308   *out_len = 0;
309 
310   if (ctx->error_encountered) {
311     return -1;
312   }
313 
314   size_t bytes_out = 0, i;
315   for (i = 0; i < in_len; i++) {
316     const char c = in[i];
317     switch (c) {
318       case ' ':
319       case '\t':
320       case '\r':
321       case '\n':
322         continue;
323     }
324 
325     if (base64_ascii_to_bin(c) == 0xff || ctx->eof_seen) {
326       ctx->error_encountered = 1;
327       return -1;
328     }
329 
330     ctx->data[ctx->data_used++] = c;
331     if (ctx->data_used == 4) {
332       size_t num_bytes_resulting;
333       if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) {
334         ctx->error_encountered = 1;
335         return -1;
336       }
337 
338       ctx->data_used = 0;
339       bytes_out += num_bytes_resulting;
340       out += num_bytes_resulting;
341 
342       if (num_bytes_resulting < 3) {
343         ctx->eof_seen = 1;
344       }
345     }
346   }
347 
348   if (bytes_out > INT_MAX) {
349     ctx->error_encountered = 1;
350     *out_len = 0;
351     return -1;
352   }
353   *out_len = (int)bytes_out;
354 
355   if (ctx->eof_seen) {
356     return 0;
357   }
358 
359   return 1;
360 }
361 
EVP_DecodeFinal(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len)362 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
363   *out_len = 0;
364   if (ctx->error_encountered || ctx->data_used != 0) {
365     return -1;
366   }
367 
368   return 1;
369 }
370 
EVP_DecodeBase64(uint8_t * out,size_t * out_len,size_t max_out,const uint8_t * in,size_t in_len)371 int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
372                      const uint8_t *in, size_t in_len) {
373   *out_len = 0;
374 
375   if (in_len % 4 != 0) {
376     return 0;
377   }
378 
379   size_t max_len;
380   if (!EVP_DecodedLength(&max_len, in_len) ||
381       max_out < max_len) {
382     return 0;
383   }
384 
385   size_t i, bytes_out = 0;
386   for (i = 0; i < in_len; i += 4) {
387     size_t num_bytes_resulting;
388 
389     if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) {
390       return 0;
391     }
392 
393     bytes_out += num_bytes_resulting;
394     out += num_bytes_resulting;
395     if (num_bytes_resulting != 3 && i != in_len - 4) {
396       return 0;
397     }
398   }
399 
400   *out_len = bytes_out;
401   return 1;
402 }
403 
EVP_DecodeBlock(uint8_t * dst,const uint8_t * src,size_t src_len)404 int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
405   /* Trim spaces and tabs from the beginning of the input. */
406   while (src_len > 0) {
407     if (src[0] != ' ' && src[0] != '\t') {
408       break;
409     }
410 
411     src++;
412     src_len--;
413   }
414 
415   /* Trim newlines, spaces and tabs from the end of the line. */
416   while (src_len > 0) {
417     switch (src[src_len-1]) {
418       case ' ':
419       case '\t':
420       case '\r':
421       case '\n':
422         src_len--;
423         continue;
424     }
425 
426     break;
427   }
428 
429   size_t dst_len;
430   if (!EVP_DecodedLength(&dst_len, src_len) ||
431       dst_len > INT_MAX ||
432       !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
433     return -1;
434   }
435 
436   /* EVP_DecodeBlock does not take padding into account, so put the
437    * NULs back in... so the caller can strip them back out. */
438   while (dst_len % 3 != 0) {
439     dst[dst_len++] = '\0';
440   }
441   assert(dst_len <= INT_MAX);
442 
443   return (int)dst_len;
444 }
445