2 Unix SMB/CIFS implementation.
3 a implementation of MD4 designed for use in the SMB authentication protocol
4 Copyright (C) Andrew Tridgell 1997-1998.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "../lib/crypto/md4.h"
23 /* NOTE: This code makes no attempt to be fast!
25 It assumes that a int is at least 32 bits long
32 static uint32_t F(uint32_t X
, uint32_t Y
, uint32_t Z
)
34 return (X
&Y
) | ((~X
)&Z
);
37 static uint32_t G(uint32_t X
, uint32_t Y
, uint32_t Z
)
39 return (X
&Y
) | (X
&Z
) | (Y
&Z
);
42 static uint32_t H(uint32_t X
, uint32_t Y
, uint32_t Z
)
47 static uint32_t lshift(uint32_t 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] + (uint32_t)0x5A827999,s)
55 #define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32_t)0x6ED9EBA1,s)
57 /* this applies md4 to 64 byte chunks */
58 static void mdfour64(struct mdfour_state
*s
, uint32_t *M
)
61 uint32_t AA
, BB
, CC
, DD
;
67 AA
= s
->A
; BB
= s
->B
; CC
= s
->C
; DD
= s
->D
;
69 ROUND1(s
->A
,s
->B
,s
->C
,s
->D
, 0, 3); ROUND1(s
->D
,s
->A
,s
->B
,s
->C
, 1, 7);
70 ROUND1(s
->C
,s
->D
,s
->A
,s
->B
, 2, 11); ROUND1(s
->B
,s
->C
,s
->D
,s
->A
, 3, 19);
71 ROUND1(s
->A
,s
->B
,s
->C
,s
->D
, 4, 3); ROUND1(s
->D
,s
->A
,s
->B
,s
->C
, 5, 7);
72 ROUND1(s
->C
,s
->D
,s
->A
,s
->B
, 6, 11); ROUND1(s
->B
,s
->C
,s
->D
,s
->A
, 7, 19);
73 ROUND1(s
->A
,s
->B
,s
->C
,s
->D
, 8, 3); ROUND1(s
->D
,s
->A
,s
->B
,s
->C
, 9, 7);
74 ROUND1(s
->C
,s
->D
,s
->A
,s
->B
, 10, 11); ROUND1(s
->B
,s
->C
,s
->D
,s
->A
, 11, 19);
75 ROUND1(s
->A
,s
->B
,s
->C
,s
->D
, 12, 3); ROUND1(s
->D
,s
->A
,s
->B
,s
->C
, 13, 7);
76 ROUND1(s
->C
,s
->D
,s
->A
,s
->B
, 14, 11); ROUND1(s
->B
,s
->C
,s
->D
,s
->A
, 15, 19);
78 ROUND2(s
->A
,s
->B
,s
->C
,s
->D
, 0, 3); ROUND2(s
->D
,s
->A
,s
->B
,s
->C
, 4, 5);
79 ROUND2(s
->C
,s
->D
,s
->A
,s
->B
, 8, 9); ROUND2(s
->B
,s
->C
,s
->D
,s
->A
, 12, 13);
80 ROUND2(s
->A
,s
->B
,s
->C
,s
->D
, 1, 3); ROUND2(s
->D
,s
->A
,s
->B
,s
->C
, 5, 5);
81 ROUND2(s
->C
,s
->D
,s
->A
,s
->B
, 9, 9); ROUND2(s
->B
,s
->C
,s
->D
,s
->A
, 13, 13);
82 ROUND2(s
->A
,s
->B
,s
->C
,s
->D
, 2, 3); ROUND2(s
->D
,s
->A
,s
->B
,s
->C
, 6, 5);
83 ROUND2(s
->C
,s
->D
,s
->A
,s
->B
, 10, 9); ROUND2(s
->B
,s
->C
,s
->D
,s
->A
, 14, 13);
84 ROUND2(s
->A
,s
->B
,s
->C
,s
->D
, 3, 3); ROUND2(s
->D
,s
->A
,s
->B
,s
->C
, 7, 5);
85 ROUND2(s
->C
,s
->D
,s
->A
,s
->B
, 11, 9); ROUND2(s
->B
,s
->C
,s
->D
,s
->A
, 15, 13);
87 ROUND3(s
->A
,s
->B
,s
->C
,s
->D
, 0, 3); ROUND3(s
->D
,s
->A
,s
->B
,s
->C
, 8, 9);
88 ROUND3(s
->C
,s
->D
,s
->A
,s
->B
, 4, 11); ROUND3(s
->B
,s
->C
,s
->D
,s
->A
, 12, 15);
89 ROUND3(s
->A
,s
->B
,s
->C
,s
->D
, 2, 3); ROUND3(s
->D
,s
->A
,s
->B
,s
->C
, 10, 9);
90 ROUND3(s
->C
,s
->D
,s
->A
,s
->B
, 6, 11); ROUND3(s
->B
,s
->C
,s
->D
,s
->A
, 14, 15);
91 ROUND3(s
->A
,s
->B
,s
->C
,s
->D
, 1, 3); ROUND3(s
->D
,s
->A
,s
->B
,s
->C
, 9, 9);
92 ROUND3(s
->C
,s
->D
,s
->A
,s
->B
, 5, 11); ROUND3(s
->B
,s
->C
,s
->D
,s
->A
, 13, 15);
93 ROUND3(s
->A
,s
->B
,s
->C
,s
->D
, 3, 3); ROUND3(s
->D
,s
->A
,s
->B
,s
->C
, 11, 9);
94 ROUND3(s
->C
,s
->D
,s
->A
,s
->B
, 7, 11); ROUND3(s
->B
,s
->C
,s
->D
,s
->A
, 15, 15);
110 static void copy64(uint32_t *M
, const uint8_t *in
)
115 M
[i
] = (in
[i
*4+3]<<24) | (in
[i
*4+2]<<16) |
116 (in
[i
*4+1]<<8) | (in
[i
*4+0]<<0);
119 static void copy4(uint8_t *out
, uint32_t x
)
122 out
[1] = (x
>>8)&0xFF;
123 out
[2] = (x
>>16)&0xFF;
124 out
[3] = (x
>>24)&0xFF;
128 * produce a md4 message digest from data of length n bytes
130 _PUBLIC_
void mdfour(uint8_t *out
, const uint8_t *in
, int n
)
136 struct mdfour_state state
;
138 state
.A
= 0x67452301;
139 state
.B
= 0xefcdab89;
140 state
.C
= 0x98badcfe;
141 state
.D
= 0x10325476;
172 copy4(out
+4, state
.B
);
173 copy4(out
+8, state
.C
);
174 copy4(out
+12, state
.D
);