summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/lhash/lhash.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libcrypto/lhash/lhash.c
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/lhash/lhash.c')
-rw-r--r--src/lib/libcrypto/lhash/lhash.c489
1 files changed, 489 insertions, 0 deletions
diff --git a/src/lib/libcrypto/lhash/lhash.c b/src/lib/libcrypto/lhash/lhash.c
new file mode 100644
index 0000000000..6dfb5c9ccc
--- /dev/null
+++ b/src/lib/libcrypto/lhash/lhash.c
@@ -0,0 +1,489 @@
1/* crypto/lhash/lhash.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59char *lh_version="lhash part of SSLeay 0.9.0b 29-Jun-1998";
60
61/* Code for dynamic hash table routines
62 * Author - Eric Young v 2.0
63 *
64 * 2.0 eay - Fixed a bug that occured when using lh_delete
65 * from inside lh_doall(). As entries were deleted,
66 * the 'table' was 'contract()ed', making some entries
67 * jump from the end of the table to the start, there by
68 * skiping the lh_doall() processing. eay - 4/12/95
69 *
70 * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs
71 * were not being free()ed. 21/11/95
72 *
73 * 1.8 eay - Put the stats routines into a separate file, lh_stats.c
74 * 19/09/95
75 *
76 * 1.7 eay - Removed the fputs() for realloc failures - the code
77 * should silently tolerate them. I have also fixed things
78 * lint complained about 04/05/95
79 *
80 * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92
81 *
82 * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992
83 *
84 * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91
85 *
86 * 1.3 eay - Fixed a few lint problems 19/3/1991
87 *
88 * 1.2 eay - Fixed lh_doall problem 13/3/1991
89 *
90 * 1.1 eay - Added lh_doall
91 *
92 * 1.0 eay - First version
93 */
94#include <stdio.h>
95#include <string.h>
96#include <stdlib.h>
97#include "lhash.h"
98
99#undef MIN_NODES
100#define MIN_NODES 16
101#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
102#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
103
104#ifndef NOPROTO
105
106#define P_CP char *
107#define P_CPP char *,char *
108static void expand(LHASH *lh);
109static void contract(LHASH *lh);
110static LHASH_NODE **getrn(LHASH *lh, char *data, unsigned long *rhash);
111
112#else
113
114#define P_CP
115#define P_CPP
116static void expand();
117static void contract();
118static LHASH_NODE **getrn();
119
120#endif
121
122LHASH *lh_new(h, c)
123unsigned long (*h)();
124int (*c)();
125 {
126 LHASH *ret;
127 int i;
128
129 if ((ret=(LHASH *)malloc(sizeof(LHASH))) == NULL)
130 goto err0;
131 if ((ret->b=(LHASH_NODE **)malloc(sizeof(LHASH_NODE *)*MIN_NODES)) == NULL)
132 goto err1;
133 for (i=0; i<MIN_NODES; i++)
134 ret->b[i]=NULL;
135 ret->comp=((c == NULL)?(int (*)())strcmp:c);
136 ret->hash=((h == NULL)?(unsigned long (*)())lh_strhash:h);
137 ret->num_nodes=MIN_NODES/2;
138 ret->num_alloc_nodes=MIN_NODES;
139 ret->p=0;
140 ret->pmax=MIN_NODES/2;
141 ret->up_load=UP_LOAD;
142 ret->down_load=DOWN_LOAD;
143 ret->num_items=0;
144
145 ret->num_expands=0;
146 ret->num_expand_reallocs=0;
147 ret->num_contracts=0;
148 ret->num_contract_reallocs=0;
149 ret->num_hash_calls=0;
150 ret->num_comp_calls=0;
151 ret->num_insert=0;
152 ret->num_replace=0;
153 ret->num_delete=0;
154 ret->num_no_delete=0;
155 ret->num_retrieve=0;
156 ret->num_retrieve_miss=0;
157 ret->num_hash_comps=0;
158
159 return(ret);
160err1:
161 free((char *)ret);
162err0:
163 return(NULL);
164 }
165
166void lh_free(lh)
167LHASH *lh;
168 {
169 unsigned int i;
170 LHASH_NODE *n,*nn;
171
172 for (i=0; i<lh->num_nodes; i++)
173 {
174 n=lh->b[i];
175 while (n != NULL)
176 {
177 nn=n->next;
178 free(n);
179 n=nn;
180 }
181 }
182 free((char *)lh->b);
183 free((char *)lh);
184 }
185
186char *lh_insert(lh, data)
187LHASH *lh;
188char *data;
189 {
190 unsigned long hash;
191 LHASH_NODE *nn,**rn;
192 char *ret;
193
194 if (lh->up_load <= (lh->num_items*LH_LOAD_MULT/lh->num_nodes))
195 expand(lh);
196
197 rn=getrn(lh,data,&hash);
198
199 if (*rn == NULL)
200 {
201 if ((nn=(LHASH_NODE *)malloc(sizeof(LHASH_NODE))) == NULL)
202 return(NULL);
203 nn->data=data;
204 nn->next=NULL;
205#ifndef NO_HASH_COMP
206 nn->hash=hash;
207#endif
208 *rn=nn;
209 ret=NULL;
210 lh->num_insert++;
211 lh->num_items++;
212 }
213 else /* replace same key */
214 {
215 ret= (*rn)->data;
216 (*rn)->data=data;
217 lh->num_replace++;
218 }
219 return(ret);
220 }
221
222char *lh_delete(lh, data)
223LHASH *lh;
224char *data;
225 {
226 unsigned long hash;
227 LHASH_NODE *nn,**rn;
228 char *ret;
229
230 rn=getrn(lh,data,&hash);
231
232 if (*rn == NULL)
233 {
234 lh->num_no_delete++;
235 return(NULL);
236 }
237 else
238 {
239 nn= *rn;
240 *rn=nn->next;
241 ret=nn->data;
242 free((char *)nn);
243 lh->num_delete++;
244 }
245
246 lh->num_items--;
247 if ((lh->num_nodes > MIN_NODES) &&
248 (lh->down_load >= (lh->num_items*LH_LOAD_MULT/lh->num_nodes)))
249 contract(lh);
250
251 return(ret);
252 }
253
254char *lh_retrieve(lh, data)
255LHASH *lh;
256char *data;
257 {
258 unsigned long hash;
259 LHASH_NODE **rn;
260 char *ret;
261
262 rn=getrn(lh,data,&hash);
263
264 if (*rn == NULL)
265 {
266 lh->num_retrieve_miss++;
267 return(NULL);
268 }
269 else
270 {
271 ret= (*rn)->data;
272 lh->num_retrieve++;
273 }
274 return(ret);
275 }
276
277void lh_doall(lh, func)
278LHASH *lh;
279void (*func)();
280 {
281 lh_doall_arg(lh,func,NULL);
282 }
283
284void lh_doall_arg(lh, func, arg)
285LHASH *lh;
286void (*func)();
287char *arg;
288 {
289 int i;
290 LHASH_NODE *a,*n;
291
292 /* reverse the order so we search from 'top to bottom'
293 * We were having memory leaks otherwise */
294 for (i=lh->num_nodes-1; i>=0; i--)
295 {
296 a=lh->b[i];
297 while (a != NULL)
298 {
299 /* 28/05/91 - eay - n added so items can be deleted
300 * via lh_doall */
301 n=a->next;
302 func(a->data,arg);
303 a=n;
304 }
305 }
306 }
307
308static void expand(lh)
309LHASH *lh;
310 {
311 LHASH_NODE **n,**n1,**n2,*np;
312 unsigned int p,i,j;
313 unsigned long hash,nni;
314
315 lh->num_nodes++;
316 lh->num_expands++;
317 p=(int)lh->p++;
318 n1= &(lh->b[p]);
319 n2= &(lh->b[p+(int)lh->pmax]);
320 *n2=NULL; /* 27/07/92 - eay - undefined pointer bug */
321 nni=lh->num_alloc_nodes;
322
323 for (np= *n1; np != NULL; )
324 {
325#ifndef NO_HASH_COMP
326 hash=np->hash;
327#else
328 hash=(*(lh->hash))(np->data);
329 lh->num_hash_calls++;
330#endif
331 if ((hash%nni) != p)
332 { /* move it */
333 *n1= (*n1)->next;
334 np->next= *n2;
335 *n2=np;
336 }
337 else
338 n1= &((*n1)->next);
339 np= *n1;
340 }
341
342 if ((lh->p) >= lh->pmax)
343 {
344 j=(int)lh->num_alloc_nodes*2;
345 n=(LHASH_NODE **)realloc((char *)lh->b,
346 (unsigned int)sizeof(LHASH_NODE *)*j);
347 if (n == NULL)
348 {
349/* fputs("realloc error in lhash",stderr); */
350 lh->p=0;
351 return;
352 }
353 /* else */
354 for (i=(int)lh->num_alloc_nodes; i<j; i++)/* 26/02/92 eay */
355 n[i]=NULL; /* 02/03/92 eay */
356 lh->pmax=lh->num_alloc_nodes;
357 lh->num_alloc_nodes=j;
358 lh->num_expand_reallocs++;
359 lh->p=0;
360 lh->b=n;
361 }
362 }
363
364static void contract(lh)
365LHASH *lh;
366 {
367 LHASH_NODE **n,*n1,*np;
368
369 np=lh->b[lh->p+lh->pmax-1];
370 lh->b[lh->p+lh->pmax-1]=NULL; /* 24/07-92 - eay - weird but :-( */
371 if (lh->p == 0)
372 {
373 n=(LHASH_NODE **)realloc((char *)lh->b,
374 (unsigned int)(sizeof(LHASH_NODE *)*lh->pmax));
375 if (n == NULL)
376 {
377/* fputs("realloc error in lhash",stderr); */
378 return;
379 }
380 lh->num_contract_reallocs++;
381 lh->num_alloc_nodes/=2;
382 lh->pmax/=2;
383 lh->p=lh->pmax-1;
384 lh->b=n;
385 }
386 else
387 lh->p--;
388
389 lh->num_nodes--;
390 lh->num_contracts++;
391
392 n1=lh->b[(int)lh->p];
393 if (n1 == NULL)
394 lh->b[(int)lh->p]=np;
395 else
396 {
397 while (n1->next != NULL)
398 n1=n1->next;
399 n1->next=np;
400 }
401 }
402
403static LHASH_NODE **getrn(lh, data, rhash)
404LHASH *lh;
405char *data;
406unsigned long *rhash;
407 {
408 LHASH_NODE **ret,*n1;
409 unsigned long hash,nn;
410 int (*cf)();
411
412 hash=(*(lh->hash))(data);
413 lh->num_hash_calls++;
414 *rhash=hash;
415
416 nn=hash%lh->pmax;
417 if (nn < lh->p)
418 nn=hash%lh->num_alloc_nodes;
419
420 cf=lh->comp;
421 ret= &(lh->b[(int)nn]);
422 for (n1= *ret; n1 != NULL; n1=n1->next)
423 {
424#ifndef NO_HASH_COMP
425 lh->num_hash_comps++;
426 if (n1->hash != hash)
427 {
428 ret= &(n1->next);
429 continue;
430 }
431#endif
432 lh->num_comp_calls++;
433 if ((*cf)(n1->data,data) == 0)
434 break;
435 ret= &(n1->next);
436 }
437 return(ret);
438 }
439
440/*
441static unsigned long lh_strhash(str)
442char *str;
443 {
444 int i,l;
445 unsigned long ret=0;
446 unsigned short *s;
447
448 if (str == NULL) return(0);
449 l=(strlen(str)+1)/2;
450 s=(unsigned short *)str;
451 for (i=0; i<l; i++)
452 ret^=(s[i]<<(i&0x0f));
453 return(ret);
454 } */
455
456/* The following hash seems to work very well on normal text strings
457 * no collisions on /usr/dict/words and it distributes on %2^n quite
458 * well, not as good as MD5, but still good.
459 */
460unsigned long lh_strhash(c)
461char *c;
462 {
463 unsigned long ret=0;
464 long n;
465 unsigned long v;
466 int r;
467
468 if ((c == NULL) || (*c == '\0'))
469 return(ret);
470/*
471 unsigned char b[16];
472 MD5(c,strlen(c),b);
473 return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24));
474*/
475
476 n=0x100;
477 while (*c)
478 {
479 v=n|(*c);
480 n+=0x100;
481 r= (int)((v>>2)^v)&0x0f;
482 ret=(ret<<r)|(ret>>(32-r));
483 ret&=0xFFFFFFFFL;
484 ret^=v*v;
485 c++;
486 }
487 return((ret>>16)^ret);
488 }
489