md4.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/*
10 * Unix SMB/Netbios implementation.
11 * Version 1.9.
12 * a implementation of MD4 designed for use in the SMB authentication protocol
13 * Copyright (C) Andrew Tridgell 1997
14 */
15
16/*
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31
32#include "squid.h"
33#include <string.h>
34#include "smblib/md4.h"
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
41typedef unsigned int uint32;
42
43static uint32 A, B, C, D;
44
45static uint32
47{
48 return (X & Y) | ((~X) & Z);
49}
50
51static uint32
53{
54 return (X & Y) | (X & Z) | (Y & Z);
55}
56
57static uint32
59{
60 return X ^ Y ^ Z;
61}
62
63static uint32
64lshift(uint32 x, int s)
65{
66 x &= 0xFFFFFFFF;
67 return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
68}
69
70#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
71#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s)
72#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
73
74/* this applies md4 to 64 byte chunks */
75static 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
151 for (j = 0; j < 16; j++)
152 X[j] = 0;
153}
154
155static void
156copy64(uint32 * M, unsigned char *in)
157{
158 int i;
159
160 for (i = 0; i < 16; i++)
161 M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
162 (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
163}
164
165static void
166copy4(unsigned char *out, uint32 x)
167{
168 out[0] = x & 0xFF;
169 out[1] = (x >> 8) & 0xFF;
170 out[2] = (x >> 16) & 0xFF;
171 out[3] = (x >> 24) & 0xFF;
172}
173
174/* produce a md4 message digest from data of length n bytes */
175void
176mdfour(unsigned char *out, unsigned char *in, int n)
177{
178 unsigned char buf[128];
179 uint32 M[16];
180 uint32 b = n * 8;
181 int i;
182
183 A = 0x67452301;
184 B = 0xefcdab89;
185 C = 0x98badcfe;
186 D = 0x10325476;
187
188 while (n > 64) {
189 copy64(M, in);
190 mdfour64(M);
191 in += 64;
192 n -= 64;
193 }
194
195 for (i = 0; i < 128; i++)
196 buf[i] = 0;
197 memcpy(buf, in, n);
198 buf[n] = 0x80;
199
200 if (n <= 55) {
201 copy4(buf + 56, b);
202 copy64(M, buf);
203 mdfour64(M);
204 } else {
205 copy4(buf + 120, b);
206 copy64(M, buf);
207 mdfour64(M);
208 copy64(M, buf + 64);
209 mdfour64(M);
210 }
211
212 for (i = 0; i < 128; i++)
213 buf[i] = 0;
214 copy64(M, buf);
215
216 copy4(out, A);
217 copy4(out + 4, B);
218 copy4(out + 8, C);
219 copy4(out + 12, D);
220
221 A = B = C = D = 0;
222}
223
unsigned int uint32
Definition: md4.c:41
#define ROUND3(a, b, c, d, k, s)
Definition: md4.c:72
static void copy4(unsigned char *out, uint32 x)
Definition: md4.c:166
static uint32 H(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:58
static uint32 G(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:52
static uint32 C
Definition: md4.c:43
#define ROUND2(a, b, c, d, k, s)
Definition: md4.c:71
static void mdfour64(uint32 *M)
Definition: md4.c:76
static uint32 A
Definition: md4.c:43
static void copy64(uint32 *M, unsigned char *in)
Definition: md4.c:156
static uint32 D
Definition: md4.c:43
#define ROUND1(a, b, c, d, k, s)
Definition: md4.c:70
static uint32 F(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:46
static uint32 lshift(uint32 x, int s)
Definition: md4.c:64
void mdfour(unsigned char *out, unsigned char *in, int n)
Definition: md4.c:176
static uint32 B
Definition: md4.c:43

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors