2 Unix SMB/Netbios implementation.
4 a implementation of MD4 designed for use in the SMB authentication protocol
5 Copyright (C) Andrew Tridgell 1997-1998.
6 Modified by Steve French (sfrench@us.ibm.com) 2002-2003
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include <linux/module.h>
24 #include "cifsencrypt.h"
26 /* NOTE: This code makes no attempt to be fast! */
29 F(__u32 X
, __u32 Y
, __u32 Z
)
31 return (X
& Y
) | ((~X
) & Z
);
35 G(__u32 X
, __u32 Y
, __u32 Z
)
37 return (X
& Y
) | (X
& Z
) | (Y
& Z
);
41 H(__u32 X
, __u32 Y
, __u32 Z
)
47 lshift(__u32 x
, int s
)
50 return ((x
<< s
) & 0xFFFFFFFF) | (x
>> (32 - s
));
53 #define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
54 #define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
55 #define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
57 /* this applies md4 to 64 byte chunks */
59 mdfour64(__u32
* M
, __u32
* A
, __u32
*B
, __u32
* C
, __u32
*D
)
66 for (j
= 0; j
< 16; j
++)
74 ROUND1(A
, B
, C
, D
, 0, 3);
75 ROUND1(D
, A
, B
, C
, 1, 7);
76 ROUND1(C
, D
, A
, B
, 2, 11);
77 ROUND1(B
, C
, D
, A
, 3, 19);
78 ROUND1(A
, B
, C
, D
, 4, 3);
79 ROUND1(D
, A
, B
, C
, 5, 7);
80 ROUND1(C
, D
, A
, B
, 6, 11);
81 ROUND1(B
, C
, D
, A
, 7, 19);
82 ROUND1(A
, B
, C
, D
, 8, 3);
83 ROUND1(D
, A
, B
, C
, 9, 7);
84 ROUND1(C
, D
, A
, B
, 10, 11);
85 ROUND1(B
, C
, D
, A
, 11, 19);
86 ROUND1(A
, B
, C
, D
, 12, 3);
87 ROUND1(D
, A
, B
, C
, 13, 7);
88 ROUND1(C
, D
, A
, B
, 14, 11);
89 ROUND1(B
, C
, D
, A
, 15, 19);
91 ROUND2(A
, B
, C
, D
, 0, 3);
92 ROUND2(D
, A
, B
, C
, 4, 5);
93 ROUND2(C
, D
, A
, B
, 8, 9);
94 ROUND2(B
, C
, D
, A
, 12, 13);
95 ROUND2(A
, B
, C
, D
, 1, 3);
96 ROUND2(D
, A
, B
, C
, 5, 5);
97 ROUND2(C
, D
, A
, B
, 9, 9);
98 ROUND2(B
, C
, D
, A
, 13, 13);
99 ROUND2(A
, B
, C
, D
, 2, 3);
100 ROUND2(D
, A
, B
, C
, 6, 5);
101 ROUND2(C
, D
, A
, B
, 10, 9);
102 ROUND2(B
, C
, D
, A
, 14, 13);
103 ROUND2(A
, B
, C
, D
, 3, 3);
104 ROUND2(D
, A
, B
, C
, 7, 5);
105 ROUND2(C
, D
, A
, B
, 11, 9);
106 ROUND2(B
, C
, D
, A
, 15, 13);
108 ROUND3(A
, B
, C
, D
, 0, 3);
109 ROUND3(D
, A
, B
, C
, 8, 9);
110 ROUND3(C
, D
, A
, B
, 4, 11);
111 ROUND3(B
, C
, D
, A
, 12, 15);
112 ROUND3(A
, B
, C
, D
, 2, 3);
113 ROUND3(D
, A
, B
, C
, 10, 9);
114 ROUND3(C
, D
, A
, B
, 6, 11);
115 ROUND3(B
, C
, D
, A
, 14, 15);
116 ROUND3(A
, B
, C
, D
, 1, 3);
117 ROUND3(D
, A
, B
, C
, 9, 9);
118 ROUND3(C
, D
, A
, B
, 5, 11);
119 ROUND3(B
, C
, D
, A
, 13, 15);
120 ROUND3(A
, B
, C
, D
, 3, 3);
121 ROUND3(D
, A
, B
, C
, 11, 9);
122 ROUND3(C
, D
, A
, B
, 7, 11);
123 ROUND3(B
, C
, D
, A
, 15, 15);
135 for (j
= 0; j
< 16; j
++)
140 copy64(__u32
* M
, unsigned char *in
)
144 for (i
= 0; i
< 16; i
++)
145 M
[i
] = (in
[i
* 4 + 3] << 24) | (in
[i
* 4 + 2] << 16) |
146 (in
[i
* 4 + 1] << 8) | (in
[i
* 4 + 0] << 0);
150 copy4(unsigned char *out
, __u32 x
)
153 out
[1] = (x
>> 8) & 0xFF;
154 out
[2] = (x
>> 16) & 0xFF;
155 out
[3] = (x
>> 24) & 0xFF;
158 /* produce a md4 message digest from data of length n bytes */
160 mdfour(unsigned char *out
, unsigned char *in
, int n
)
162 unsigned char buf
[128];
166 __u32 A
= 0x67452301;
167 __u32 B
= 0xefcdab89;
168 __u32 C
= 0x98badcfe;
169 __u32 D
= 0x10325476;
173 mdfour64(M
, &A
, &B
, &C
, &D
);
178 for (i
= 0; i
< 128; i
++)
186 mdfour64(M
, &A
, &B
, &C
, &D
);
190 mdfour64(M
, &A
, &B
, &C
, &D
);
192 mdfour64(M
, &A
, &B
, &C
, &D
);
195 for (i
= 0; i
< 128; i
++)