Suggestion from "mgh".
[open-ps2-loader.git] / ee_core / src / md4.c
blob48b84cf5a88f1bb7196a598d18f6739db46e90b6
1 /*
2 * Adapted from java to C by jimmikaelkael <jimmikaelkael@wanadoo.fr>
3 */
5 /**
6 * Implements the MD4 message digest algorithm in Java.
7 *
8 * References:
9 *
10 * Ronald L. Rivest,
11 * The MD4 Message-Digest Algorithm: <http://www.roxen.com/rfc/rfc1320.html>,
12 * IETF RFC-1320 (informational).
14 * Revision: 1.2
15 * @author Raif S. Naffah
18 #include <string.h>
20 static unsigned int context[4];
23 * The basic MD4 atomic functions.
25 static unsigned int FF(int a, int b, int c, int d, int x, int s)
27 unsigned int t = (a + ((b & c) | (~b & d)) + x) & 0xFFFFFFFF;
28 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
31 static unsigned int GG(int a, int b, int c, int d, int x, int s)
33 unsigned int t = (a + ((b & c) | (b & d) | (c & d)) + x + 0x5A827999) & 0xFFFFFFFF;
34 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
37 static unsigned int HH(int a, int b, int c, int d, int x, int s)
39 unsigned int t = (a + (b ^ c ^ d) + x + 0x6ED9EBA1) & 0xFFFFFFFF;
40 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
43 /**
44 * MD4 basic transformation.
46 * Transforms context based on 512 bits from input block
48 * @param block input block
50 static void transform(unsigned char *block)
52 int i;
53 unsigned int X[16];
55 for (i=0; i<16; i++)
56 X[i] = (block[i*4+3] << 24) | (block[i*4+2] << 16) | (block[i*4+1] << 8) | block[i*4];
58 unsigned int A = context[0];
59 unsigned int B = context[1];
60 unsigned int C = context[2];
61 unsigned int D = context[3];
63 A = FF(A, B, C, D, X[0], 3);
64 D = FF(D, A, B, C, X[1], 7);
65 C = FF(C, D, A, B, X[2], 11);
66 B = FF(B, C, D, A, X[3], 19);
67 A = FF(A, B, C, D, X[4], 3);
68 D = FF(D, A, B, C, X[5], 7);
69 C = FF(C, D, A, B, X[6], 11);
70 B = FF(B, C, D, A, X[7], 19);
71 A = FF(A, B, C, D, X[8], 3);
72 D = FF(D, A, B, C, X[9], 7);
73 C = FF(C, D, A, B, X[10], 11);
74 B = FF(B, C, D, A, X[11], 19);
75 A = FF(A, B, C, D, X[12], 3);
76 D = FF(D, A, B, C, X[13], 7);
77 C = FF(C, D, A, B, X[14], 11);
78 B = FF(B, C, D, A, X[15], 19);
80 A = GG(A, B, C, D, X[0], 3);
81 D = GG(D, A, B, C, X[4], 5);
82 C = GG(C, D, A, B, X[8], 9);
83 B = GG(B, C, D, A, X[12], 13);
84 A = GG(A, B, C, D, X[1], 3);
85 D = GG(D, A, B, C, X[5], 5);
86 C = GG(C, D, A, B, X[9], 9);
87 B = GG(B, C, D, A, X[13], 13);
88 A = GG(A, B, C, D, X[2], 3);
89 D = GG(D, A, B, C, X[6], 5);
90 C = GG(C, D, A, B, X[10], 9);
91 B = GG(B, C, D, A, X[14], 13);
92 A = GG(A, B, C, D, X[3], 3);
93 D = GG(D, A, B, C, X[7], 5);
94 C = GG(C, D, A, B, X[11], 9);
95 B = GG(B, C, D, A, X[15], 13);
97 A = HH(A, B, C, D, X[0], 3);
98 D = HH(D, A, B, C, X[8], 9);
99 C = HH(C, D, A, B, X[4], 11);
100 B = HH(B, C, D, A, X[12], 15);
101 A = HH(A, B, C, D, X[2], 3);
102 D = HH(D, A, B, C, X[10], 9);
103 C = HH(C, D, A, B, X[6], 11);
104 B = HH(B, C, D, A, X[14], 15);
105 A = HH(A, B, C, D, X[1], 3);
106 D = HH(D, A, B, C, X[9], 9);
107 C = HH(C, D, A, B, X[5], 11);
108 B = HH(B, C, D, A, X[13], 15);
109 A = HH(A, B, C, D, X[3], 3);
110 D = HH(D, A, B, C, X[11], 9);
111 C = HH(C, D, A, B, X[7], 11);
112 B = HH(B, C, D, A, X[15], 15);
114 context[0] += A;
115 context[1] += B;
116 context[2] += C;
117 context[3] += D;
119 context[0] &= 0xFFFFFFFF;
120 context[1] &= 0xFFFFFFFF;
121 context[2] &= 0xFFFFFFFF;
122 context[3] &= 0xFFFFFFFF;
126 * Resets this object disregarding any temporary data present at the
127 * time of the invocation of this call.
129 static void engineReset()
131 // initial values of MD4 i.e. A, B, C, D
132 // as per rfc-1320; they are low-order byte first
133 context[0] = 0x67452301;
134 context[1] = 0xEFCDAB89;
135 context[2] = 0x98BADCFE;
136 context[3] = 0x10325476;
139 /**
140 * produce a MD4 message digest from message of len bytes
142 unsigned char *MD4(unsigned char *message, int len, unsigned char *cipher)
144 unsigned char buffer[128];
145 unsigned int b = len * 8;
147 engineReset();
149 while (len > 64) {
150 memcpy(buffer, message, 64);
151 transform(buffer);
152 message += 64;
153 len -= 64;
156 memset(buffer, 0, 128);
157 memcpy(buffer, message, len);
158 buffer[len] = 0x80;
160 if (len < 56) {
161 *((unsigned int *)&buffer[56]) = b;
162 transform(buffer);
163 } else {
164 *((unsigned int *)&buffer[120]) = b;
165 transform(buffer);
166 transform(&buffer[64]);
169 *((unsigned int *)&cipher[0]) = context[0];
170 *((unsigned int *)&cipher[4]) = context[1];
171 *((unsigned int *)&cipher[8]) = context[2];
172 *((unsigned int *)&cipher[12]) = context[3];
174 return (unsigned char *)cipher;