| File: | md5.c |
| Location: | line 104, column 29 |
| Description: | Potential buffer overflow. Replace with 'sizeof(chBuffer) - strlen(chBuffer) - 1' or use a safer 'strlcat' API |
| 1 | /* -*- c++ -*- |
| 2 | Copyright (C) 2004-2013 Christian Wieninger |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or |
| 5 | modify it under the terms of the GNU General Public License |
| 6 | as published by the Free Software Foundation; either version 2 |
| 7 | of the License, or (at your option) any later version. |
| 8 | |
| 9 | This program is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program; if not, write to the Free Software |
| 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 | Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| 18 | |
| 19 | The author can be reached at cwieninger@gmx.de |
| 20 | |
| 21 | The project's page is at http://winni.vdr-developer.org/epgsearch |
| 22 | */ |
| 23 | |
| 24 | ///////////////////////////////////////////////////////////////////////// |
| 25 | // MD5.cpp |
| 26 | // Implementation file for MD5 class |
| 27 | // |
| 28 | // This C++ Class implementation of the original RSA Data Security, Inc. |
| 29 | // MD5 Message-Digest Algorithm is copyright (c) 2002, Gary McNickle. |
| 30 | // All rights reserved. This software is a derivative of the "RSA Data |
| 31 | // Security, Inc. MD5 Message-Digest Algorithm" |
| 32 | // |
| 33 | // You may use this software free of any charge, but without any |
| 34 | // warranty or implied warranty, provided that you follow the terms |
| 35 | // of the original RSA copyright, listed below. |
| 36 | // |
| 37 | // Original RSA Data Security, Inc. Copyright notice |
| 38 | ///////////////////////////////////////////////////////////////////////// |
| 39 | // |
| 40 | // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All |
| 41 | // rights reserved. |
| 42 | // |
| 43 | // License to copy and use this software is granted provided that it |
| 44 | // is identified as the "RSA Data Security, Inc. MD5 Message-Digest |
| 45 | // Algorithm" in all material mentioning or referencing this software |
| 46 | // or this function. |
| 47 | // License is also granted to make and use derivative works provided |
| 48 | // that such works are identified as "derived from the RSA Data |
| 49 | // Security, Inc. MD5 Message-Digest Algorithm" in all material |
| 50 | // mentioning or referencing the derived work. |
| 51 | // RSA Data Security, Inc. makes no representations concerning either |
| 52 | // the merchantability of this software or the suitability of this |
| 53 | // software for any particular purpose. It is provided "as is" |
| 54 | // without express or implied warranty of any kind. |
| 55 | // These notices must be retained in any copies of any part of this |
| 56 | // documentation and/or software. |
| 57 | ///////////////////////////////////////////////////////////////////////// |
| 58 | |
| 59 | #include <assert.h> |
| 60 | #include <memory.h> |
| 61 | #include <stdio.h> |
| 62 | #include <string.h> |
| 63 | #include "md5.h" |
| 64 | |
| 65 | |
| 66 | static unsigned char PADDING[64] = |
| 67 | { |
| 68 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 69 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 70 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 |
| 71 | }; |
| 72 | |
| 73 | #define S117 7 |
| 74 | #define S1212 12 |
| 75 | #define S1317 17 |
| 76 | #define S1422 22 |
| 77 | #define S215 5 |
| 78 | #define S229 9 |
| 79 | #define S2314 14 |
| 80 | #define S2420 20 |
| 81 | #define S314 4 |
| 82 | #define S3211 11 |
| 83 | #define S3316 16 |
| 84 | #define S3423 23 |
| 85 | #define S416 6 |
| 86 | #define S4210 10 |
| 87 | #define S4315 15 |
| 88 | #define S4421 21 |
| 89 | |
| 90 | |
| 91 | // PrintMD5: Converts a completed md5 digest into a char* string. |
| 92 | char* PrintMD5(uchar md5Digest[16]) |
| 93 | { |
| 94 | char chBuffer[256]; |
| 95 | char chEach[10]; |
| 96 | int nCount; |
| 97 | |
| 98 | memset(chBuffer,0,256); |
| 99 | memset(chEach, 0, 10); |
| 100 | |
| 101 | for (nCount = 0; nCount < 16; nCount++) |
| 102 | { |
| 103 | sprintf(chEach, "%02x", md5Digest[nCount]); |
| 104 | strncat(chBuffer, chEach, sizeof(chEach)); |
Potential buffer overflow. Replace with 'sizeof(chBuffer) - strlen(chBuffer) - 1' or use a safer 'strlcat' API | |
| 105 | } |
| 106 | |
| 107 | return strdup(chBuffer); |
| 108 | } |
| 109 | |
| 110 | // MD5String: Performs the MD5 algorithm on a char* string, returning |
| 111 | // the results as a char*. |
| 112 | char* MD5String(char* szString) |
| 113 | { |
| 114 | int nLen = strlen(szString); |
| 115 | md5 alg; |
| 116 | |
| 117 | alg.Update((unsigned char*)szString, (unsigned int)nLen); |
| 118 | alg.Finalize(); |
| 119 | |
| 120 | return PrintMD5(alg.Digest()); |
| 121 | |
| 122 | } |
| 123 | |
| 124 | // md5::Init |
| 125 | // Initializes a new context. |
| 126 | void md5::Init() |
| 127 | { |
| 128 | memset(m_Count, 0, 2 * sizeof(uint4)); |
| 129 | |
| 130 | m_State[0] = 0x67452301; |
| 131 | m_State[1] = 0xefcdab89; |
| 132 | m_State[2] = 0x98badcfe; |
| 133 | m_State[3] = 0x10325476; |
| 134 | } |
| 135 | |
| 136 | // md5::Update |
| 137 | // MD5 block update operation. Continues an MD5 message-digest |
| 138 | // operation, processing another message block, and updating the |
| 139 | // context. |
| 140 | void md5::Update(uchar* chInput, uint4 nInputLen) |
| 141 | { |
| 142 | uint4 i, index, partLen; |
| 143 | |
| 144 | // Compute number of bytes mod 64 |
| 145 | index = (unsigned int)((m_Count[0] >> 3) & 0x3F); |
| 146 | |
| 147 | // Update number of bits |
| 148 | if ((m_Count[0] += (nInputLen << 3)) < (nInputLen << 3)) |
| 149 | m_Count[1]++; |
| 150 | |
| 151 | m_Count[1] += (nInputLen >> 29); |
| 152 | |
| 153 | partLen = 64 - index; |
| 154 | |
| 155 | // Transform as many times as possible. |
| 156 | if (nInputLen >= partLen) |
| 157 | { |
| 158 | memcpy( &m_Buffer[index], chInput, partLen ); |
| 159 | Transform(m_Buffer); |
| 160 | |
| 161 | for (i = partLen; i + 63 < nInputLen; i += 64) |
| 162 | Transform(&chInput[i]); |
| 163 | |
| 164 | index = 0; |
| 165 | } |
| 166 | else |
| 167 | i = 0; |
| 168 | |
| 169 | // Buffer remaining input |
| 170 | memcpy( &m_Buffer[index], &chInput[i], nInputLen-i ); |
| 171 | } |
| 172 | |
| 173 | // md5::Finalize |
| 174 | // MD5 finalization. Ends an MD5 message-digest operation, writing |
| 175 | // the message digest and zeroizing the context. |
| 176 | void md5::Finalize() |
| 177 | { |
| 178 | uchar bits[8]; |
| 179 | uint4 index, padLen; |
| 180 | |
| 181 | // Save number of bits |
| 182 | Encode (bits, m_Count, 8); |
| 183 | |
| 184 | // Pad out to 56 mod 64 |
| 185 | index = (unsigned int)((m_Count[0] >> 3) & 0x3f); |
| 186 | padLen = (index < 56) ? (56 - index) : (120 - index); |
| 187 | Update(PADDING, padLen); |
| 188 | |
| 189 | // Append length (before padding) |
| 190 | Update (bits, 8); |
| 191 | |
| 192 | // Store state in digest |
| 193 | Encode (m_Digest, m_State, 16); |
| 194 | |
| 195 | memset(m_Count, 0, 2 * sizeof(uint4)); |
| 196 | memset(m_State, 0, 4 * sizeof(uint4)); |
| 197 | memset(m_Buffer,0, 64 * sizeof(uchar)); |
| 198 | } |
| 199 | |
| 200 | // md5::Transform |
| 201 | // MD5 basic transformation. Transforms state based on block. |
| 202 | void md5::Transform (uchar* block) |
| 203 | { |
| 204 | uint4 a = m_State[0], b = m_State[1], c = m_State[2], d = m_State[3], x[16]; |
| 205 | |
| 206 | Decode (x, block, 64); |
| 207 | |
| 208 | // Round 1 |
| 209 | FF (a, b, c, d, x[ 0], S117, 0xd76aa478); |
| 210 | FF (d, a, b, c, x[ 1], S1212, 0xe8c7b756); |
| 211 | FF (c, d, a, b, x[ 2], S1317, 0x242070db); |
| 212 | FF (b, c, d, a, x[ 3], S1422, 0xc1bdceee); |
| 213 | FF (a, b, c, d, x[ 4], S117, 0xf57c0faf); |
| 214 | FF (d, a, b, c, x[ 5], S1212, 0x4787c62a); |
| 215 | FF (c, d, a, b, x[ 6], S1317, 0xa8304613); |
| 216 | FF (b, c, d, a, x[ 7], S1422, 0xfd469501); |
| 217 | FF (a, b, c, d, x[ 8], S117, 0x698098d8); |
| 218 | FF (d, a, b, c, x[ 9], S1212, 0x8b44f7af); |
| 219 | FF (c, d, a, b, x[10], S1317, 0xffff5bb1); |
| 220 | FF (b, c, d, a, x[11], S1422, 0x895cd7be); |
| 221 | FF (a, b, c, d, x[12], S117, 0x6b901122); |
| 222 | FF (d, a, b, c, x[13], S1212, 0xfd987193); |
| 223 | FF (c, d, a, b, x[14], S1317, 0xa679438e); |
| 224 | FF (b, c, d, a, x[15], S1422, 0x49b40821); |
| 225 | |
| 226 | // Round 2 |
| 227 | GG (a, b, c, d, x[ 1], S215, 0xf61e2562); |
| 228 | GG (d, a, b, c, x[ 6], S229, 0xc040b340); |
| 229 | GG (c, d, a, b, x[11], S2314, 0x265e5a51); |
| 230 | GG (b, c, d, a, x[ 0], S2420, 0xe9b6c7aa); |
| 231 | GG (a, b, c, d, x[ 5], S215, 0xd62f105d); |
| 232 | GG (d, a, b, c, x[10], S229, 0x2441453); |
| 233 | GG (c, d, a, b, x[15], S2314, 0xd8a1e681); |
| 234 | GG (b, c, d, a, x[ 4], S2420, 0xe7d3fbc8); |
| 235 | GG (a, b, c, d, x[ 9], S215, 0x21e1cde6); |
| 236 | GG (d, a, b, c, x[14], S229, 0xc33707d6); |
| 237 | GG (c, d, a, b, x[ 3], S2314, 0xf4d50d87); |
| 238 | GG (b, c, d, a, x[ 8], S2420, 0x455a14ed); |
| 239 | GG (a, b, c, d, x[13], S215, 0xa9e3e905); |
| 240 | GG (d, a, b, c, x[ 2], S229, 0xfcefa3f8); |
| 241 | GG (c, d, a, b, x[ 7], S2314, 0x676f02d9); |
| 242 | GG (b, c, d, a, x[12], S2420, 0x8d2a4c8a); |
| 243 | |
| 244 | // Round 3 |
| 245 | HH (a, b, c, d, x[ 5], S314, 0xfffa3942); |
| 246 | HH (d, a, b, c, x[ 8], S3211, 0x8771f681); |
| 247 | HH (c, d, a, b, x[11], S3316, 0x6d9d6122); |
| 248 | HH (b, c, d, a, x[14], S3423, 0xfde5380c); |
| 249 | HH (a, b, c, d, x[ 1], S314, 0xa4beea44); |
| 250 | HH (d, a, b, c, x[ 4], S3211, 0x4bdecfa9); |
| 251 | HH (c, d, a, b, x[ 7], S3316, 0xf6bb4b60); |
| 252 | HH (b, c, d, a, x[10], S3423, 0xbebfbc70); |
| 253 | HH (a, b, c, d, x[13], S314, 0x289b7ec6); |
| 254 | HH (d, a, b, c, x[ 0], S3211, 0xeaa127fa); |
| 255 | HH (c, d, a, b, x[ 3], S3316, 0xd4ef3085); |
| 256 | HH (b, c, d, a, x[ 6], S3423, 0x4881d05); |
| 257 | HH (a, b, c, d, x[ 9], S314, 0xd9d4d039); |
| 258 | HH (d, a, b, c, x[12], S3211, 0xe6db99e5); |
| 259 | HH (c, d, a, b, x[15], S3316, 0x1fa27cf8); |
| 260 | HH (b, c, d, a, x[ 2], S3423, 0xc4ac5665); |
| 261 | |
| 262 | // Round 4 |
| 263 | II (a, b, c, d, x[ 0], S416, 0xf4292244); |
| 264 | II (d, a, b, c, x[ 7], S4210, 0x432aff97); |
| 265 | II (c, d, a, b, x[14], S4315, 0xab9423a7); |
| 266 | II (b, c, d, a, x[ 5], S4421, 0xfc93a039); |
| 267 | II (a, b, c, d, x[12], S416, 0x655b59c3); |
| 268 | II (d, a, b, c, x[ 3], S4210, 0x8f0ccc92); |
| 269 | II (c, d, a, b, x[10], S4315, 0xffeff47d); |
| 270 | II (b, c, d, a, x[ 1], S4421, 0x85845dd1); |
| 271 | II (a, b, c, d, x[ 8], S416, 0x6fa87e4f); |
| 272 | II (d, a, b, c, x[15], S4210, 0xfe2ce6e0); |
| 273 | II (c, d, a, b, x[ 6], S4315, 0xa3014314); |
| 274 | II (b, c, d, a, x[13], S4421, 0x4e0811a1); |
| 275 | II (a, b, c, d, x[ 4], S416, 0xf7537e82); |
| 276 | II (d, a, b, c, x[11], S4210, 0xbd3af235); |
| 277 | II (c, d, a, b, x[ 2], S4315, 0x2ad7d2bb); |
| 278 | II (b, c, d, a, x[ 9], S4421, 0xeb86d391); |
| 279 | |
| 280 | m_State[0] += a; |
| 281 | m_State[1] += b; |
| 282 | m_State[2] += c; |
| 283 | m_State[3] += d; |
| 284 | |
| 285 | memset(x, 0, sizeof(x)); |
| 286 | } |
| 287 | |
| 288 | // md5::Encode |
| 289 | // Encodes input (uint4) into output (uchar). Assumes nLength is |
| 290 | // a multiple of 4. |
| 291 | void md5::Encode(uchar* dest, uint4* src, uint4 nLength) |
| 292 | { |
| 293 | uint4 i, j; |
| 294 | |
| 295 | assert(nLength % 4 == 0)((nLength % 4 == 0) ? static_cast<void> (0) : __assert_fail ("nLength % 4 == 0", "md5.c", 295, __PRETTY_FUNCTION__)); |
| 296 | |
| 297 | for (i = 0, j = 0; j < nLength; i++, j += 4) |
| 298 | { |
| 299 | dest[j] = (uchar)(src[i] & 0xff); |
| 300 | dest[j+1] = (uchar)((src[i] >> 8) & 0xff); |
| 301 | dest[j+2] = (uchar)((src[i] >> 16) & 0xff); |
| 302 | dest[j+3] = (uchar)((src[i] >> 24) & 0xff); |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | // md5::Decode |
| 307 | // Decodes input (uchar) into output (uint4). Assumes nLength is |
| 308 | // a multiple of 4. |
| 309 | void md5::Decode(uint4* dest, uchar* src, uint4 nLength) |
| 310 | { |
| 311 | uint4 i, j; |
| 312 | |
| 313 | assert(nLength % 4 == 0)((nLength % 4 == 0) ? static_cast<void> (0) : __assert_fail ("nLength % 4 == 0", "md5.c", 313, __PRETTY_FUNCTION__)); |
| 314 | |
| 315 | for (i = 0, j = 0; j < nLength; i++, j += 4) |
| 316 | { |
| 317 | dest[i] = ((uint4)src[j]) | (((uint4)src[j+1])<<8) | |
| 318 | (((uint4)src[j+2])<<16) | (((uint4)src[j+3])<<24); |
| 319 | } |
| 320 | } |