Bug Summary

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

Annotated Source Code

1/* -*- c++ -*-
2Copyright (C) 2004-2013 Christian Wieninger
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18
19The author can be reached at cwieninger@gmx.de
20
21The 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
66static 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.
92char* 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*.
112char* 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.
126void 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.
140void 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.
176void 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.
202void 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.
291void 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.
309void 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}