]>
Commit | Line | Data |
---|---|---|
f7f3304a | 1 | #include "squid.h" |
75072239 | 2 | |
26ac0430 | 3 | /* |
94439e4e | 4 | * Unix SMB/Netbios implementation. |
5 | * Version 1.9. | |
6 | * a implementation of MD4 designed for use in the SMB authentication protocol | |
7 | * Copyright (C) Andrew Tridgell 1997 | |
26ac0430 | 8 | * |
94439e4e | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the License, or | |
12 | * (at your option) any later version. | |
26ac0430 | 13 | * |
94439e4e | 14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
26ac0430 | 18 | * |
94439e4e | 19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 | */ | |
23 | ||
5b4834ee | 24 | #include <string.h> |
7c16470c | 25 | #include "smblib/md4.h" |
94439e4e | 26 | |
26ac0430 AJ |
27 | /* NOTE: This code makes no attempt to be fast! |
28 | * | |
94439e4e | 29 | * It assumes that a int is at least 32 bits long |
30 | */ | |
31 | ||
32 | typedef unsigned int uint32; | |
33 | ||
34 | static uint32 A, B, C, D; | |
35 | ||
36 | static uint32 | |
37 | F(uint32 X, uint32 Y, uint32 Z) | |
38 | { | |
39 | return (X & Y) | ((~X) & Z); | |
40 | } | |
41 | ||
42 | static uint32 | |
43 | G(uint32 X, uint32 Y, uint32 Z) | |
44 | { | |
45 | return (X & Y) | (X & Z) | (Y & Z); | |
46 | } | |
47 | ||
48 | static uint32 | |
49 | H(uint32 X, uint32 Y, uint32 Z) | |
50 | { | |
51 | return X ^ Y ^ Z; | |
52 | } | |
53 | ||
54 | static uint32 | |
55 | lshift(uint32 x, int s) | |
56 | { | |
57 | x &= 0xFFFFFFFF; | |
58 | return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); | |
59 | } | |
60 | ||
61 | #define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) | |
62 | #define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) | |
63 | #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) | |
64 | ||
65 | /* this applies md4 to 64 byte chunks */ | |
66 | static void | |
67 | mdfour64(uint32 * M) | |
68 | { | |
69 | int j; | |
70 | uint32 AA, BB, CC, DD; | |
71 | uint32 X[16]; | |
72 | ||
73 | for (j = 0; j < 16; j++) | |
26ac0430 | 74 | X[j] = M[j]; |
94439e4e | 75 | |
76 | AA = A; | |
77 | BB = B; | |
78 | CC = C; | |
79 | DD = D; | |
80 | ||
81 | ROUND1(A, B, C, D, 0, 3); | |
82 | ROUND1(D, A, B, C, 1, 7); | |
83 | ROUND1(C, D, A, B, 2, 11); | |
84 | ROUND1(B, C, D, A, 3, 19); | |
85 | ROUND1(A, B, C, D, 4, 3); | |
86 | ROUND1(D, A, B, C, 5, 7); | |
87 | ROUND1(C, D, A, B, 6, 11); | |
88 | ROUND1(B, C, D, A, 7, 19); | |
89 | ROUND1(A, B, C, D, 8, 3); | |
90 | ROUND1(D, A, B, C, 9, 7); | |
91 | ROUND1(C, D, A, B, 10, 11); | |
92 | ROUND1(B, C, D, A, 11, 19); | |
93 | ROUND1(A, B, C, D, 12, 3); | |
94 | ROUND1(D, A, B, C, 13, 7); | |
95 | ROUND1(C, D, A, B, 14, 11); | |
96 | ROUND1(B, C, D, A, 15, 19); | |
97 | ||
98 | ROUND2(A, B, C, D, 0, 3); | |
99 | ROUND2(D, A, B, C, 4, 5); | |
100 | ROUND2(C, D, A, B, 8, 9); | |
101 | ROUND2(B, C, D, A, 12, 13); | |
102 | ROUND2(A, B, C, D, 1, 3); | |
103 | ROUND2(D, A, B, C, 5, 5); | |
104 | ROUND2(C, D, A, B, 9, 9); | |
105 | ROUND2(B, C, D, A, 13, 13); | |
106 | ROUND2(A, B, C, D, 2, 3); | |
107 | ROUND2(D, A, B, C, 6, 5); | |
108 | ROUND2(C, D, A, B, 10, 9); | |
109 | ROUND2(B, C, D, A, 14, 13); | |
110 | ROUND2(A, B, C, D, 3, 3); | |
111 | ROUND2(D, A, B, C, 7, 5); | |
112 | ROUND2(C, D, A, B, 11, 9); | |
113 | ROUND2(B, C, D, A, 15, 13); | |
114 | ||
115 | ROUND3(A, B, C, D, 0, 3); | |
116 | ROUND3(D, A, B, C, 8, 9); | |
117 | ROUND3(C, D, A, B, 4, 11); | |
118 | ROUND3(B, C, D, A, 12, 15); | |
119 | ROUND3(A, B, C, D, 2, 3); | |
120 | ROUND3(D, A, B, C, 10, 9); | |
121 | ROUND3(C, D, A, B, 6, 11); | |
122 | ROUND3(B, C, D, A, 14, 15); | |
123 | ROUND3(A, B, C, D, 1, 3); | |
124 | ROUND3(D, A, B, C, 9, 9); | |
125 | ROUND3(C, D, A, B, 5, 11); | |
126 | ROUND3(B, C, D, A, 13, 15); | |
127 | ROUND3(A, B, C, D, 3, 3); | |
128 | ROUND3(D, A, B, C, 11, 9); | |
129 | ROUND3(C, D, A, B, 7, 11); | |
130 | ROUND3(B, C, D, A, 15, 15); | |
131 | ||
132 | A += AA; | |
133 | B += BB; | |
134 | C += CC; | |
135 | D += DD; | |
136 | ||
137 | A &= 0xFFFFFFFF; | |
138 | B &= 0xFFFFFFFF; | |
139 | C &= 0xFFFFFFFF; | |
140 | D &= 0xFFFFFFFF; | |
141 | ||
142 | for (j = 0; j < 16; j++) | |
26ac0430 | 143 | X[j] = 0; |
94439e4e | 144 | } |
145 | ||
146 | static void | |
147 | copy64(uint32 * M, unsigned char *in) | |
148 | { | |
149 | int i; | |
150 | ||
151 | for (i = 0; i < 16; i++) | |
26ac0430 AJ |
152 | M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | |
153 | (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0); | |
94439e4e | 154 | } |
155 | ||
156 | static void | |
157 | copy4(unsigned char *out, uint32 x) | |
158 | { | |
159 | out[0] = x & 0xFF; | |
160 | out[1] = (x >> 8) & 0xFF; | |
161 | out[2] = (x >> 16) & 0xFF; | |
162 | out[3] = (x >> 24) & 0xFF; | |
163 | } | |
164 | ||
165 | /* produce a md4 message digest from data of length n bytes */ | |
166 | void | |
167 | mdfour(unsigned char *out, unsigned char *in, int n) | |
168 | { | |
169 | unsigned char buf[128]; | |
170 | uint32 M[16]; | |
171 | uint32 b = n * 8; | |
172 | int i; | |
173 | ||
174 | A = 0x67452301; | |
175 | B = 0xefcdab89; | |
176 | C = 0x98badcfe; | |
177 | D = 0x10325476; | |
178 | ||
179 | while (n > 64) { | |
26ac0430 AJ |
180 | copy64(M, in); |
181 | mdfour64(M); | |
182 | in += 64; | |
183 | n -= 64; | |
94439e4e | 184 | } |
185 | ||
186 | for (i = 0; i < 128; i++) | |
26ac0430 | 187 | buf[i] = 0; |
94439e4e | 188 | memcpy(buf, in, n); |
189 | buf[n] = 0x80; | |
190 | ||
191 | if (n <= 55) { | |
26ac0430 AJ |
192 | copy4(buf + 56, b); |
193 | copy64(M, buf); | |
194 | mdfour64(M); | |
94439e4e | 195 | } else { |
26ac0430 AJ |
196 | copy4(buf + 120, b); |
197 | copy64(M, buf); | |
198 | mdfour64(M); | |
199 | copy64(M, buf + 64); | |
200 | mdfour64(M); | |
94439e4e | 201 | } |
202 | ||
203 | for (i = 0; i < 128; i++) | |
26ac0430 | 204 | buf[i] = 0; |
94439e4e | 205 | copy64(M, buf); |
206 | ||
207 | copy4(out, A); | |
208 | copy4(out + 4, B); | |
209 | copy4(out + 8, C); | |
210 | copy4(out + 12, D); | |
211 | ||
212 | A = B = C = D = 0; | |
213 | } |