Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 17:10:12 by
