PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
md4.c
1/*
2 * Adapted from java to C by jimmikaelkael <jimmikaelkael@wanadoo.fr>
3 */
4
18#include "types.h"
19#include "defs.h"
20#include "irx.h"
21#include "string.h"
22
23static unsigned int context[4];
24
25/*
26 * The basic MD4 atomic functions.
27 */
28static unsigned int FF(int a, int b, int c, int d, int x, int s)
29{
30 unsigned int t = (a + ((b & c) | (~b & d)) + x) & 0xFFFFFFFF;
31 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
32}
33
34static unsigned int GG(int a, int b, int c, int d, int x, int s)
35{
36 unsigned int t = (a + ((b & c) | (b & d) | (c & d)) + x + 0x5A827999) & 0xFFFFFFFF;
37 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
38}
39
40static unsigned int HH(int a, int b, int c, int d, int x, int s)
41{
42 unsigned int t = (a + (b ^ c ^ d) + x + 0x6ED9EBA1) & 0xFFFFFFFF;
43 return ((t << s) & 0xFFFFFFFF) | (t >> (32 - s));
44}
45
53static void transform(const unsigned char *block)
54{
55 int i;
56 unsigned int X[16];
57
58 for (i = 0; i < 16; i++)
59 X[i] = (block[i * 4 + 3] << 24) | (block[i * 4 + 2] << 16) | (block[i * 4 + 1] << 8) | block[i * 4];
60
61 unsigned int A = context[0];
62 unsigned int B = context[1];
63 unsigned int C = context[2];
64 unsigned int D = context[3];
65
66 A = FF(A, B, C, D, X[0], 3);
67 D = FF(D, A, B, C, X[1], 7);
68 C = FF(C, D, A, B, X[2], 11);
69 B = FF(B, C, D, A, X[3], 19);
70 A = FF(A, B, C, D, X[4], 3);
71 D = FF(D, A, B, C, X[5], 7);
72 C = FF(C, D, A, B, X[6], 11);
73 B = FF(B, C, D, A, X[7], 19);
74 A = FF(A, B, C, D, X[8], 3);
75 D = FF(D, A, B, C, X[9], 7);
76 C = FF(C, D, A, B, X[10], 11);
77 B = FF(B, C, D, A, X[11], 19);
78 A = FF(A, B, C, D, X[12], 3);
79 D = FF(D, A, B, C, X[13], 7);
80 C = FF(C, D, A, B, X[14], 11);
81 B = FF(B, C, D, A, X[15], 19);
82
83 A = GG(A, B, C, D, X[0], 3);
84 D = GG(D, A, B, C, X[4], 5);
85 C = GG(C, D, A, B, X[8], 9);
86 B = GG(B, C, D, A, X[12], 13);
87 A = GG(A, B, C, D, X[1], 3);
88 D = GG(D, A, B, C, X[5], 5);
89 C = GG(C, D, A, B, X[9], 9);
90 B = GG(B, C, D, A, X[13], 13);
91 A = GG(A, B, C, D, X[2], 3);
92 D = GG(D, A, B, C, X[6], 5);
93 C = GG(C, D, A, B, X[10], 9);
94 B = GG(B, C, D, A, X[14], 13);
95 A = GG(A, B, C, D, X[3], 3);
96 D = GG(D, A, B, C, X[7], 5);
97 C = GG(C, D, A, B, X[11], 9);
98 B = GG(B, C, D, A, X[15], 13);
99
100 A = HH(A, B, C, D, X[0], 3);
101 D = HH(D, A, B, C, X[8], 9);
102 C = HH(C, D, A, B, X[4], 11);
103 B = HH(B, C, D, A, X[12], 15);
104 A = HH(A, B, C, D, X[2], 3);
105 D = HH(D, A, B, C, X[10], 9);
106 C = HH(C, D, A, B, X[6], 11);
107 B = HH(B, C, D, A, X[14], 15);
108 A = HH(A, B, C, D, X[1], 3);
109 D = HH(D, A, B, C, X[9], 9);
110 C = HH(C, D, A, B, X[5], 11);
111 B = HH(B, C, D, A, X[13], 15);
112 A = HH(A, B, C, D, X[3], 3);
113 D = HH(D, A, B, C, X[11], 9);
114 C = HH(C, D, A, B, X[7], 11);
115 B = HH(B, C, D, A, X[15], 15);
116
117 context[0] += A;
118 context[1] += B;
119 context[2] += C;
120 context[3] += D;
121
122 context[0] &= 0xFFFFFFFF;
123 context[1] &= 0xFFFFFFFF;
124 context[2] &= 0xFFFFFFFF;
125 context[3] &= 0xFFFFFFFF;
126}
127
132static void engineReset()
133{
134 // initial values of MD4 i.e. A, B, C, D
135 // as per rfc-1320; they are low-order byte first
136 context[0] = 0x67452301;
137 context[1] = 0xEFCDAB89;
138 context[2] = 0x98BADCFE;
139 context[3] = 0x10325476;
140}
141
145unsigned char *MD4(unsigned char *message, int len, unsigned char *cipher)
146{
147 union
148 {
149 unsigned char ucbuff[128];
150 unsigned int uibuff[128 / sizeof(unsigned int)];
151 } buffer;
152 unsigned int b = len * 8;
153
154 engineReset();
155
156 while (len > 64) {
157 memcpy(buffer.ucbuff, message, 64);
158 transform(buffer.ucbuff);
159 message += 64;
160 len -= 64;
161 }
162
163 memset(buffer.ucbuff, 0, 128);
164 memcpy(buffer.ucbuff, message, len);
165 buffer.ucbuff[len] = 0x80;
166
167 if (len < 56) {
168 buffer.uibuff[56 / sizeof(unsigned int)] = b;
169 transform(buffer.ucbuff);
170 } else {
171 buffer.uibuff[120 / sizeof(unsigned int)] = b;
172 transform(buffer.ucbuff);
173 transform(&buffer.ucbuff[64]);
174 }
175
176 *((unsigned int *)&cipher[0]) = context[0];
177 *((unsigned int *)&cipher[4]) = context[1];
178 *((unsigned int *)&cipher[8]) = context[2];
179 *((unsigned int *)&cipher[12]) = context[3];
180
181 return (unsigned char *)cipher;
182}