Coverage Report

Created: 2025-07-12 06:14

/src/opensips/md5.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
3
4
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
5
rights reserved.
6
7
License to copy and use this software is granted provided that it
8
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
9
Algorithm" in all material mentioning or referencing this software
10
or this function.
11
12
License is also granted to make and use derivative works provided
13
that such works are identified as "derived from the RSA Data
14
Security, Inc. MD5 Message-Digest Algorithm" in all material
15
mentioning or referencing the derived work.
16
17
RSA Data Security, Inc. makes no representations concerning either
18
the merchantability of this software or the suitability of this
19
software for any particular purpose. It is provided "as is"
20
without express or implied warranty of any kind.
21
22
These notices must be retained in any copies of any part of this
23
documentation and/or software.
24
 */
25
26
/*!
27
 * \file
28
 * \brief MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
29
 */
30
31
32
#include <string.h>
33
#include "md5global.h"
34
#include "md5.h"
35
36
37
#define USE_MEM
38
39
/* Constants for MD5Transform routine.
40
 */
41
42
43
#define S11 7
44
#define S12 12
45
#define S13 17
46
#define S14 22
47
#define S21 5
48
#define S22 9
49
#define S23 14
50
#define S24 20
51
#define S31 4
52
#define S32 11
53
#define S33 16
54
#define S34 23
55
#define S41 6
56
#define S42 10
57
#define S43 15
58
#define S44 21
59
60
static void MD5Transform(UINT4 [4], const unsigned char [64]);
61
static void Encode(unsigned char *, UINT4 *, unsigned int);
62
static void Decode(UINT4 *, const unsigned char *, unsigned int);
63
static void MD5_memcpy(POINTER, POINTER, unsigned int);
64
static void MD5_memset(POINTER, int, unsigned int);
65
66
static unsigned char PADDING[64] = {
67
  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68
  0, 0, 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
70
};
71
72
/* F, G, H and I are basic MD5 functions.
73
 */
74
0
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
75
0
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
76
0
#define H(x, y, z) ((x) ^ (y) ^ (z))
77
0
#define I(x, y, z) ((y) ^ ((x) | (~z)))
78
79
/* ROTATE_LEFT rotates x left n bits.
80
 */
81
0
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
82
83
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
84
Rotation is separate from addition to prevent recomputation.
85
 */
86
0
#define FF(a, b, c, d, x, s, ac) { \
87
0
 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
88
0
 (a) = ROTATE_LEFT ((a), (s)); \
89
0
 (a) += (b); \
90
0
  }
91
0
#define GG(a, b, c, d, x, s, ac) { \
92
0
 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
93
0
 (a) = ROTATE_LEFT ((a), (s)); \
94
0
 (a) += (b); \
95
0
  }
96
0
#define HH(a, b, c, d, x, s, ac) { \
97
0
 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
98
0
 (a) = ROTATE_LEFT ((a), (s)); \
99
0
 (a) += (b); \
100
0
  }
101
0
#define II(a, b, c, d, x, s, ac) { \
102
0
 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
103
0
 (a) = ROTATE_LEFT ((a), (s)); \
104
0
 (a) += (b); \
105
0
  }
106
107
/* MD5 initialization. Begins an MD5 operation, writing a new context.
108
   MD5_CTX *context - context
109
 */
110
void MD5Init (MD5_CTX *context)
111
0
{
112
0
  context->count[0] = context->count[1] = 0;
113
  /* Load magic initialization constants.
114
*/
115
0
  context->state[0] = 0x67452301;
116
0
  context->state[1] = 0xefcdab89;
117
0
  context->state[2] = 0x98badcfe;
118
0
  context->state[3] = 0x10325476;
119
0
}
120
121
/* MD5 block update operation. Continues an MD5 message-digest
122
   operation, processing another message block, and updating the
123
   context.
124
   MD5_CTX *context - context
125
   unsigned char *input - input block
126
   unsigned int inputLen - length of input block
127
 */
128
void MD5Update (MD5_CTX *context, const char *input, unsigned int inputLen)
129
0
{
130
0
  unsigned int i, index, partLen;
131
132
  /* Compute number of bytes mod 64 */
133
0
  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
134
135
  /* Update number of bits */
136
0
  if ((context->count[0] += ((UINT4)inputLen << 3))
137
138
0
   < ((UINT4)inputLen << 3))
139
0
 context->count[1]++;
140
0
  context->count[1] += ((UINT4)inputLen >> 29);
141
142
0
  partLen = 64 - index;
143
144
  /* Transform as many times as possible.
145
*/
146
0
  if (inputLen >= partLen) {
147
0
 MD5_memcpy
148
0
   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
149
0
 MD5Transform (context->state, context->buffer);
150
151
0
 for (i = partLen; i + 63 < inputLen; i += 64)
152
0
   MD5Transform (context->state, (const unsigned char *)(&input[i]));
153
154
0
 index = 0;
155
0
  }
156
0
  else
157
0
 i = 0;
158
159
  /* Buffer remaining input */
160
0
  MD5_memcpy
161
0
 ((POINTER)&context->buffer[index], (POINTER)&input[i],
162
0
  inputLen-i);
163
0
}
164
165
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
166
  the message digest and zeroizing the context.
