aboutsummaryrefslogtreecommitdiff
path: root/crypto/base64
diff options
context:
space:
mode:
authorAdam Langley <agl@chromium.org>2014-06-20 12:00:00 -0700
committerAdam Langley <agl@chromium.org>2014-06-20 13:17:32 -0700
commit95c29f3cd1f6c08c6c0927868683392eea727ccb (patch)
tree012767320ced9abca61472a4daa4c4a56b7ebe2b /crypto/base64
downloadboringssl-95c29f3cd1f6c08c6c0927868683392eea727ccb.zip
boringssl-95c29f3cd1f6c08c6c0927868683392eea727ccb.tar.gz
boringssl-95c29f3cd1f6c08c6c0927868683392eea727ccb.tar.bz2
Inital import.
Initial fork from f2d678e6e89b6508147086610e985d4e8416e867 (1.0.2 beta). (This change contains substantial changes from the original and effectively starts a new history.)
Diffstat (limited to 'crypto/base64')
-rw-r--r--crypto/base64/CMakeLists.txt9
-rw-r--r--crypto/base64/base64.c391
-rw-r--r--crypto/base64/base64.h141
3 files changed, 541 insertions, 0 deletions
diff --git a/crypto/base64/CMakeLists.txt b/crypto/base64/CMakeLists.txt
new file mode 100644
index 0000000..2601abd
--- /dev/null
+++ b/crypto/base64/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(. .. ../../include)
+
+add_library(
+ base64
+
+ OBJECT
+
+ base64.c
+)
diff --git a/crypto/base64/base64.c b/crypto/base64/base64.c
new file mode 100644
index 0000000..fb9aa36
--- /dev/null
+++ b/crypto/base64/base64.c
@@ -0,0 +1,391 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/base64.h>
+
+#include <assert.h>
+
+
+static const unsigned char data_bin2ascii[65] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+#define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
+#define conv_ascii2bin(a) (data_ascii2bin[(a) & 0x7f])
+
+/* 64 char lines
+ * pad input with 0
+ * left over chars are set to =
+ * 1 byte => xx==
+ * 2 bytes => xxx=
+ * 3 bytes => xxxx
+ */
+#define BIN_PER_LINE (64/4*3)
+#define CHUNKS_PER_LINE (64/4)
+#define CHAR_PER_LINE (64+1)
+
+/* 0xF0 is a EOLN
+ * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
+ * 0xF2 is EOF
+ * 0xE0 is ignore at start of line.
+ * 0xFF is error */
+
+#define B64_EOLN 0xF0
+#define B64_CR 0xF1
+#define B64_EOF 0xF2
+#define B64_WS 0xE0
+#define B64_ERROR 0xFF
+#define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
+
+static const unsigned char data_ascii2bin[128] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
+ 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
+ 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
+ ctx->length = 48;
+ ctx->num = 0;
+ ctx->line_num = 0;
+}
+
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
+ const uint8_t *in, size_t in_len) {
+ unsigned i, j;
+ unsigned total = 0;
+
+ *out_len = 0;
+ if (in_len == 0) {
+ return;
+ }
+
+ assert(ctx->length <= sizeof(ctx->enc_data));
+
+ if ((ctx->num + in_len) < ctx->length) {
+ memcpy(&ctx->enc_data[ctx->num], in, in_len);
+ ctx->num += in_len;
+ return;
+ }
+ if (ctx->num != 0) {
+ i = ctx->length - ctx->num;
+ memcpy(&ctx->enc_data[ctx->num], in, i);
+ in += i;
+ in_len -= i;
+ j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
+ ctx->num = 0;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total = j + 1;
+ }
+ while (in_len >= ctx->length) {
+ j = EVP_EncodeBlock(out, in, ctx->length);
+ in += ctx->length;
+ in_len -= ctx->length;
+ out += j;
+ *(out++) = '\n';
+ *out = '\0';
+ total += j + 1;
+ }
+ if (in_len != 0) {
+ memcpy(&ctx->enc_data[0], in, in_len);
+ }
+ ctx->num = in_len;
+ *out_len = total;
+}
+
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
+ unsigned ret = 0;
+
+ if (ctx->num != 0) {
+ ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
+ out[ret++] = '\n';
+ out[ret] = '\0';
+ ctx->num = 0;
+ }
+ *out_len = ret;
+}
+
+size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
+ unsigned long l;
+ size_t i, ret = 0;
+
+ for (i = src_len; i > 0; i -= 3) {
+ if (i >= 3) {
+ l = (((unsigned long)src[0]) << 16L) | (((unsigned long)src[1]) << 8L) | src[2];
+ *(dst++) = conv_bin2ascii(l >> 18L);
+ *(dst++) = conv_bin2ascii(l >> 12L);
+ *(dst++) = conv_bin2ascii(l >> 6L);
+ *(dst++) = conv_bin2ascii(l);
+ } else {
+ l = ((unsigned long)src[0]) << 16L;
+ if (i == 2) {
+ l |= ((unsigned long)src[1] << 8L);
+ }
+
+ *(dst++) = conv_bin2ascii(l >> 18L);
+ *(dst++) = conv_bin2ascii(l >> 12L);
+ *(dst++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L);
+ *(dst++) = '=';
+ }
+ ret += 4;
+ src += 3;
+ }
+
+ *dst = '\0';
+ return ret;
+}
+
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
+ ctx->length = 30;
+ ctx->num = 0;
+ ctx->line_num = 0;
+ ctx->expect_nl = 0;
+}
+
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
+ const uint8_t *in, size_t in_len) {
+ int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
+ uint8_t *d;
+ unsigned i, n, ln, ret = 0;
+
+ n = ctx->num;
+ d = ctx->enc_data;
+ ln = ctx->line_num;
+ exp_nl = ctx->expect_nl;
+
+ /* last line of input. */
+ if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
+ rv = 0;
+ goto end;
+ }
+
+ /* We parse the input data */
+ for (i = 0; i < in_len; i++) {
+ /* If the current line is > 80 characters, scream alot */
+ if (ln >= 80) {
+ rv = -1;
+ goto end;
+ }
+
+ /* Get char and put it into the buffer */
+ tmp = *(in++);
+ v = conv_ascii2bin(tmp);
+ /* only save the good data :-) */
+ if (!B64_NOT_BASE64(v)) {
+ assert(n < sizeof(ctx->enc_data));
+ d[n++] = tmp;
+ ln++;
+ } else if (v == B64_ERROR) {
+ rv = -1;
+ goto end;
+ }
+
+ /* have we seen a '=' which is 'definitly' the last
+ * input line. seof will point to the character that
+ * holds it. and eof will hold how many characters to
+ * chop off. */
+ if (tmp == '=') {
+ if (seof == -1) {
+ seof = n;
+ }
+ eof++;
+ }
+
+ if (v == B64_CR) {
+ ln = 0;
+ if (exp_nl) {
+ continue;
+ }
+ }
+
+ /* eoln */
+ if (v == B64_EOLN) {
+ ln = 0;
+ if (exp_nl) {
+ exp_nl = 0;
+ continue;
+ }
+ }
+ exp_nl = 0;
+
+ /* If we are at the end of input and it looks like a
+ * line, process it. */
+ if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
+ v = B64_EOF;
+ /* In case things were given us in really small
+ records (so two '=' were given in separate
+ updates), eof may contain the incorrect number
+ of ending bytes to skip, so let's redo the count */
+ eof = 0;
+ if (d[n - 1] == '=') {
+ eof++;
+ }
+ if (d[n - 2] == '=') {
+ eof++;
+ }
+ /* There will never be more than two '=' */
+ }
+
+ if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
+ /* This is needed to work correctly on 64 byte input
+ * lines. We process the line and then need to
+ * accept the '\n' */
+ if (v != B64_EOF && n >= 64) {
+ exp_nl = 1;
+ }
+ if (n > 0) {
+ v = EVP_DecodeBlock(out, d, n);
+ n = 0;
+ if (v < 0) {
+ rv = 0;
+ goto end;
+ }
+ ret += (v - eof);
+ } else {
+ eof = 1;
+ v = 0;
+ }
+
+ /* This is the case where we have had a short
+ * but valid input line */
+ if (v < (int)ctx->length && eof) {
+ rv = 0;
+ goto end;
+ } else {
+ ctx->length = v;
+ }
+
+ if (seof >= 0) {
+ rv = 0;
+ goto end;
+ }
+ out += v;
+ }
+ }
+ rv = 1;
+
+end:
+ *out_len = ret;
+ ctx->num = n;
+ ctx->line_num = ln;
+ ctx->expect_nl = exp_nl;
+ return rv;
+}
+
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
+ int i;
+
+ *outl = 0;
+ if (ctx->num != 0) {
+ i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
+ if (i < 0) {
+ return -1;
+ }
+ ctx->num = 0;
+ *outl = i;
+ return 1;
+ } else {
+ return 1;
+ }
+}
+
+size_t EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
+ int a, b, c, d;
+ unsigned long l;
+ size_t i, ret = 0;
+
+ /* trim white space from the start of the line. */
+ while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
+ src++;
+ src_len--;
+ }
+
+ /* strip off stuff at the end of the line
+ * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
+ while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
+ src_len--;
+ }
+
+ if (src_len % 4 != 0) {
+ return -1;
+ }
+
+ for (i = 0; i < src_len; i += 4) {
+ a = conv_ascii2bin(*(src++));
+ b = conv_ascii2bin(*(src++));
+ c = conv_ascii2bin(*(src++));
+ d = conv_ascii2bin(*(src++));
+ if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
+ return -1;
+ }
+ l = ((((unsigned long)a) << 18L) | (((unsigned long)b) << 12L) |
+ (((unsigned long)c) << 6L) | (((unsigned long)d)));
+ *(dst++) = (uint8_t)(l >> 16L) & 0xff;
+ *(dst++) = (uint8_t)(l >> 8L) & 0xff;
+ *(dst++) = (uint8_t)(l) & 0xff;
+ ret += 3;
+ }
+
+ return ret;
+}
diff --git a/crypto/base64/base64.h b/crypto/base64/base64.h
new file mode 100644
index 0000000..afafaef
--- /dev/null
+++ b/crypto/base64/base64.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#ifndef OPENSSL_HEADER_BASE64_H
+#define OPENSSL_HEADER_BASE64_H
+
+#include <openssl/base.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* base64 functions.
+ *
+ * For historical reasons, these functions have the EVP_ prefix but just do
+ * base64 encoding and decoding. */
+
+
+typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
+
+
+/* Encoding */
+
+/* EVP_EncodeInit initialises |*ctx|, which is typically stack allocated, for
+ * an encoding operation. */
+void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+
+/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
+ * version of them to |out| and sets |*out_len| to the number of bytes written.
+ * Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
+ * flush it before using the encoded data. */
+void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
+ const uint8_t *in, size_t in_len);
+
+/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
+ * sets |*out_len| to the number of bytes written. */
+void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len);
+
+/* EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the result to
+ * |dst|. It returns the number of bytes written. */
+size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
+
+
+/* Decoding */
+
+/* EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for
+ * a decoding operation. */
+void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+
+/* EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded
+ * data to |out| and sets |*out_len| to the number of bytes written. Some state
+ * may be contained in |ctx| so |EVP_DecodeFinal| must be used to flush it
+ * before using the encoded data.
+ *
+ * It returns -1 on error, one if a full line of input was processed and zero
+ * if the line was short (i.e. it was the last line). */
+int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
+ const uint8_t *in, size_t in_len);
+
+/* EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and
+ * sets |*out_len| to the number of bytes written. It returns one on success
+ * and minus one on error. */
+int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len);
+
+/* EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to
+ * |dst|. It returns the number of bytes written. */
+size_t EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len);
+
+
+struct evp_encode_ctx_st {
+ unsigned num; /* number saved in a partial encode/decode */
+ unsigned length; /* The length is either the output line length
+ * (in input bytes) or the shortest input line
+ * length that is ok. Once decoding begins,
+ * the length is adjusted up each time a longer
+ * line is decoded */
+ uint8_t enc_data[80]; /* data to encode */
+ unsigned line_num; /* number read on current line */
+ int expect_nl;
+};
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_BASE64_H */