Path: blob/master/libs/tomcrypt/src/misc/base64/base64_decode.c
5972 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file base64_decode.c12Compliant base64 code donated by Wayne Scott ([email protected])13base64 URL Safe variant (RFC 4648 section 5) by Karel Miko14*/151617#if defined(LTC_BASE64) || defined (LTC_BASE64_URL)1819#if defined(LTC_BASE64)20static const unsigned char map_base64[256] = {21255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,22255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,23255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,24255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,2552, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,26255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,277, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,2819, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,29255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,3037, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,3149, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,32255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,33255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,34255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,35255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,36255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,37255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,38255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,39255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,40255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,41255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,42255, 255, 255, 255 };43#endif /* LTC_BASE64 */4445static const unsigned char map_base64url[] = {46#if defined(LTC_BASE64_URL)47255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,48255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,49255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,50255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,5152, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,52255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,537, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,5419, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63,55255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,5637, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,5749, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,58255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,59255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,60255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,61255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,62255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,63255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,64255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,65255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,66255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,67255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,68255, 255, 255, 25569#endif /* LTC_BASE64_URL */70};7172enum {73relaxed = 0,74strict = 175};7677static int _base64_decode_internal(const unsigned char *in, unsigned long inlen,78unsigned char *out, unsigned long *outlen,79const unsigned char *map, int is_strict)80{81unsigned long t, x, y, z;82unsigned char c;83int g;8485LTC_ARGCHK(in != NULL);86LTC_ARGCHK(out != NULL);87LTC_ARGCHK(outlen != NULL);8889g = 0; /* '=' counter */90for (x = y = z = t = 0; x < inlen; x++) {91c = map[in[x]&0xFF];92if (c == 254) {93g++;94continue;95}96else if (is_strict && g > 0) {97/* we only allow '=' to be at the end */98return CRYPT_INVALID_PACKET;99}100if (c == 255) {101if (is_strict)102return CRYPT_INVALID_PACKET;103else104continue;105}106107t = (t<<6)|c;108109if (++y == 4) {110if (z + 3 > *outlen) return CRYPT_BUFFER_OVERFLOW;111out[z++] = (unsigned char)((t>>16)&255);112out[z++] = (unsigned char)((t>>8)&255);113out[z++] = (unsigned char)(t&255);114y = t = 0;115}116}117118if (y != 0) {119if (y == 1) return CRYPT_INVALID_PACKET;120if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET;121t = t << (6 * (4 - y));122if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW;123if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255);124if (y == 3) out[z++] = (unsigned char) ((t >> 8) & 255);125}126*outlen = z;127return CRYPT_OK;128}129130#if defined(LTC_BASE64)131/**132Relaxed base64 decode a block of memory133@param in The base64 data to decode134@param inlen The length of the base64 data135@param out [out] The destination of the binary decoded data136@param outlen [in/out] The max size and resulting size of the decoded data137@return CRYPT_OK if successful138*/139int base64_decode(const unsigned char *in, unsigned long inlen,140unsigned char *out, unsigned long *outlen)141{142return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed);143}144145/**146Strict base64 decode a block of memory147@param in The base64 data to decode148@param inlen The length of the base64 data149@param out [out] The destination of the binary decoded data150@param outlen [in/out] The max size and resulting size of the decoded data151@return CRYPT_OK if successful152*/153int base64_strict_decode(const unsigned char *in, unsigned long inlen,154unsigned char *out, unsigned long *outlen)155{156return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict);157}158#endif /* LTC_BASE64 */159160#if defined(LTC_BASE64_URL)161/**162Relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory163@param in The base64 data to decode164@param inlen The length of the base64 data165@param out [out] The destination of the binary decoded data166@param outlen [in/out] The max size and resulting size of the decoded data167@return CRYPT_OK if successful168*/169int base64url_decode(const unsigned char *in, unsigned long inlen,170unsigned char *out, unsigned long *outlen)171{172return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed);173}174175/**176Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory177@param in The base64 data to decode178@param inlen The length of the base64 data179@param out [out] The destination of the binary decoded data180@param outlen [in/out] The max size and resulting size of the decoded data181@return CRYPT_OK if successful182*/183int base64url_strict_decode(const unsigned char *in, unsigned long inlen,184unsigned char *out, unsigned long *outlen)185{186return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict);187}188#endif /* LTC_BASE64_URL */189190#endif191192193