/*
 * RFC 1521 base64 encoding/decoding
 *
 * Copyright (C) 2018, Nordic Semiconductor ASA
 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Adapted for Zephyr by Carles Cufi (carles.cufi@nordicsemi.no)
 *  - Removed mbedtls_ prefixes
 *  - Reworked coding style
 */

#include <stdint.h>
#include <errno.h>
#include <sys/base64.h>

static const uint8_t base64_enc_map[64] = {
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
	'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
	'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
	'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
	'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
	'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
	'8', '9', '+', '/'
};

static const uint8_t base64_dec_map[128] = {
	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
	127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
	127, 127, 127,	62, 127, 127, 127,  63,  52,  53,
	 54,  55,  56,	57,  58,  59,  60,  61, 127, 127,
	127,  64, 127, 127, 127,   0,	1,   2,   3,   4,
	  5,   6,   7,	 8,   9,  10,  11,  12,  13,  14,
	 15,  16,  17,	18,  19,  20,  21,  22,  23,  24,
	 25, 127, 127, 127, 127, 127, 127,  26,  27,  28,
	 29,  30,  31,	32,  33,  34,  35,  36,  37,  38,
	 39,  40,  41,	42,  43,  44,  45,  46,  47,  48,
	 49,  50,  51, 127, 127, 127, 127, 127
};

#define BASE64_SIZE_T_MAX	((size_t) -1) /* SIZE_T_MAX is not standard */

/*
 * Encode a buffer into base64 format
 */
int base64_encode(uint8_t *dst, size_t dlen, size_t *olen, const uint8_t *src,
		  size_t slen)
{
	size_t i, n;
	int C1, C2, C3;
	uint8_t *p;

	if (slen == 0) {
		*olen = 0;
		return 0;
	}

	n = slen / 3 + (slen % 3 != 0);

	if (n > (BASE64_SIZE_T_MAX - 1) / 4) {
		*olen = BASE64_SIZE_T_MAX;
		return -ENOMEM;
	}

	n *= 4;

	if ((dlen < n + 1) || (!dst)) {
		*olen = n + 1;
		return -ENOMEM;
	}

	n = (slen / 3) * 3;

	for (i = 0, p = dst; i < n; i += 3) {
		C1 = *src++;
		C2 = *src++;
		C3 = *src++;

		*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
		*p++ = base64_enc_map[(((C1 &  3) << 4) + (C2 >> 4)) & 0x3F];
		*p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
		*p++ = base64_enc_map[C3 & 0x3F];
	}

	if (i < slen) {
		C1 = *src++;
		C2 = ((i + 1) < slen) ? *src++ : 0;

		*p++ = base64_enc_map[(C1 >> 2) & 0x3F];
		*p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];

		if ((i + 1) < slen) {
			*p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
		} else {
			*p++ = '=';
		}

		*p++ = '=';
	}

	*olen = p - dst;
	*p = 0U;

	return 0;
}

/*
 * Decode a base64-formatted buffer
 */
int base64_decode(uint8_t *dst, size_t dlen, size_t *olen, const uint8_t *src,
		  size_t slen)
{
	size_t i, n;
	uint32_t j, x;
	uint8_t *p;

	/* First pass: check for validity and get output length */
	for (i = n = j = 0U; i < slen; i++) {
		/* Skip spaces before checking for EOL */
		x = 0U;
		while (i < slen && src[i] == ' ') {
			++i;
			++x;
		}

		/* Spaces at end of buffer are OK */
		if (i == slen) {
			break;
		}

		if ((slen - i) >= 2 && src[i] == '\r' && src[i + 1] == '\n') {
			continue;
		}

		if (src[i] == '\n') {
			continue;
		}

		/* Space inside a line is an error */
		if (x != 0U) {
			return -EINVAL;
		}

		if (src[i] == '=' && ++j > 2) {
			return -EINVAL;
		}

		if (src[i] > 127 || base64_dec_map[src[i]] == 127U) {
			return -EINVAL;
		}

		if (base64_dec_map[src[i]] < 64 && j != 0U) {
			return -EINVAL;
		}

		n++;
	}

	if (n == 0) {
		*olen = 0;
		return 0;
	}

	/* The following expression is to calculate the following formula
	 * without risk of integer overflow in n:
	 *	   n = ( ( n * 6 ) + 7 ) >> 3;
	 */
	n = (6 * (n >> 3)) + ((6 * (n & 0x7) + 7) >> 3);
	n -= j;

	if (dst == NULL || dlen < n) {
		*olen = n;
		return -ENOMEM;
	}

	for (j = 3U, n = x = 0U, p = dst; i > 0; i--, src++) {

		if (*src == '\r' || *src == '\n' || *src == ' ') {
			continue;
		}

		j -= (base64_dec_map[*src] == 64U);
		x  = (x << 6) | (base64_dec_map[*src] & 0x3F);

		if (++n == 4) {
			n = 0;
			if (j > 0) {
				*p++ = (unsigned char)(x >> 16);
			}
			if (j > 1) {
				*p++ = (unsigned char)(x >> 8);
			}
			if (j > 2) {
				*p++ = (unsigned char)(x);
			}
		}
	}

	*olen = p - dst;

	return 0;
}
