vkQuake2 doxygen  1.0 dev
md4.c
Go to the documentation of this file.
1 /*
2  * Public Domain C source implementation of RFC 1320
3  * - The MD4 Message-Digest Algorithm -
4  *
5  * http://www.faqs.org/rfcs/rfc1320.html
6  * by Steven Fuller
7  */
8 
9 #include <inttypes.h>
10 
11 #define ROTATELEFT32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
12 
13 #define F(X, Y, Z) (((X)&(Y)) | ((~X) & (Z)))
14 #define G(X, Y, Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
15 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
16 
17 #define S(a, b, c, d, k, s) \
18  { \
19  a += (F((b), (c), (d)) + X[(k)]); \
20  a = ROTATELEFT32(a, s); \
21  }
22 #define T(a, b, c, d, k, s) \
23  { \
24  a += (G((b), (c), (d)) + X[(k)] + 0x5A827999); \
25  a = ROTATELEFT32(a, s); \
26  }
27 #define U(a, b, c, d, k, s) \
28  { \
29  a += (H((b), (c), (d)) + X[(k)] + 0x6ED9EBA1); \
30  a = ROTATELEFT32(a, s); \
31  }
32 
33 static uint32_t X[16];
34 static uint32_t A, AA;
35 static uint32_t B, BB;
36 static uint32_t C, CC;
37 static uint32_t D, DD;
38 
39 static void
41 {
42  AA = A;
43  BB = B;
44  CC = C;
45  DD = D;
46 
47  S(A, B, C, D, 0, 3);
48  S(D, A, B, C, 1, 7);
49  S(C, D, A, B, 2, 11);
50  S(B, C, D, A, 3, 19);
51  S(A, B, C, D, 4, 3);
52  S(D, A, B, C, 5, 7);
53  S(C, D, A, B, 6, 11);
54  S(B, C, D, A, 7, 19);
55  S(A, B, C, D, 8, 3);
56  S(D, A, B, C, 9, 7);
57  S(C, D, A, B, 10, 11);
58  S(B, C, D, A, 11, 19);
59  S(A, B, C, D, 12, 3);
60  S(D, A, B, C, 13, 7);
61  S(C, D, A, B, 14, 11);
62  S(B, C, D, A, 15, 19);
63 
64  T(A, B, C, D, 0, 3);
65  T(D, A, B, C, 4, 5);
66  T(C, D, A, B, 8, 9);
67  T(B, C, D, A, 12, 13);
68  T(A, B, C, D, 1, 3);
69  T(D, A, B, C, 5, 5);
70  T(C, D, A, B, 9, 9);
71  T(B, C, D, A, 13, 13);
72  T(A, B, C, D, 2, 3);
73  T(D, A, B, C, 6, 5);
74  T(C, D, A, B, 10, 9);
75  T(B, C, D, A, 14, 13);
76  T(A, B, C, D, 3, 3);
77  T(D, A, B, C, 7, 5);
78  T(C, D, A, B, 11, 9);
79  T(B, C, D, A, 15, 13);
80 
81  U(A, B, C, D, 0, 3);
82  U(D, A, B, C, 8, 9);
83  U(C, D, A, B, 4, 11);
84  U(B, C, D, A, 12, 15);
85  U(A, B, C, D, 2, 3);
86  U(D, A, B, C, 10, 9);
87  U(C, D, A, B, 6, 11);
88  U(B, C, D, A, 14, 15);
89  U(A, B, C, D, 1, 3);
90  U(D, A, B, C, 9, 9);
91  U(C, D, A, B, 5, 11);
92  U(B, C, D, A, 13, 15);
93  U(A, B, C, D, 3, 3);
94  U(D, A, B, C, 11, 9);
95  U(C, D, A, B, 7, 11);
96  U(B, C, D, A, 15, 15);
97 
98  A += AA;
99  B += BB;
100  C += CC;
101  D += DD;
102 }
103 
104 static void
105 PerformMD4(const unsigned char *buf, int length, unsigned char *digest)
106 {
107  int len = length / 64; /* number of full blocks */
108  int rem = length % 64; /* number of left over bytes */
109 
110  int i, j;
111  const unsigned char *ptr = buf;
112 
113  /* initialize the MD buffer */
114  A = 0x67452301;
115  B = 0xEFCDAB89;
116  C = 0x98BADCFE;
117  D = 0x10325476;
118 
119  for (i = 0; i < len; i++)
120  {
121  for (j = 0; j < 16; j++)
122  {
123  X[j] = ((ptr[0] << 0) | (ptr[1] << 8) |
124  (ptr[2] << 16) | (ptr[3] << 24));
125 
126  ptr += 4;
127  }
128 
129  DoMD4();
130  }
131 
132  i = rem / 4;
133 
134  for (j = 0; j < i; j++)
135  {
136  X[j] = ((ptr[0] << 0) | (ptr[1] << 8) |
137  (ptr[2] << 16) | (ptr[3] << 24));
138 
139  ptr += 4;
140  }
141 
142  switch (rem % 4)
143  {
144  case 0:
145  X[j] = 0x80U;
146  break;
147  case 1:
148  X[j] = ((ptr[0] << 0) | ((0x80U) << 8));
149  break;
150  case 2:
151  X[j] = ((ptr[0] << 0) | (ptr[1] << 8) | ((0x80U) << 16));
152  break;
153  case 3:
154  X[j] =
155  ((ptr[0] <<
156  0) | (ptr[1] << 8) | (ptr[2] << 16) | ((0x80U) << 24));
157  break;
158  }
159 
160  j++;
161 
162  if (j > 14)
163  {
164  for ( ; j < 16; j++)
165  {
166  X[j] = 0;
167  }
168 
169  DoMD4();
170 
171  j = 0;
172  }
173 
174  for ( ; j < 14; j++)
175  {
176  X[j] = 0;
177  }
178 
179  X[14] = (length & 0x1FFFFFFF) << 3;
180  X[15] = (length & ~0x1FFFFFFF) >> 29;
181 
182  DoMD4();
183 
184  digest[0] = (A & 0x000000FF) >> 0;
185  digest[1] = (A & 0x0000FF00) >> 8;
186  digest[2] = (A & 0x00FF0000) >> 16;
187  digest[3] = (A & 0xFF000000) >> 24;
188  digest[4] = (B & 0x000000FF) >> 0;
189  digest[5] = (B & 0x0000FF00) >> 8;
190  digest[6] = (B & 0x00FF0000) >> 16;
191  digest[7] = (B & 0xFF000000) >> 24;
192  digest[8] = (C & 0x000000FF) >> 0;
193  digest[9] = (C & 0x0000FF00) >> 8;
194  digest[10] = (C & 0x00FF0000) >> 16;
195  digest[11] = (C & 0xFF000000) >> 24;
196  digest[12] = (D & 0x000000FF) >> 0;
197  digest[13] = (D & 0x0000FF00) >> 8;
198  digest[14] = (D & 0x00FF0000) >> 16;
199  digest[15] = (D & 0xFF000000) >> 24;
200 
201  A = AA = 0;
202  B = BB = 0;
203  C = CC = 0;
204  D = DD = 0;
205 
206  for (j = 0; j < 16; j++)
207  {
208  X[j] = 0;
209  }
210 }
211 
212 unsigned
213 Com_BlockChecksum(void *buffer, int length)
214 {
215  uint32_t digest[4];
216  unsigned val;
217 
218  PerformMD4((unsigned char *)buffer, length, (unsigned char *)digest);
219 
220  val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
221 
222  return val;
223 }
DoMD4
static void DoMD4()
Definition: md4.c:40
C
static uint32_t C
Definition: md4.c:36
X
static uint32_t X[16]
Definition: md4.c:33
T
#define T(a, b, c, d, k, s)
Definition: md4.c:22
S
#define S(a, b, c, d, k, s)
Definition: md4.c:17
U
#define U(a, b, c, d, k, s)
Definition: md4.c:27
i
int i
Definition: q_shared.c:305
D
static uint32_t D
Definition: md4.c:37
A
static uint32_t A
Definition: md4.c:34
buffer
GLenum GLfloat * buffer
Definition: qgl_win.c:151
j
GLint j
Definition: qgl_win.c:150
B
static uint32_t B
Definition: md4.c:35
CC
static uint32_t CC
Definition: md4.c:36
DD
static uint32_t DD
Definition: md4.c:37
PerformMD4
static void PerformMD4(const unsigned char *buf, int length, unsigned char *digest)
Definition: md4.c:105
Com_BlockChecksum
unsigned Com_BlockChecksum(void *buffer, int length)
Definition: md4.c:213
BB
static uint32_t BB
Definition: md4.c:35
AA
static uint32_t AA
Definition: md4.c:34