195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved. 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com). 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL. 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to. The following conditions 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA, 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com). 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed. 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used. 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package. 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met: 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer. 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * notice, this list of conditions and the following disclaimer in the 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * documentation and/or other materials provided with the distribution. 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * must display the following acknowledgement: 3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes cryptographic software written by 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Eric Young (eay@cryptsoft.com)" 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The word 'cryptographic' can be left out if the rouines from the library 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * being used are not cryptographic related :-). 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the apps directory (application code) you must include an acknowledgement: 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE. 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed. i.e. this code cannot simply be 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */ 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/base64.h> 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <assert.h> 60ded93581f1674f81faa0dba4b15a842756066ab2Adam Langley#include <limits.h> 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const unsigned char data_bin2ascii[65] = 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f]) 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* 64 char lines 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * pad input with 0 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * left over chars are set to = 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1 byte => xx== 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2 bytes => xxx= 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3 bytes => xxxx 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley */ 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define BIN_PER_LINE (64/4*3) 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define CHUNKS_PER_LINE (64/4) 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define CHAR_PER_LINE (64+1) 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* 0xF0 is a EOLN 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0xF2 is EOF 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0xE0 is ignore at start of line. 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 0xFF is error */ 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_EOLN 0xF0 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_CR 0xF1 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_EOF 0xF2 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_WS 0xE0 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_ERROR 0xFF 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3) 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 92d698f322b58a50ee1acf21a734367d151c154dd1David Benjaminstatic const uint8_t data_ascii2bin[128] = { 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF, 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF, 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 98d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 106d698f322b58a50ee1acf21a734367d151c154dd1David Benjaminstatic uint8_t conv_ascii2bin(uint8_t a) { 107d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (a >= 128) { 108d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 0xFF; 109d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 110d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return data_ascii2bin[a]; 111d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin} 112d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->length = 48; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->line_num = 0; 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, size_t in_len) { 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned i, j; 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned total = 0; 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = 0; 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len == 0) { 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(ctx->length <= sizeof(ctx->enc_data)); 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1318750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley if (ctx->num + in_len < ctx->length) { 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(&ctx->enc_data[ctx->num], in, in_len); 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num += in_len; 13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->num != 0) { 13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = ctx->length - ctx->num; 13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(&ctx->enc_data[ctx->num], in, i); 13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in += i; 14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in_len -= i; 14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); 14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += j; 14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(out++) = '\n'; 14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = '\0'; 14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley total = j + 1; 14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (in_len >= ctx->length) { 14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley j = EVP_EncodeBlock(out, in, ctx->length); 15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in += ctx->length; 15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley in_len -= ctx->length; 15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += j; 15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(out++) = '\n'; 15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out = '\0'; 15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley total += j + 1; 15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len != 0) { 15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(&ctx->enc_data[0], in, in_len); 15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = in_len; 16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = total; 16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { 16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned ret = 0; 16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->num != 0) { 16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); 16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out[ret++] = '\n'; 17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out[ret] = '\0'; 17195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = ret; 17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleysize_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { 1778750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley uint32_t l; 1788750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley size_t remaining = src_len, ret = 0; 17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1808750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley while (remaining) { 1818750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley if (remaining >= 3) { 1828750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2]; 18395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l >> 18L); 18495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l >> 12L); 18595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l >> 6L); 18695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l); 1878750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley remaining -= 3; 18895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 1898750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley l = ((uint32_t)src[0]) << 16L; 1908750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley if (remaining == 2) { 1918750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley l |= ((uint32_t)src[1] << 8L); 19295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 19395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 19495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l >> 18L); 19595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = conv_bin2ascii(l >> 12L); 1968750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L); 19795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *(dst++) = '='; 1988750fe58f4bd74a3dd1aeba47ace94907d0a7de5Adam Langley remaining = 0; 19995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret += 4; 20195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley src += 3; 20295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 20395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 20495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *dst = '\0'; 20595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return ret; 20695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 20795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 208d698f322b58a50ee1acf21a734367d151c154dd1David Benjaminint EVP_DecodedLength(size_t *out_len, size_t len) { 209d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (len % 4 != 0) { 210d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 0; 211d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 212d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin *out_len = (len / 4) * 3; 213d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 1; 214d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin} 215d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 216d698f322b58a50ee1acf21a734367d151c154dd1David Benjaminint EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out, 217d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin const uint8_t *in, size_t in_len) { 218d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin uint8_t a, b, c, d; 219d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin size_t pad_len = 0, len = 0, max_len, i; 220d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin uint32_t l; 221d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 222d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) { 223d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 0; 224d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 225d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 226d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin for (i = 0; i < in_len; i += 4) { 227d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin a = conv_ascii2bin(*(in++)); 228d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin b = conv_ascii2bin(*(in++)); 229d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (i + 4 == in_len && in[1] == '=') { 230d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (in[0] == '=') { 231d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin pad_len = 2; 232d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } else { 233d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin pad_len = 1; 234d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 235d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 236d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (pad_len < 2) { 237d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin c = conv_ascii2bin(*(in++)); 238d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } else { 239d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin c = 0; 240d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 241d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (pad_len < 1) { 242d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin d = conv_ascii2bin(*(in++)); 243d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } else { 244d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin d = 0; 245d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 246d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) { 247d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 0; 248d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 249d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) | 250d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin (((uint32_t)c) << 6L) | (((uint32_t)d))); 251d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin *(out++) = (uint8_t)(l >> 16L) & 0xff; 252d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (pad_len < 2) { 253d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin *(out++) = (uint8_t)(l >> 8L) & 0xff; 254d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 255d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (pad_len < 1) { 256d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin *(out++) = (uint8_t)(l) & 0xff; 257d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 258d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin len += 3 - pad_len; 259d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin } 260d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin *out_len = len; 261d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return 1; 262d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin} 263d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin 26495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid EVP_DecodeInit(EVP_ENCODE_CTX *ctx) { 26595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->length = 30; 26695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 26795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->line_num = 0; 26895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->expect_nl = 0; 26995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 27095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, 27295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley const uint8_t *in, size_t in_len) { 27395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl; 27495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley uint8_t *d; 27595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley unsigned i, n, ln, ret = 0; 27695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 27795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = ctx->num; 27895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley d = ctx->enc_data; 27995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ln = ctx->line_num; 28095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley exp_nl = ctx->expect_nl; 28195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* last line of input. */ 28395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) { 28495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = 0; 28595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 28695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 28795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 28895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* We parse the input data */ 28995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley for (i = 0; i < in_len; i++) { 29095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If the current line is > 80 characters, scream alot */ 29195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ln >= 80) { 29295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = -1; 29395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 29495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 29595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 29695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* Get char and put it into the buffer */ 29795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley tmp = *(in++); 29895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley v = conv_ascii2bin(tmp); 29995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* only save the good data :-) */ 30095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (!B64_NOT_BASE64(v)) { 30195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley assert(n < sizeof(ctx->enc_data)); 30295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley d[n++] = tmp; 30395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ln++; 30495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else if (v == B64_ERROR) { 30595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = -1; 30695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 30795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 30895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 30995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* have we seen a '=' which is 'definitly' the last 31095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * input line. seof will point to the character that 31195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * holds it. and eof will hold how many characters to 31295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * chop off. */ 31395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (tmp == '=') { 31495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (seof == -1) { 31595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley seof = n; 31695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 31795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eof++; 31864bda23cad8cb912a55328ee9a298ca4d9795477Adam Langley if (eof > 2) { 31964bda23cad8cb912a55328ee9a298ca4d9795477Adam Langley /* There are, at most, two equals signs at the end of base64 data. */ 32064bda23cad8cb912a55328ee9a298ca4d9795477Adam Langley rv = -1; 32164bda23cad8cb912a55328ee9a298ca4d9795477Adam Langley goto end; 32264bda23cad8cb912a55328ee9a298ca4d9795477Adam Langley } 32395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 32495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (v == B64_CR) { 32695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ln = 0; 32795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (exp_nl) { 32895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 32995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 33295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* eoln */ 33395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (v == B64_EOLN) { 33495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ln = 0; 33595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (exp_nl) { 33695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley exp_nl = 0; 33795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley continue; 33895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 33995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 34095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley exp_nl = 0; 34195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 34295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* If we are at the end of input and it looks like a 34395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * line, process it. */ 34495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((i + 1) == in_len && (((n & 3) == 0) || eof)) { 34595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley v = B64_EOF; 34695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* In case things were given us in really small 34795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley records (so two '=' were given in separate 34895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley updates), eof may contain the incorrect number 34995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley of ending bytes to skip, so let's redo the count */ 35095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eof = 0; 35195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (d[n - 1] == '=') { 35295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eof++; 35395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (d[n - 2] == '=') { 35595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eof++; 35695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* There will never be more than two '=' */ 35895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 35995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 36095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if ((v == B64_EOF && (n & 3) == 0) || n >= 64) { 36195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* This is needed to work correctly on 64 byte input 36295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lines. We process the line and then need to 36395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * accept the '\n' */ 36495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (v != B64_EOF && n >= 64) { 36595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley exp_nl = 1; 36695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 36795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (n > 0) { 368d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin /* TODO(davidben): Switch this to EVP_DecodeBase64. */ 36995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley v = EVP_DecodeBlock(out, d, n); 37095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley n = 0; 37195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (v < 0) { 37295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = 0; 37395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 37495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 37595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ret += (v - eof); 37695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 37795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley eof = 1; 37895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley v = 0; 37995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 38195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* This is the case where we have had a short 38295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * but valid input line */ 38395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (v < (int)ctx->length && eof) { 38495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = 0; 38595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 38695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 38795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->length = v; 38895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 38995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (seof >= 0) { 39195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = 0; 39295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley goto end; 39395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley out += v; 39595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 39795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley rv = 1; 39895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 39995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyend: 40095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_len = ret; 40195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = n; 40295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->line_num = ln; 40395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->expect_nl = exp_nl; 40495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return rv; 40595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 40695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 40795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) { 40895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley int i; 40995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 41095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *outl = 0; 41195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (ctx->num != 0) { 412d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin /* TODO(davidben): Switch this to EVP_DecodeBase64. */ 41395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); 41495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (i < 0) { 41595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 41695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 41795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ctx->num = 0; 41895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *outl = i; 41995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 42095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } else { 42195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 42295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 42395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 42495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 425ded93581f1674f81faa0dba4b15a842756066ab2Adam Langleyint EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { 426d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin size_t dst_len; 42795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 42895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* trim white space from the start of the line. */ 42995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (conv_ascii2bin(*src) == B64_WS && src_len > 0) { 43095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley src++; 43195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley src_len--; 43295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 43495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley /* strip off stuff at the end of the line 43595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */ 43695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) { 43795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley src_len--; 43895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 43995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 440d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) { 44195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return -1; 44295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 443d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) { 444d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return -1; 44595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 44695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 447d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin /* EVP_DecodeBlock does not take padding into account, so put the 448d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin * NULs back in... so the caller can strip them back out. */ 449d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin while (dst_len % 3 != 0) { 450d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin dst[dst_len++] = '\0'; 451ded93581f1674f81faa0dba4b15a842756066ab2Adam Langley } 452d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin assert(dst_len <= INT_MAX); 453ded93581f1674f81faa0dba4b15a842756066ab2Adam Langley 454d698f322b58a50ee1acf21a734367d151c154dd1David Benjamin return dst_len; 45595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 456660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley 457660140206ed32aa217ba3f299debae8d9ac472ecAdam Langleyint EVP_EncodedLength(size_t *out_len, size_t len) { 458660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley if (len + 2 < len) { 459660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley return 0; 460660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley } 461660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley len += 2; 462660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley len /= 3; 463660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley if (((len << 2) >> 2) != len) { 464660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley return 0; 465660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley } 466660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley len <<= 2; 467660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley if (len + 1 < len) { 468660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley return 0; 469660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley } 470660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley len++; 471660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley *out_len = len; 472660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley return 1; 473660140206ed32aa217ba3f299debae8d9ac472ecAdam Langley} 474