]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/smblib/md4.c
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / lib / smblib / md4.c
CommitLineData
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
32typedef unsigned int uint32;
33
34static uint32 A, B, C, D;
35
36static uint32
37F(uint32 X, uint32 Y, uint32 Z)
38{
39 return (X & Y) | ((~X) & Z);
40}
41
42static uint32
43G(uint32 X, uint32 Y, uint32 Z)
44{
45 return (X & Y) | (X & Z) | (Y & Z);
46}
47
48static uint32
49H(uint32 X, uint32 Y, uint32 Z)
50{
51 return X ^ Y ^ Z;
52}
53
54static uint32
55lshift(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 */
66static void
67mdfour64(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
146static void
147copy64(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
156static void
157copy4(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 */
166void
167mdfour(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}