167
  unsigned char digest[16] - message digest
168
  MD5_CTX *context - context
169
 */
170
void MD5Final (char digest[16], MD5_CTX *context)
171
0
{
172
0
  unsigned char bits[8];
173
0
  unsigned int index, padLen;
174
175
  /* Save number of bits */
176
0
  Encode (bits, context->count, 8);
177
178
  /* Pad out to 56 mod 64.
179
*/
180
0
  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
181
0
  padLen = (index < 56) ? (56 - index) : (120 - index);
182
0
  MD5Update (context, (const char *)PADDING, padLen);
183
184
  /* Append length (before padding) */
185
0
  MD5Update (context, (const char *)bits, 8);
186
187
  /* Store state in digest */
188
0
  Encode ((unsigned char *)digest, context->state, 16);
189
190
  /* Zeroize sensitive information.
191
*/
192
0
  MD5_memset ((POINTER)context, 0, sizeof (*context));
193
0
}
194
195
/* MD5 basic transformation. Transforms state based on block.
196
 */
197
static void MD5Transform (UINT4 state[4], const unsigned char block[64])
198
0
{
199
0
  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
200
201
0
  Decode (x, block, 64);
202
203
  /* Round 1 */
204
0
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
205
0
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
206
0
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
207
0
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
208
0
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
209
0
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
210
0
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
211
0
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
212
0
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
213
0
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
214
0
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
215
0
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
216
0
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
217
0
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
218
0
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
219
0
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
220
221
 /* Round 2 */
222
0
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
223
0
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
224
0
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
225
0
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
226
0
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
227
0
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
228
0
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
229
0
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
230
0
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
231
0
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
232
0
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
233
0
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
234
0
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
235
0
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
236
0
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
237
0
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
238
239
  /* Round 3 */
240
0
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
241
0
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
242
0
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
243
0
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
244
0
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
245
0
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
246
0
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
247
0
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
248
0
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
249
0
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
250
0
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
251
0
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
252
0
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
253
0
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
254
0
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
255
0
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
256
257
  /* Round 4 */
258
0
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
259
0
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
260
0
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
261
0
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
262
0
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
263
0
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
264
0
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
265
0
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
266
0
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
267
0
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
268
0
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
269
0
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
270
0
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
271
0
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
272
0
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
273
0
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
274
275
0
  state[0] += a;
276
0
  state[1] += b;
277
0
  state[2] += c;
278
0
  state[3] += d;
279
280
  /* Zeroize sensitive information.
281
*/
282
0
  MD5_memset ((POINTER)x, 0, sizeof (x));
283
0
}
284
285
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
286
  a multiple of 4.
287
 */
288
static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
289
0
{
290
0
  unsigned int i, j;
291
292
0
  for (i = 0, j = 0; j < len; i++, j += 4) {
293
0
 output[j] = (unsigned char)(input[i] & 0xff);
294
0
 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
295
0
 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
296
0
 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
297
0
  }
298
0
}
299
300
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
301
  a multiple of 4.
302
 */
303
static void Decode (UINT4 *output, const unsigned char *input, unsigned int len)
304
0
{
305
0
  unsigned int i, j;
306
307
0
  for (i = 0, j = 0; j < len; i++, j += 4)
308
0
 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
309
0
   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
310
0
}
311
312
/* Note: Replace "for loop" with standard memcpy if possible.
313
 */
314
315
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
316
0
{
317
318
#ifndef USE_MEM
319
  unsigned int i;
320
321
  for (i = 0; i < len; i++)
322
 output[i] = input[i];
323
#else
324
0
  memcpy( output, input, len );
325
0
#endif
326
0
}
327
328
/* Note: Replace "for loop" with standard memset if possible.
329
 */
330
static void MD5_memset (POINTER output, int value, unsigned int len)
331
0
{
332
333
#ifndef USE_MEM
334
  unsigned int i;
335
  for (i = 0; i < len; i++)
336
 ((char *)output)[i] = (char)value;
337
#else
338
0
  memset( output, value, len );
339
0
#endif
340
0
}