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