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