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 | } |