A simple CyaSSL-based HMAC-MD5 implementation. Licensed under GPL v2.
Dependents: RFrec_full RFtrans_full
coding.c
00001 /* coding.c 00002 * 00003 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include "coding.h" 00027 #include "error.h" 00028 //#include "logging.h" 00029 00030 00031 enum { 00032 BAD = 0xFF, /* invalid encoding */ 00033 PAD = '=', 00034 PEM_LINE_SZ = 64 00035 }; 00036 00037 00038 static 00039 const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 00040 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 00041 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00042 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00043 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 00044 20, 21, 22, 23, 24, 25, 00045 BAD, BAD, BAD, BAD, BAD, BAD, 00046 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 00047 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 00048 46, 47, 48, 49, 50, 51 00049 }; 00050 00051 00052 int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00053 { 00054 word32 i = 0; 00055 word32 j = 0; 00056 word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); 00057 const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1; 00058 00059 plainSz = (plainSz * 3 + 3) / 4; 00060 if (plainSz > *outLen) return BAD_FUNC_ARG; 00061 00062 while (inLen > 3) { 00063 byte b1, b2, b3; 00064 byte e1 = in[j++]; 00065 byte e2 = in[j++]; 00066 byte e3 = in[j++]; 00067 byte e4 = in[j++]; 00068 00069 int pad3 = 0; 00070 int pad4 = 0; 00071 00072 if (e1 == 0) /* end file 0's */ 00073 break; 00074 if (e3 == PAD) 00075 pad3 = 1; 00076 if (e4 == PAD) 00077 pad4 = 1; 00078 00079 if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) { 00080 // CYASSL_MSG("Bad Base64 Decode data, too small"); 00081 return ASN_INPUT_E; 00082 } 00083 00084 if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) { 00085 // CYASSL_MSG("Bad Base64 Decode data, too big"); 00086 return ASN_INPUT_E; 00087 } 00088 00089 e1 = base64Decode[e1 - 0x2B]; 00090 e2 = base64Decode[e2 - 0x2B]; 00091 e3 = (e3 == PAD) ? 0 : base64Decode[e3 - 0x2B]; 00092 e4 = (e4 == PAD) ? 0 : base64Decode[e4 - 0x2B]; 00093 00094 b1 = (e1 << 2) | (e2 >> 4); 00095 b2 = ((e2 & 0xF) << 4) | (e3 >> 2); 00096 b3 = ((e3 & 0x3) << 6) | e4; 00097 00098 out[i++] = b1; 00099 if (!pad3) 00100 out[i++] = b2; 00101 if (!pad4) 00102 out[i++] = b3; 00103 else 00104 break; 00105 00106 inLen -= 4; 00107 if (in[j] == ' ' || in[j] == '\r' || in[j] == '\n') { 00108 byte endLine = in[j++]; 00109 inLen--; 00110 while (endLine == ' ') { /* allow trailing whitespace */ 00111 endLine = in[j++]; 00112 inLen--; 00113 } 00114 if (endLine == '\r') { 00115 endLine = in[j++]; 00116 inLen--; 00117 } 00118 if (endLine != '\n') { 00119 // CYASSL_MSG("Bad end of line in Base64 Decode"); 00120 return ASN_INPUT_E; 00121 } 00122 } 00123 } 00124 *outLen = i; 00125 00126 return 0; 00127 } 00128 00129 00130 00131 static 00132 const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 00133 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 00134 'U', 'V', 'W', 'X', 'Y', 'Z', 00135 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 00136 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 00137 'u', 'v', 'w', 'x', 'y', 'z', 00138 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 00139 '+', '/' 00140 }; 00141 00142 00143 /* porting assistance from yaSSL by Raphael HUCK */ 00144 int Base64_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) 00145 { 00146 word32 i = 0, 00147 j = 0, 00148 n = 0; /* new line counter */ 00149 00150 word32 outSz = (inLen + 3 - 1) / 3 * 4; 00151 outSz += (outSz + PEM_LINE_SZ - 1) / PEM_LINE_SZ; /* new lines */ 00152 00153 if (outSz > *outLen) return BAD_FUNC_ARG; 00154 00155 while (inLen > 2) { 00156 byte b1 = in[j++]; 00157 byte b2 = in[j++]; 00158 byte b3 = in[j++]; 00159 00160 /* encoded idx */ 00161 byte e1 = b1 >> 2; 00162 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00163 byte e3 = ((b2 & 0xF) << 2) | (b3 >> 6); 00164 byte e4 = b3 & 0x3F; 00165 00166 /* store */ 00167 out[i++] = base64Encode[e1]; 00168 out[i++] = base64Encode[e2]; 00169 out[i++] = base64Encode[e3]; 00170 out[i++] = base64Encode[e4]; 00171 00172 inLen -= 3; 00173 00174 if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) 00175 out[i++] = '\n'; 00176 } 00177 00178 /* last integral */ 00179 if (inLen) { 00180 int twoBytes = (inLen == 2); 00181 00182 byte b1 = in[j++]; 00183 byte b2 = (twoBytes) ? in[j++] : 0; 00184 00185 byte e1 = b1 >> 2; 00186 byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4); 00187 byte e3 = (b2 & 0xF) << 2; 00188 00189 out[i++] = base64Encode[e1]; 00190 out[i++] = base64Encode[e2]; 00191 out[i++] = (twoBytes) ? base64Encode[e3] : PAD; 00192 out[i++] = PAD; 00193 } 00194 00195 out[i++] = '\n'; 00196 if (i != outSz) 00197 return ASN_INPUT_E; 00198 *outLen = outSz; 00199 00200 return 0; 00201 } 00202 00203 #if defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) 00204 00205 static 00206 const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 00207 BAD, BAD, BAD, BAD, BAD, BAD, BAD, 00208 10, 11, 12, 13, 14, 15 00209 }; /* A starts at 0x41 not 0x3A */ 00210 00211 int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) 00212 { 00213 word32 inIdx = 0; 00214 word32 outIdx = 0; 00215 00216 if (inLen == 1 && *outLen && in) { 00217 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ 00218 00219 /* sanity check */ 00220 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00221 return ASN_INPUT_E; 00222 00223 b = hexDecode[b]; 00224 00225 if (b == BAD) 00226 return ASN_INPUT_E; 00227 00228 out[outIdx++] = b; 00229 00230 *outLen = outIdx; 00231 return 0; 00232 } 00233 00234 if (inLen % 2) 00235 return BAD_FUNC_ARG; 00236 00237 if (*outLen < (inLen / 2)) 00238 return BAD_FUNC_ARG; 00239 00240 while (inLen) { 00241 byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ 00242 byte b2 = in[inIdx++] - 0x30; 00243 00244 /* sanity checks */ 00245 if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00246 return ASN_INPUT_E; 00247 if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) 00248 return ASN_INPUT_E; 00249 00250 b = hexDecode[b]; 00251 b2 = hexDecode[b2]; 00252 00253 if (b == BAD || b2 == BAD) 00254 return ASN_INPUT_E; 00255 00256 out[outIdx++] = (b << 4) | b2; 00257 inLen -= 2; 00258 } 00259 00260 *outLen = outIdx; 00261 return 0; 00262 } 00263 00264 00265 #endif /* defined(OPENSSL_EXTRA) || defined (SESSION_CERTS) || defined(CYASSL_KEY_GEN) || defined(CYASSL_CERT_GEN) || defined(HAVE_WEBSERVER) */
Generated on Wed Jul 13 2022 10:25:18 by 1.7.2