OpenVAS Scanner 23.32.3
md4.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 1997-1998 Andrew Tridgell
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
13
14#include "md4.h"
15
16#include <stdint.h>
17#include <string.h>
18
19#ifndef uint32
20#define uint32 uint32_t
21#endif
22
23/* NOTE: This code makes no attempt to be fast!
24
25 It assumes that a int is at least 32 bits long
26*/
27
28static uint32 A, B, C, D;
29
30static uint32
32{
33 return (X & Y) | ((~X) & Z);
34}
35
36static uint32
38{
39 return (X & Y) | (X & Z) | (Y & Z);
40}
41
42static uint32
44{
45 return X ^ Y ^ Z;
46}
47
48static uint32
49lshift (uint32 x, int s)
50{
51 x &= 0xFFFFFFFF;
52 return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
53}
54
55#define ROUND1(a, b, c, d, k, s) a = lshift (a + F (b, c, d) + X[k], s)
56#define ROUND2(a, b, c, d, k, s) \
57 a = lshift (a + G (b, c, d) + X[k] + (uint32) 0x5A827999, s)
58#define ROUND3(a, b, c, d, k, s) \
59 a = lshift (a + H (b, c, d) + X[k] + (uint32) 0x6ED9EBA1, s)
60
61/* this applies md4 to 64 byte chunks */
62static void
64{
65 int j;
66 uint32 AA, BB, CC, DD;
67 uint32 X[16];
68
69 for (j = 0; j < 16; j++)
70 X[j] = M[j];
71
72 AA = A;
73 BB = B;
74 CC = C;
75 DD = D;
76
77 ROUND1 (A, B, C, D, 0, 3);
78 ROUND1 (D, A, B, C, 1, 7);
79 ROUND1 (C, D, A, B, 2, 11);
80 ROUND1 (B, C, D, A, 3, 19);
81 ROUND1 (A, B, C, D, 4, 3);
82 ROUND1 (D, A, B, C, 5, 7);
83 ROUND1 (C, D, A, B, 6, 11);
84 ROUND1 (B, C, D, A, 7, 19);
85 ROUND1 (A, B, C, D, 8, 3);
86 ROUND1 (D, A, B, C, 9, 7);
87 ROUND1 (C, D, A, B, 10, 11);
88 ROUND1 (B, C, D, A, 11, 19);
89 ROUND1 (A, B, C, D, 12, 3);
90 ROUND1 (D, A, B, C, 13, 7);
91 ROUND1 (C, D, A, B, 14, 11);
92 ROUND1 (B, C, D, A, 15, 19);
93
94 ROUND2 (A, B, C, D, 0, 3);
95 ROUND2 (D, A, B, C, 4, 5);
96 ROUND2 (C, D, A, B, 8, 9);
97 ROUND2 (B, C, D, A, 12, 13);
98 ROUND2 (A, B, C, D, 1, 3);
99 ROUND2 (D, A, B, C, 5, 5);
100 ROUND2 (C, D, A, B, 9, 9);
101 ROUND2 (B, C, D, A, 13, 13);
102 ROUND2 (A, B, C, D, 2, 3);
103 ROUND2 (D, A, B, C, 6, 5);
104 ROUND2 (C, D, A, B, 10, 9);
105 ROUND2 (B, C, D, A, 14, 13);
106 ROUND2 (A, B, C, D, 3, 3);
107 ROUND2 (D, A, B, C, 7, 5);
108 ROUND2 (C, D, A, B, 11, 9);
109 ROUND2 (B, C, D, A, 15, 13);
110
111 ROUND3 (A, B, C, D, 0, 3);
112 ROUND3 (D, A, B, C, 8, 9);
113 ROUND3 (C, D, A, B, 4, 11);
114 ROUND3 (B, C, D, A, 12, 15);
115 ROUND3 (A, B, C, D, 2, 3);
116 ROUND3 (D, A, B, C, 10, 9);
117 ROUND3 (C, D, A, B, 6, 11);
118 ROUND3 (B, C, D, A, 14, 15);
119 ROUND3 (A, B, C, D, 1, 3);
120 ROUND3 (D, A, B, C, 9, 9);
121 ROUND3 (C, D, A, B, 5, 11);
122 ROUND3 (B, C, D, A, 13, 15);
123 ROUND3 (A, B, C, D, 3, 3);
124 ROUND3 (D, A, B, C, 11, 9);
125 ROUND3 (C, D, A, B, 7, 11);
126 ROUND3 (B, C, D, A, 15, 15);
127
128 A += AA;
129 B += BB;
130 C += CC;
131 D += DD;
132
133 A &= 0xFFFFFFFF;
134 B &= 0xFFFFFFFF;
135 C &= 0xFFFFFFFF;
136 D &= 0xFFFFFFFF;
137
138 for (size_t i = 0; i < 16; i++)
139 {
140 *(volatile char *) (X + i) = '\0';
141 }
142}
143
144static void
145copy64_ntlmssp (uint32 *M, const unsigned char *in)
146{
147 int i;
148
149 for (i = 0; i < 16; i++)
150 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | (in[i * 4 + 1] << 8)
151 | (in[i * 4 + 0] << 0);
152}
153
154static void
155copy4_ntlmssp (unsigned char *out, uint32 x)
156{
157 out[0] = x & 0xFF;
158 out[1] = (x >> 8) & 0xFF;
159 out[2] = (x >> 16) & 0xFF;
160 out[3] = (x >> 24) & 0xFF;
161}
162
163/* produce a md4 message digest from data of length n bytes */
164void
165mdfour_ntlmssp (unsigned char *out, const unsigned char *in, int n)
166{
167 unsigned char buf[128];
168 uint32 M[16];
169 uint32 b = n * 8;
170 int i;
171
172 A = 0x67452301;
173 B = 0xefcdab89;
174 C = 0x98badcfe;
175 D = 0x10325476;
176
177 while (n > 64)
178 {
179 copy64_ntlmssp (M, in);
181 in += 64;
182 n -= 64;
183 }
184
185 for (i = 0; i < 128; i++)
186 buf[i] = 0;
187 memcpy (buf, in, n);
188 buf[n] = 0x80;
189
190 if (n <= 55)
191 {
192 copy4_ntlmssp (buf + 56, b);
193 copy64_ntlmssp (M, buf);
195 }
196 else
197 {
198 copy4_ntlmssp (buf + 120, b);
199 copy64_ntlmssp (M, buf);
201 copy64_ntlmssp (M, buf + 64);
203 }
204
205 for (i = 0; i < 128; i++)
206 buf[i] = 0;
207 copy64_ntlmssp (M, buf);
208
209 copy4_ntlmssp (out, A);
210 copy4_ntlmssp (out + 4, B);
211 copy4_ntlmssp (out + 8, C);
212 copy4_ntlmssp (out + 12, D);
213
214 A = B = C = D = 0;
215}
#define uint32
Definition genrand.c:40
#define ROUND3(a, b, c, d, k, s)
Definition md4.c:58
static uint32 H(uint32 X, uint32 Y, uint32 Z)
Definition md4.c:43
static uint32 G(uint32 X, uint32 Y, uint32 Z)
Definition md4.c:37
static void copy4_ntlmssp(unsigned char *out, uint32 x)
Definition md4.c:155
static uint32 C
Definition md4.c:28
#define ROUND2(a, b, c, d, k, s)
Definition md4.c:56
static void copy64_ntlmssp(uint32 *M, const unsigned char *in)
Definition md4.c:145
void mdfour_ntlmssp(unsigned char *out, const unsigned char *in, int n)
Definition md4.c:165
static uint32 A
Definition md4.c:28
static uint32 D
Definition md4.c:28
#define ROUND1(a, b, c, d, k, s)
Definition md4.c:55
static uint32 F(uint32 X, uint32 Y, uint32 Z)
Definition md4.c:31
static uint32 lshift(uint32 x, int s)
Definition md4.c:49
static uint32 B
Definition md4.c:28
static void mdfour64_ntlmssp(uint32 *M)
Definition md4.c:63
Unix SMB/CIFS implementation.