Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers base64.c Source File

base64.c

Go to the documentation of this file.
00001 /**
00002  * @file base64.c
00003  * @brief Base64 encoding scheme
00004  *
00005  * @section License
00006  *
00007  * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
00008  *
00009  * This file is part of CycloneCrypto Open.
00010  *
00011  * This program is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU General Public License
00013  * as published by the Free Software Foundation; either version 2
00014  * of the License, or (at your option) any later version.
00015  *
00016  * This program is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  * GNU General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU General Public License
00022  * along with this program; if not, write to the Free Software Foundation,
00023  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024  *
00025  * @section Description
00026  *
00027  * Base64 is a encoding scheme that represents binary data in an ASCII string
00028  * format by translating it into a radix-64 representation. Refer to RFC 4648
00029  * for more details
00030  *
00031  * @author Oryx Embedded SARL (www.oryx-embedded.com)
00032  * @version 1.7.6
00033  **/
00034 
00035 //Switch to the appropriate trace level
00036 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
00037 
00038 //Dependencies
00039 #include "crypto.h"
00040 #include "base64.h"
00041 
00042 //Check crypto library configuration
00043 #if (BASE64_SUPPORT == ENABLED)
00044 
00045 //Base64 encoding table
00046 static const char_t base64EncTable[64] =
00047 {
00048    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
00049    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
00050    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
00051    'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
00052 };
00053 
00054 //Base64 decoding table
00055 static const uint8_t base64DecTable[128] =
00056 {
00057    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00058    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00059    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
00060    0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00061    0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
00062    0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
00063    0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
00064    0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
00065 };
00066 
00067 
00068 /**
00069  * @brief Base64 encoding algorithm
00070  * @param[in] input Input data to encode
00071  * @param[in] inputLength Length of the data to encode
00072  * @param[out] output NULL-terminated string encoded with Base64 algorithm
00073  * @param[out] outputLength Length of the encoded string (optional parameter)
00074  **/
00075 
00076 void base64Encode(const void *input, size_t inputLength, char_t *output, size_t *outputLength)
00077 {
00078    size_t i;
00079    const uint8_t *p;
00080 
00081    //Point to the first byte of the input stream
00082    p = input;
00083    //Length of the encoded string
00084    i = 0;
00085 
00086    //Divide the input stream into blocks of 3 bytes
00087    while(inputLength >= 3)
00088    {
00089       //Map each 3-byte block to 4 printable characters using the Base64 character set
00090       output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
00091       output[i++] = base64EncTable[((p[0] & 0x03) << 4) | ((p[1] & 0xF0) >> 4)];
00092       output[i++] = base64EncTable[((p[1] & 0x0F) << 2) | ((p[2] & 0xC0) >> 6)];
00093       output[i++] = base64EncTable[p[2] & 0x3F];
00094       //Point to the next 3-byte block
00095       p += 3;
00096       //Remaining bytes to process
00097       inputLength -= 3;
00098    }
00099 
00100    //The last block contains only 1 byte?
00101    if(inputLength == 1)
00102    {
00103       output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
00104       output[i++] = base64EncTable[(p[0] & 0x03) << 4];
00105       output[i++] = '=';
00106       output[i++] = '=';
00107    }
00108    //The last block contains only 2 bytes?
00109    else if(inputLength == 2)
00110    {
00111       output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
00112       output[i++] = base64EncTable[((p[0] & 0x03) << 4) | ((p[1] & 0xF0) >> 4)];
00113       output[i++] = base64EncTable[(p[1] & 0x0F) << 2];
00114       output[i++] = '=';
00115    }
00116 
00117    //Properly terminate the resulting string
00118    output[i] = '\0';
00119 
00120    //Return the length of the encoded string (excluding the terminating NULL)
00121    if(outputLength != NULL)
00122       *outputLength = i;
00123 }
00124 
00125 
00126 /**
00127  * @brief Base64 decoding algorithm
00128  * @param[in] input Base64 encoded string
00129  * @param[in] inputLength Length of the encoded string
00130  * @param[out] output Resulting decoded data
00131  * @param[out] outputLength Length of the decoded data
00132  * @return Error code
00133  **/
00134 
00135 error_t base64Decode(const char_t *input, size_t inputLength, void *output, size_t *outputLength)
00136 {
00137    size_t i;
00138    size_t j;
00139    uint32_t value;
00140    uint8_t *p;
00141 
00142    //Point to the first byte of the output stream
00143    p = output;
00144    //Length of the decoded stream
00145    i = 0;
00146 
00147    //The length of the string to decode must be a multiple of 4
00148    if(inputLength % 4)
00149       return ERROR_INVALID_LENGTH;
00150 
00151    //Process the Base64 encoded string
00152    while(inputLength >= 4)
00153    {
00154       //Divide the input stream into blocks of 4 characters
00155       for(value = 0, j = 0; j < 4; j++)
00156       {
00157          //The "==" sequence indicates that the last block contains only 1 byte
00158          if(inputLength == 2 && input[0] == '=' && input[1] == '=')
00159          {
00160             //Decode the last byte
00161             p[i++] = (value >> 4) & 0xFF;
00162             //Return the length of the decoded data
00163             *outputLength = i;
00164             //Decoding is now complete
00165             return NO_ERROR;
00166          }
00167          //The "=" sequence indicates that the last block contains only 2 bytes
00168          else if(inputLength == 1 && *input == '=')
00169          {
00170             //Decode the last two bytes
00171             p[i++] = (value >> 10) & 0xFF;
00172             p[i++] = (value >> 2) & 0xFF;
00173             //Return the length of the decoded data
00174             *outputLength = i;
00175             //Decoding is now complete
00176             return NO_ERROR;
00177          }
00178          //Ensure the current character belongs to the Base64 character set
00179          else if(((uint8_t) *input) > 127 || base64DecTable[(uint8_t) *input] > 63)
00180          {
00181             //Decoding failed
00182             return ERROR_INVALID_CHARACTER;
00183          }
00184 
00185          //Decode the current character
00186          value = (value << 6) | base64DecTable[(uint8_t) *input];
00187          //Point to the next character to decode
00188          input++;
00189          //Remaining bytes to process
00190          inputLength--;
00191       }
00192 
00193       //Map each 4-character block to 3 bytes
00194       p[i++] = (value >> 16) & 0xFF;
00195       p[i++] = (value >> 8) & 0xFF;
00196       p[i++] = value  & 0xFF;
00197    }
00198 
00199    //Return the length of the decoded data
00200    *outputLength = i;
00201    //Decoding is now complete
00202    return NO_ERROR;
00203 }
00204 
00205 #endif
00206