Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file base64.c
Sergunb 0:8918a71cdbe9 3 * @brief Base64 encoding scheme
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneCrypto Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @section Description
Sergunb 0:8918a71cdbe9 26 *
Sergunb 0:8918a71cdbe9 27 * Base64 is a encoding scheme that represents binary data in an ASCII string
Sergunb 0:8918a71cdbe9 28 * format by translating it into a radix-64 representation. Refer to RFC 4648
Sergunb 0:8918a71cdbe9 29 * for more details
Sergunb 0:8918a71cdbe9 30 *
Sergunb 0:8918a71cdbe9 31 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 32 * @version 1.7.6
Sergunb 0:8918a71cdbe9 33 **/
Sergunb 0:8918a71cdbe9 34
Sergunb 0:8918a71cdbe9 35 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 36 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 37
Sergunb 0:8918a71cdbe9 38 //Dependencies
Sergunb 0:8918a71cdbe9 39 #include "crypto.h"
Sergunb 0:8918a71cdbe9 40 #include "base64.h"
Sergunb 0:8918a71cdbe9 41
Sergunb 0:8918a71cdbe9 42 //Check crypto library configuration
Sergunb 0:8918a71cdbe9 43 #if (BASE64_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 44
Sergunb 0:8918a71cdbe9 45 //Base64 encoding table
Sergunb 0:8918a71cdbe9 46 static const char_t base64EncTable[64] =
Sergunb 0:8918a71cdbe9 47 {
Sergunb 0:8918a71cdbe9 48 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
Sergunb 0:8918a71cdbe9 49 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
Sergunb 0:8918a71cdbe9 50 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
Sergunb 0:8918a71cdbe9 51 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
Sergunb 0:8918a71cdbe9 52 };
Sergunb 0:8918a71cdbe9 53
Sergunb 0:8918a71cdbe9 54 //Base64 decoding table
Sergunb 0:8918a71cdbe9 55 static const uint8_t base64DecTable[128] =
Sergunb 0:8918a71cdbe9 56 {
Sergunb 0:8918a71cdbe9 57 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Sergunb 0:8918a71cdbe9 58 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Sergunb 0:8918a71cdbe9 59 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
Sergunb 0:8918a71cdbe9 60 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Sergunb 0:8918a71cdbe9 61 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
Sergunb 0:8918a71cdbe9 62 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
Sergunb 0:8918a71cdbe9 63 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
Sergunb 0:8918a71cdbe9 64 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
Sergunb 0:8918a71cdbe9 65 };
Sergunb 0:8918a71cdbe9 66
Sergunb 0:8918a71cdbe9 67
Sergunb 0:8918a71cdbe9 68 /**
Sergunb 0:8918a71cdbe9 69 * @brief Base64 encoding algorithm
Sergunb 0:8918a71cdbe9 70 * @param[in] input Input data to encode
Sergunb 0:8918a71cdbe9 71 * @param[in] inputLength Length of the data to encode
Sergunb 0:8918a71cdbe9 72 * @param[out] output NULL-terminated string encoded with Base64 algorithm
Sergunb 0:8918a71cdbe9 73 * @param[out] outputLength Length of the encoded string (optional parameter)
Sergunb 0:8918a71cdbe9 74 **/
Sergunb 0:8918a71cdbe9 75
Sergunb 0:8918a71cdbe9 76 void base64Encode(const void *input, size_t inputLength, char_t *output, size_t *outputLength)
Sergunb 0:8918a71cdbe9 77 {
Sergunb 0:8918a71cdbe9 78 size_t i;
Sergunb 0:8918a71cdbe9 79 const uint8_t *p;
Sergunb 0:8918a71cdbe9 80
Sergunb 0:8918a71cdbe9 81 //Point to the first byte of the input stream
Sergunb 0:8918a71cdbe9 82 p = input;
Sergunb 0:8918a71cdbe9 83 //Length of the encoded string
Sergunb 0:8918a71cdbe9 84 i = 0;
Sergunb 0:8918a71cdbe9 85
Sergunb 0:8918a71cdbe9 86 //Divide the input stream into blocks of 3 bytes
Sergunb 0:8918a71cdbe9 87 while(inputLength >= 3)
Sergunb 0:8918a71cdbe9 88 {
Sergunb 0:8918a71cdbe9 89 //Map each 3-byte block to 4 printable characters using the Base64 character set
Sergunb 0:8918a71cdbe9 90 output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
Sergunb 0:8918a71cdbe9 91 output[i++] = base64EncTable[((p[0] & 0x03) << 4) | ((p[1] & 0xF0) >> 4)];
Sergunb 0:8918a71cdbe9 92 output[i++] = base64EncTable[((p[1] & 0x0F) << 2) | ((p[2] & 0xC0) >> 6)];
Sergunb 0:8918a71cdbe9 93 output[i++] = base64EncTable[p[2] & 0x3F];
Sergunb 0:8918a71cdbe9 94 //Point to the next 3-byte block
Sergunb 0:8918a71cdbe9 95 p += 3;
Sergunb 0:8918a71cdbe9 96 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 97 inputLength -= 3;
Sergunb 0:8918a71cdbe9 98 }
Sergunb 0:8918a71cdbe9 99
Sergunb 0:8918a71cdbe9 100 //The last block contains only 1 byte?
Sergunb 0:8918a71cdbe9 101 if(inputLength == 1)
Sergunb 0:8918a71cdbe9 102 {
Sergunb 0:8918a71cdbe9 103 output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
Sergunb 0:8918a71cdbe9 104 output[i++] = base64EncTable[(p[0] & 0x03) << 4];
Sergunb 0:8918a71cdbe9 105 output[i++] = '=';
Sergunb 0:8918a71cdbe9 106 output[i++] = '=';
Sergunb 0:8918a71cdbe9 107 }
Sergunb 0:8918a71cdbe9 108 //The last block contains only 2 bytes?
Sergunb 0:8918a71cdbe9 109 else if(inputLength == 2)
Sergunb 0:8918a71cdbe9 110 {
Sergunb 0:8918a71cdbe9 111 output[i++] = base64EncTable[(p[0] & 0xFC) >> 2];
Sergunb 0:8918a71cdbe9 112 output[i++] = base64EncTable[((p[0] & 0x03) << 4) | ((p[1] & 0xF0) >> 4)];
Sergunb 0:8918a71cdbe9 113 output[i++] = base64EncTable[(p[1] & 0x0F) << 2];
Sergunb 0:8918a71cdbe9 114 output[i++] = '=';
Sergunb 0:8918a71cdbe9 115 }
Sergunb 0:8918a71cdbe9 116
Sergunb 0:8918a71cdbe9 117 //Properly terminate the resulting string
Sergunb 0:8918a71cdbe9 118 output[i] = '\0';
Sergunb 0:8918a71cdbe9 119
Sergunb 0:8918a71cdbe9 120 //Return the length of the encoded string (excluding the terminating NULL)
Sergunb 0:8918a71cdbe9 121 if(outputLength != NULL)
Sergunb 0:8918a71cdbe9 122 *outputLength = i;
Sergunb 0:8918a71cdbe9 123 }
Sergunb 0:8918a71cdbe9 124
Sergunb 0:8918a71cdbe9 125
Sergunb 0:8918a71cdbe9 126 /**
Sergunb 0:8918a71cdbe9 127 * @brief Base64 decoding algorithm
Sergunb 0:8918a71cdbe9 128 * @param[in] input Base64 encoded string
Sergunb 0:8918a71cdbe9 129 * @param[in] inputLength Length of the encoded string
Sergunb 0:8918a71cdbe9 130 * @param[out] output Resulting decoded data
Sergunb 0:8918a71cdbe9 131 * @param[out] outputLength Length of the decoded data
Sergunb 0:8918a71cdbe9 132 * @return Error code
Sergunb 0:8918a71cdbe9 133 **/
Sergunb 0:8918a71cdbe9 134
Sergunb 0:8918a71cdbe9 135 error_t base64Decode(const char_t *input, size_t inputLength, void *output, size_t *outputLength)
Sergunb 0:8918a71cdbe9 136 {
Sergunb 0:8918a71cdbe9 137 size_t i;
Sergunb 0:8918a71cdbe9 138 size_t j;
Sergunb 0:8918a71cdbe9 139 uint32_t value;
Sergunb 0:8918a71cdbe9 140 uint8_t *p;
Sergunb 0:8918a71cdbe9 141
Sergunb 0:8918a71cdbe9 142 //Point to the first byte of the output stream
Sergunb 0:8918a71cdbe9 143 p = output;
Sergunb 0:8918a71cdbe9 144 //Length of the decoded stream
Sergunb 0:8918a71cdbe9 145 i = 0;
Sergunb 0:8918a71cdbe9 146
Sergunb 0:8918a71cdbe9 147 //The length of the string to decode must be a multiple of 4
Sergunb 0:8918a71cdbe9 148 if(inputLength % 4)
Sergunb 0:8918a71cdbe9 149 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 150
Sergunb 0:8918a71cdbe9 151 //Process the Base64 encoded string
Sergunb 0:8918a71cdbe9 152 while(inputLength >= 4)
Sergunb 0:8918a71cdbe9 153 {
Sergunb 0:8918a71cdbe9 154 //Divide the input stream into blocks of 4 characters
Sergunb 0:8918a71cdbe9 155 for(value = 0, j = 0; j < 4; j++)
Sergunb 0:8918a71cdbe9 156 {
Sergunb 0:8918a71cdbe9 157 //The "==" sequence indicates that the last block contains only 1 byte
Sergunb 0:8918a71cdbe9 158 if(inputLength == 2 && input[0] == '=' && input[1] == '=')
Sergunb 0:8918a71cdbe9 159 {
Sergunb 0:8918a71cdbe9 160 //Decode the last byte
Sergunb 0:8918a71cdbe9 161 p[i++] = (value >> 4) & 0xFF;
Sergunb 0:8918a71cdbe9 162 //Return the length of the decoded data
Sergunb 0:8918a71cdbe9 163 *outputLength = i;
Sergunb 0:8918a71cdbe9 164 //Decoding is now complete
Sergunb 0:8918a71cdbe9 165 return NO_ERROR;
Sergunb 0:8918a71cdbe9 166 }
Sergunb 0:8918a71cdbe9 167 //The "=" sequence indicates that the last block contains only 2 bytes
Sergunb 0:8918a71cdbe9 168 else if(inputLength == 1 && *input == '=')
Sergunb 0:8918a71cdbe9 169 {
Sergunb 0:8918a71cdbe9 170 //Decode the last two bytes
Sergunb 0:8918a71cdbe9 171 p[i++] = (value >> 10) & 0xFF;
Sergunb 0:8918a71cdbe9 172 p[i++] = (value >> 2) & 0xFF;
Sergunb 0:8918a71cdbe9 173 //Return the length of the decoded data
Sergunb 0:8918a71cdbe9 174 *outputLength = i;
Sergunb 0:8918a71cdbe9 175 //Decoding is now complete
Sergunb 0:8918a71cdbe9 176 return NO_ERROR;
Sergunb 0:8918a71cdbe9 177 }
Sergunb 0:8918a71cdbe9 178 //Ensure the current character belongs to the Base64 character set
Sergunb 0:8918a71cdbe9 179 else if(((uint8_t) *input) > 127 || base64DecTable[(uint8_t) *input] > 63)
Sergunb 0:8918a71cdbe9 180 {
Sergunb 0:8918a71cdbe9 181 //Decoding failed
Sergunb 0:8918a71cdbe9 182 return ERROR_INVALID_CHARACTER;
Sergunb 0:8918a71cdbe9 183 }
Sergunb 0:8918a71cdbe9 184
Sergunb 0:8918a71cdbe9 185 //Decode the current character
Sergunb 0:8918a71cdbe9 186 value = (value << 6) | base64DecTable[(uint8_t) *input];
Sergunb 0:8918a71cdbe9 187 //Point to the next character to decode
Sergunb 0:8918a71cdbe9 188 input++;
Sergunb 0:8918a71cdbe9 189 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 190 inputLength--;
Sergunb 0:8918a71cdbe9 191 }
Sergunb 0:8918a71cdbe9 192
Sergunb 0:8918a71cdbe9 193 //Map each 4-character block to 3 bytes
Sergunb 0:8918a71cdbe9 194 p[i++] = (value >> 16) & 0xFF;
Sergunb 0:8918a71cdbe9 195 p[i++] = (value >> 8) & 0xFF;
Sergunb 0:8918a71cdbe9 196 p[i++] = value & 0xFF;
Sergunb 0:8918a71cdbe9 197 }
Sergunb 0:8918a71cdbe9 198
Sergunb 0:8918a71cdbe9 199 //Return the length of the decoded data
Sergunb 0:8918a71cdbe9 200 *outputLength = i;
Sergunb 0:8918a71cdbe9 201 //Decoding is now complete
Sergunb 0:8918a71cdbe9 202 return NO_ERROR;
Sergunb 0:8918a71cdbe9 203 }
Sergunb 0:8918a71cdbe9 204
Sergunb 0:8918a71cdbe9 205 #endif
Sergunb 0:8918a71cdbe9 206