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 
41 typedef unsigned int uint32;
42 
43 static uint32 A, B, C, D;
44 
45 static uint32
47 {
48  return (X & Y) | ((~X) & Z);
49 }
50 
51 static uint32
53 {
54  return (X & Y) | (X & Z) | (Y & Z);
55 }
56 
57 static uint32
59 {
60  return X ^ Y ^ Z;
61 }
62 
63 static uint32
64 lshift(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 */
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 
151  for (j = 0; j < 16; j++)
152  X[j] = 0;
153 }
154 
155 static void
156 copy64(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 
165 static void
166 copy4(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 */
175 void
176 mdfour(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 
static void copy64(uint32 *M, unsigned char *in)
Definition: md4.c:156
static uint32 G(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:52
static uint32 F(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:46
#define ROUND2(a, b, c, d, k, s)
Definition: md4.c:71
#define ROUND3(a, b, c, d, k, s)
Definition: md4.c:72
void mdfour(unsigned char *out, unsigned char *in, int n)
Definition: md4.c:176
unsigned int uint32
Definition: md4.c:41
static uint32 A
Definition: md4.c:43
static uint32 lshift(uint32 x, int s)
Definition: md4.c:64
static uint32 C
Definition: md4.c:43
static void mdfour64(uint32 *M)
Definition: md4.c:76
static uint32 B
Definition: md4.c:43
static void copy4(unsigned char *out, uint32 x)
Definition: md4.c:166
static uint32 D
Definition: md4.c:43
static uint32 H(uint32 X, uint32 Y, uint32 Z)
Definition: md4.c:58
#define ROUND1(a, b, c, d, k, s)
Definition: md4.c:70

 

Introduction

Documentation

Support

Miscellaneous