1 /*
2 * Copyright (C) 1999 Descolada (dyn1-tnt9-237.chicago.il.ameritech.net)
3 * Copyright (C) 1999,2000 Ross Combs (rocombs@cs.nmsu.edu)
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #include "common/setup_before.h"
20 #include <stdio.h>
21 #ifdef HAVE_STDDEF_H
22 # include <stddef.h>
23 #else
24 # ifndef NULL
25 # define NULL ((void *)0)
26 # endif
27 #endif
28 #ifdef STDC_HEADERS
29 # include <stdlib.h>
30 #endif
31 #ifdef HAVE_STRING_H
32 # include <string.h>
33 #else
34 # ifdef HAVE_STRINGS_H
35 # include <strings.h>
36 # endif
37 #endif
38 #include "compat/uint.h"
39 #include "common/introtate.h"
40 #include "common/eventlog.h"
41 #include "common/bnethash.h"
42 #include "common/setup_after.h"
43
44
45 static void hash_init(t_hash * hash);
46 static void do_hash(t_hash * hash, t_uint32 * tmp);
47 static void hash_set_16(t_uint32 * dst, unsigned char const * src, unsigned int count);
48
49
hash_init(t_hash * hash)50 static void hash_init(t_hash * hash)
51 {
52 (*hash)[0] = 0x67452301;
53 (*hash)[1] = 0xefcdab89;
54 (*hash)[2] = 0x98badcfe;
55 (*hash)[3] = 0x10325476;
56 (*hash)[4] = 0xc3d2e1f0;
57 }
58
59
do_hash(t_hash * hash,t_uint32 * tmp)60 static void do_hash(t_hash * hash, t_uint32 * tmp)
61 {
62 unsigned int i;
63 t_uint32 a,b,c,d,e,g;
64
65 for (i=0; i<64; i++)
66 tmp[i+16] = ROTL32(1,tmp[i] ^ tmp[i+8] ^ tmp[i+2] ^ tmp[i+13]);
67
68 a = (*hash)[0];
69 b = (*hash)[1];
70 c = (*hash)[2];
71 d = (*hash)[3];
72 e = (*hash)[4];
73
74 for (i=0; i<20*1; i++)
75 {
76 g = tmp[i] + ROTL32(a,5) + e + ((b & c) | (~b & d)) + 0x5a827999;
77 e = d;
78 d = c;
79 c = ROTL32(b,30);
80 b = a;
81 a = g;
82 }
83
84 for (; i<20*2; i++)
85 {
86 g = (d ^ c ^ b) + e + ROTL32(g,5) + tmp[i] + 0x6ed9eba1;
87 e = d;
88 d = c;
89 c = ROTL32(b,30);
90 b = a;
91 a = g;
92 }
93
94 for (; i<20*3; i++)
95 {
96 g = tmp[i] + ROTL32(g,5) + e + ((c & b) | (d & c) | (d & b)) - 0x70e44324;
97 e = d;
98 d = c;
99 c = ROTL32(b,30);
100 b = a;
101 a = g;
102 }
103
104 for (; i<20*4; i++)
105 {
106 g = (d ^ c ^ b) + e + ROTL32(g,5) + tmp[i] - 0x359d3e2a;
107 e = d;
108 d = c;
109 c = ROTL32(b,30);
110 b = a;
111 a = g;
112 }
113
114 (*hash)[0] += g;
115 (*hash)[1] += b;
116 (*hash)[2] += c;
117 (*hash)[3] += d;
118 (*hash)[4] += e;
119 }
120
121
122 /*
123 * Fill 16 elements of the array of 32 bit values with the bytes from
124 * dst up to count in little endian order. Fill left over space with
125 * zeros
126 */
hash_set_16(t_uint32 * dst,unsigned char const * src,unsigned int count)127 static void hash_set_16(t_uint32 * dst, unsigned char const * src, unsigned int count)
128 {
129 unsigned int i;
130 unsigned int pos;
131
132 for (pos=0,i=0; i<16; i++)
133 {
134 dst[i] = 0;
135 if (pos<count)
136 dst[i] |= ((t_uint32)src[pos]);
137 pos++;
138 if (pos<count)
139 dst[i] |= ((t_uint32)src[pos])<<8;
140 pos++;
141 if (pos<count)
142 dst[i] |= ((t_uint32)src[pos])<<16;
143 pos++;
144 if (pos<count)
145 dst[i] |= ((t_uint32)src[pos])<<24;
146 pos++;
147 }
148 }
149
150
bnet_hash(t_hash * hashout,unsigned int size,void const * datain)151 extern int bnet_hash(t_hash * hashout, unsigned int size, void const * datain)
152 {
153 t_uint32 tmp[64+16];
154 unsigned char const * data;
155 unsigned int inc;
156
157 if (!hashout || !*hashout)
158 {
159 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hashout");
160 return -1;
161 }
162 if (size>0 && !datain)
163 {
164 eventlog(eventlog_level_error,__FUNCTION__,"got NULL datain with size=%u",size);
165 return -1;
166 }
167
168 hash_init(hashout);
169
170 data = datain;
171 while (size>0)
172 {
173 if (size>64)
174 inc = 64;
175 else
176 inc = size;
177
178 hash_set_16(tmp,data,inc);
179 do_hash(hashout,tmp);
180
181 data += inc;
182 size -= inc;
183 }
184
185 return 0;
186 }
187
188
hash_eq(t_hash const h1,t_hash const h2)189 extern int hash_eq(t_hash const h1, t_hash const h2)
190 {
191 unsigned int i;
192
193 if (!h1 || !h2)
194 {
195 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hash");
196 return -1;
197 }
198
199 for (i=0; i<5; i++)
200 if (h1[i]!=h2[i])
201 return 0;
202
203 return 1;
204 }
205
206
hash_get_str(t_hash const hash)207 extern char const * hash_get_str(t_hash const hash)
208 {
209 static char temp[8*5+1]; /* each of 5 ints to 8 chars + null */
210 unsigned int i;
211
212 if (!hash)
213 {
214 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hash");
215 return NULL;
216 }
217
218 for (i=0; i<5; i++)
219 sprintf(&temp[i*8],"%08x",hash[i]);
220
221 return temp;
222 }
223
224
hash_set_str(t_hash * hash,char const * str)225 extern int hash_set_str(t_hash * hash, char const * str)
226 {
227 unsigned int i;
228
229 if (!hash)
230 {
231 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hash pointer");
232 return -1;
233 }
234 if (!*hash)
235 {
236 eventlog(eventlog_level_error,__FUNCTION__,"got NULL hash");
237 return -1;
238 }
239 if (!str)
240 {
241 eventlog(eventlog_level_error,__FUNCTION__,"got NULL str");
242 return -1;
243 }
244 if (strlen(str)!=5*8)
245 {
246 eventlog(eventlog_level_error,__FUNCTION__,"got string with length %u (should be %u)",strlen(str),5*8);
247 return -1;
248 }
249
250 for (i=0; i<5; i++)
251 if (sscanf(&str[i*8],"%8x",&(*hash)[i])!=1)
252 {
253 eventlog(eventlog_level_error,__FUNCTION__,"got bad string");
254 return -1;
255 }
256
257 return 0;
258 }
259
260
261