source: trunk/src/sh_srp.c @ 133

Last change on this file since 133 was 133, checked in by rainer, 12 years ago

Reentrant checksum/hash functions.

File size: 14.4 KB
Line 
1/* SAMHAIN file system integrity testing                                   */
2/* Copyright (C) 1999, 2000 Rainer Wichmann                                */
3/*                                                                         */
4/*  This program is free software; you can redistribute it                 */
5/*  and/or modify                                                          */
6/*  it under the terms of the GNU General Public License as                */
7/*  published by                                                           */
8/*  the Free Software Foundation; either version 2 of the License, or      */
9/*  (at your option) any later version.                                    */
10/*                                                                         */
11/*  This program is distributed in the hope that it will be useful,        */
12/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
13/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
14/*  GNU General Public License for more details.                           */
15/*                                                                         */
16/*  You should have received a copy of the GNU General Public License      */
17/*  along with this program; if not, write to the Free Software            */
18/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
19
20#include "config_xor.h"
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26
27#include "samhain.h"
28
29#ifdef USE_SRP_PROTOCOL
30
31#if (defined (SH_WITH_CLIENT) || defined (SH_WITH_SERVER))
32
33#include "sh_tiger.h"
34#include "sh_mem.h"
35#include "sh_utils.h"
36#include "sh_srp.h"
37
38#if !defined(HAVE_LIBGMP) || !defined(HAVE_GMP_H)
39#include "bignum.h"
40#else
41
42#include <gmp.h>
43
44#define BIG_OK 0
45#define bigerr_t int
46int big_errno = BIG_OK;
47
48#define bignum MP_INT
49
50inline
51int big_create (bignum * a)
52{
53  mpz_init(a);
54  return 0;
55}
56
57inline
58int big_zerop (bignum * a)
59{
60  mpz_t b;
61  int   i;
62  mpz_init_set_str(b, "0", 10);
63  i = mpz_cmp(a, b);
64  mpz_clear(b);
65  if (i)
66    return 0;
67  else
68    return 1;
69}
70
71inline
72int big_trunc (bignum * a, bignum * b, bignum * q, bignum *r)
73{
74  mpz_tdiv_qr(q, r, a, b);
75  return 0;
76}
77
78inline
79int big_exptmod (bignum * a, bignum * b, bignum * c, bignum *d)
80{
81  mpz_powm(d, a, b, c);
82  return 0;
83}
84
85char * get_str_internal = NULL;
86int    siz_str_internal = 0;
87
88inline
89char * big_string (bignum * a, int base)
90{
91  char * str = NULL;
92  int    size;
93  int    i;
94  str = mpz_get_str (str, base, a);
95
96  if (get_str_internal == NULL)
97    {
98      get_str_internal = malloc(512);   /* only once */
99      if (get_str_internal)
100        {
101          siz_str_internal = 512;
102        }
103      else
104        {
105          if (str != NULL)
106            free(str);
107          return 0;
108        }
109      get_str_internal[0] = '\0';
110    }
111
112  if (str != NULL)
113    {
114      size = strlen(str) + 1;
115      if (size > siz_str_internal)
116        get_str_internal = realloc (get_str_internal, size);
117      if (get_str_internal == NULL)
118        {
119          free(str);
120          return NULL;
121        }
122      siz_str_internal = size;
123      sl_strlcpy (get_str_internal, str, siz_str_internal);
124      for (i = 0; i < (size-1); ++i)
125        if (get_str_internal[i] >= 'a' && get_str_internal[i] <= 'f' )
126          get_str_internal[i] = get_str_internal[i] - 'a' + 'A';
127      free (str);
128    }
129  return get_str_internal;
130}
131
132inline 
133int big_add(bignum * a, bignum * b, bignum * c)
134{
135  mpz_add(c, a, b);
136  return 0;
137}
138
139inline 
140int big_sub(bignum * a, bignum * b, bignum * c)
141{
142  mpz_sub(c, a, b);
143  return 0;
144}
145
146inline 
147int big_mul(bignum * a, bignum * b, bignum * c)
148{
149  mpz_mul(c, a, b);
150  return 0;
151}
152
153inline 
154int big_greaterp(bignum * a, bignum * b)
155{
156  return mpz_cmp(a, b) > 0;
157}
158
159inline 
160int big_set_big(bignum * a, bignum * b)
161{
162    mpz_set(b, a);
163    return 0;
164}
165
166
167inline 
168int big_set_string(const char * str, int base, bignum * a)
169{
170  mpz_set_str (a, str, base);
171  return 0;
172}
173
174
175#define big_init_pkg() 0
176#define big_release_pkg()
177#define big_destroy mpz_clear
178
179/* #if defined(HAVE_LIBGMP)
180 */
181#endif
182
183#undef  FIL__
184#define FIL__  _("sh_srp.c")
185
186typedef struct sh_srp_struc {
187  char   x[KEY_LEN+1];
188  bignum a;
189  bignum p;
190  bignum g;
191} sh_srp_t;
192
193static sh_srp_t sh_srp;
194
195void sh_srp_x (char * salt, char * password)
196{
197
198  char           *combi;
199  size_t          len, l2;
200  register int i;
201  unsigned char * dez = NULL;
202  char hashbuf[KEYBUF_SIZE];
203
204  SL_ENTER(_("sh_srp_x"));
205
206  /* patch by Andreas Piesk
207   */
208  if (password == NULL)
209    dez = (unsigned char *) &(skey->pw[0]);
210  else 
211    dez = (unsigned char *) password;
212
213  for (i = 0; i < PW_LEN; ++i)
214    {
215      skey->vernam[i] = (char)(*dez); 
216      ++dez;
217    }
218  skey->vernam[PW_LEN] = '\0';
219
220  (void) sl_strlcpy (skey->vernam,
221                     sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN, 
222                                   hashbuf, sizeof(hashbuf)), 
223                     KEY_LEN);
224  skey->vernam[KEY_LEN] = '\0';
225
226  len = sl_strlen(salt) + 1;
227  l2  = sl_strlen(skey->vernam);
228  if (sl_ok_adds(len, l2))
229    len += l2;
230
231  /* H(s,P)
232   */
233  combi = SH_ALLOC(len);
234  (void) sl_strlcpy (combi, salt, len);
235  (void) sl_strlcat (combi, skey->vernam, len);
236  (void) sl_strlcpy (sh_srp.x, 
237                     sh_tiger_hash(combi, TIGER_DATA, 
238                                   (unsigned long) sl_strlen(combi),
239                                   hashbuf, sizeof(hashbuf)),
240                     KEY_LEN+1);
241  SH_FREE (combi);
242
243  SL_RET0(_("sh_srp_x"));
244}
245
246char * sh_srp_M (char * x1, char * x2, char * x3, char * hash, size_t size)
247{
248  char           *combi;
249  size_t          len, l2, l3;
250 
251  SL_ENTER(_("sh_srp_M"));
252
253  ASSERT_RET((x1 != NULL && x2 != NULL && x3 !=NULL),
254             _("x1 != NULL && x2 != NULL && x3 !=NULL"), NULL);
255
256  len = sl_strlen(x1) + 1;
257  l2  = sl_strlen(x2); 
258  l3  = sl_strlen(x3);
259
260  if (sl_ok_adds(len, l2))
261    len += l2;
262  if (sl_ok_adds(len, l3))
263    len += l3;
264 
265  /* H(x1,x2,x3)
266   */
267  combi = SH_ALLOC(len);
268  (void) sl_strlcpy (combi, x1, len);
269  (void) sl_strlcat (combi, x2, len);
270  (void) sl_strlcat (combi, x3, len);
271  (void) sh_tiger_hash(combi, TIGER_DATA, (unsigned long) (len-1),
272                       hash, size);
273  SH_FREE (combi);
274 
275  SL_RETURN(hash, _("sh_srp_M"));
276}
277
278
279void sh_srp_exit()
280{
281  SL_ENTER(_("sh_srp_exit"));
282  big_destroy(&sh_srp.g);           
283  big_destroy(&sh_srp.p);
284  big_destroy(&sh_srp.a);
285
286  big_release_pkg();
287
288  big_errno = BIG_OK;
289  SL_RET0(_("sh_srp_exit"));
290}
291
292
293int sh_srp_init()
294{
295  bigerr_t res;
296  char     modulus[80*4];
297
298  SL_ENTER(_("sh_srp_init"));
299 
300  big_errno = BIG_OK; 
301
302  res = big_init_pkg();
303 
304  if (res == BIG_OK)
305    {
306      res = big_create(&sh_srp.p);
307      if (res == BIG_OK)
308        res = big_create(&sh_srp.g);
309      if (res == BIG_OK)
310        res = big_create(&sh_srp.a);
311      if (res == BIG_OK)
312        {
313          (void) sl_strlcpy(modulus, SRP_MODULUS_1024_1, sizeof(modulus));
314          (void) sl_strlcat(modulus, SRP_MODULUS_1024_2, sizeof(modulus));
315          (void) sl_strlcat(modulus, SRP_MODULUS_1024_3, sizeof(modulus));
316          (void) sl_strlcat(modulus, SRP_MODULUS_1024_4, sizeof(modulus));
317        }
318      if (res == BIG_OK)
319        res = big_set_string (modulus,                  16, &sh_srp.p);
320      if (res == BIG_OK)
321        res = big_set_string (SRP_GENERATOR_1024,       16, &sh_srp.g);
322      if (res == BIG_OK)
323        {
324          SL_RETURN (0, _("sh_srp_init"));
325        }
326      else
327        sh_srp_exit();
328    }
329  SL_RETURN ((-1), _("sh_srp_init"));
330}
331
332
333int sh_srp_make_a ()
334{
335  UINT32 randl[6];
336  int    i;
337  int    res;
338  char   hash[KEY_LEN+1];
339
340  SL_ENTER(_("sh_srp_make_a"));
341
342  for (i = 0; i < 6; ++i)
343    randl[i] = (UINT32) taus_get (&(skey->rng0[0]), 
344                                  &(skey->rng1[0]),
345                                  &(skey->rng2[0]));
346  (void) sl_strlcpy (hash, 
347                     sh_tiger_hash((char *)&randl[0], TIGER_DATA, 
348                                   (unsigned long) 6*sizeof(UINT32)), 
349                     KEY_LEN+1);
350
351  hash[KEY_LEN] = '\0';
352
353  res = big_set_string (hash,       16, &sh_srp.a);
354  if (res == BIG_OK)
355    {
356      SL_RETURN((0), _("sh_srp_make_a"));
357    }
358  else
359    {
360      SL_RETURN((-1), _("sh_srp_make_a"));
361    }
362}
363
364/* return 0 if AB is NOT zero
365 */
366int sh_srp_check_zero (char * AB_str)
367{
368  bignum   AB, q, r;
369  bigerr_t res;
370  int      val;
371
372  SL_ENTER(_("sh_srp_check_zero"));
373
374  ASSERT_RET((AB_str != NULL), _("AB_str != NULL"), (-1));
375
376  res = big_create(&AB);
377  if (res == BIG_OK)
378    res = big_create(&q);
379  if (res == BIG_OK)
380    res = big_create(&r);
381
382  if (res == BIG_OK)
383    res = big_set_string (AB_str,       16, &AB);
384  if (res == BIG_OK)
385    res = big_trunc(&AB, &sh_srp.p, &q, &r); /* is last one the remainder ? */
386 
387  if (res != BIG_OK)             val = (-1);
388  else if (0 != big_zerop(&AB) ) val = (-1); /* 0 != (sign == 0) */
389  else                           val =    0;
390
391  big_destroy(&AB);     
392  big_destroy(&q);     
393  big_destroy(&r);     
394 
395  SL_RETURN((val), _("sh_srp_check_zero"));
396}
397
398#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
399 
400
401char * sh_srp_A ()
402{
403  bignum   A;
404  char    *str;
405  char    *combi;
406  bigerr_t res;
407
408  SL_ENTER(_("sh_srp_A"));
409
410  res = big_create(&A);
411 
412  if (res == BIG_OK)
413    res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &A);
414 
415  if (res == BIG_OK)
416    str = big_string (&A, 16);
417  else
418    str = NULL;
419 
420  if (str != NULL)
421    combi = sh_util_strdup(str);
422  else
423    combi = NULL;
424 
425  big_destroy(&A);           
426  SL_RETURN(combi, _("sh_srp_A"));
427}
428
429/* #ifdef SH_WITH_CLIENT */
430#endif 
431 
432#ifdef SH_WITH_SERVER
433
434char * sh_srp_B (char * verifier)
435{
436  bignum   B, v, t, dummy;
437  char    *str;
438  char    *combi;
439  bigerr_t res;
440
441  SL_ENTER(_("sh_srp_B"));
442
443  ASSERT_RET((verifier != NULL), _("verifier != NULL"), (NULL));
444
445  res = big_create(&dummy);
446
447  if (res == BIG_OK)
448    res = big_create(&t);
449  if (res == BIG_OK)
450    res = big_create(&v);
451  if (res == BIG_OK)
452    res = big_create(&B);
453
454  if (res == BIG_OK)
455    res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &t);
456 
457  if (res == BIG_OK)
458    big_set_string (verifier,       16, &v);
459
460  if (res == BIG_OK)
461    res = big_add (&t, &v, &dummy);
462
463  if (res == BIG_OK)
464    {
465      if ( big_greaterp(&dummy, &sh_srp.p) ) 
466        res = big_sub(&dummy, &sh_srp.p, &B);
467      else                                   
468        res = big_set_big(&dummy, &B);
469    }
470
471  if (res == BIG_OK)
472    str = big_string (&B, 16);
473  else
474    str = NULL;
475 
476  if (str != NULL)
477    combi = sh_util_strdup(str);
478  else
479    combi = NULL;
480 
481  big_destroy(&B);     
482  big_destroy(&v);     
483  big_destroy(&t);     
484  big_destroy(&dummy); 
485 
486  SL_RETURN(combi, _("sh_srp_B"));
487}
488/* #ifdef SH_WITH_SERVER */
489#endif 
490 
491 
492#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
493 
494char * sh_srp_S_c (char * u_str, char * B_str)
495{
496  bignum   u, B, x, t, base, z1, z2;
497  char    *str;
498  char    *combi;
499  bigerr_t res;
500
501  SL_ENTER(_("sh_srp_S_c"));
502
503  ASSERT_RET((u_str != NULL && B_str != NULL),
504             _("u_str != NULL && B_str != NULL"), (NULL));
505
506  big_errno = BIG_OK;
507
508  res = big_create(&z2);
509  if (res == BIG_OK)
510   res = big_create(&z1);
511  if (res == BIG_OK)
512   res = big_create(&base);
513  if (res == BIG_OK)
514   res = big_create(&t);
515  if (res == BIG_OK)
516   res = big_create(&x);
517  if (res == BIG_OK)
518   res = big_create(&B);
519  if (res == BIG_OK)
520   res = big_create(&u);
521 
522  if (res == BIG_OK)
523   res = big_set_string (B_str,          16, &B);
524  if (res == BIG_OK)
525   res = big_set_string (sh_srp.x,       16, &x);
526  if (res == BIG_OK)
527   res = big_set_string (u_str,          16, &u);
528 
529  /* the base  (B - g^x)
530   */
531  if (res == BIG_OK)
532    res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &t);
533
534  if (res == BIG_OK)
535    {
536      if ( big_greaterp(&B, &t) != 0) 
537        {
538          res = big_sub(&B, &t, &base);
539        }
540      else 
541        {
542          res = big_add(&B, &sh_srp.p, &z2);
543          if (res == BIG_OK)
544            res = big_sub(&z2, &t, &base);
545        }
546    }
547
548  /* the exponent (a + ux)
549   */
550  if (res == BIG_OK)
551    res = big_mul (&u, &x, &t);
552  if (res == BIG_OK)
553    res = big_trunc(&t, &sh_srp.p, &z1, &z2); /* is last one the remainder ? */
554  if (res == BIG_OK)
555    res = big_add(&sh_srp.a, &z2, &z1);
556  if (res == BIG_OK)
557    {
558      if ( big_greaterp(&z1, &sh_srp.p) != 0) 
559        res = big_sub(&z1, &sh_srp.p, &z2);
560      else 
561        res = big_set_big(&z1, &z2);
562    }
563
564  if (res == BIG_OK)
565    res = big_exptmod (&base, &z2, &sh_srp.p, &t);
566
567  if (res == BIG_OK)
568    str = big_string (&t, 16);
569  else
570    str = NULL;
571
572  if (str != NULL)
573    combi = sh_util_strdup(str);
574  else
575    combi = NULL;
576
577  big_destroy(&z1);         
578  big_destroy(&z2);         
579  big_destroy(&base);       
580  big_destroy(&t);     
581  big_destroy(&x);     
582  big_destroy(&B);     
583  big_destroy(&u);     
584 
585  SL_RETURN(combi, _("sh_srp_S_c"));
586}
587 
588/* #ifdef SH_WITH_CLIENT */
589#endif 
590 
591#ifdef SH_WITH_SERVER
592
593 
594char * sh_srp_S_s (char * u_str, char * A_str, char * v_str)
595{
596  bignum   u, A, v, t, base, z1, z2;
597  char    *str;
598  char    *combi;
599  bigerr_t res;
600
601  SL_ENTER(_("sh_srp_S_s"));
602
603  ASSERT_RET((u_str != NULL && A_str != NULL && v_str != NULL),
604             _("u_str != NULL && A_str != NULL && v_str != NULL"),
605             (NULL));
606
607  big_errno = BIG_OK;
608
609  res = big_create(&z2);
610  if (res == BIG_OK)
611    res = big_create(&z1);
612  if (res == BIG_OK)
613    res = big_create(&base);
614  if (res == BIG_OK)
615    res = big_create(&t);
616  if (res == BIG_OK)
617    res = big_create(&v);
618  if (res == BIG_OK)
619    res = big_create(&A);
620  if (res == BIG_OK)
621    res = big_create(&u);
622 
623  if (res == BIG_OK)
624    res = big_set_string (A_str,          16, &A);
625  if (res == BIG_OK)
626    res = big_set_string (v_str,          16, &v);
627  if (res == BIG_OK)
628    res = big_set_string (u_str,          16, &u);
629 
630  /* the base  (Av^u)
631   */
632  if (res == BIG_OK)
633    res = big_exptmod (&v, &u, &sh_srp.p, &t);
634  if (res == BIG_OK)
635    res = big_mul (&A, &t, &z1);
636  if (res == BIG_OK)
637    res = big_trunc(&z1, &sh_srp.p, &z2, &base); /* is last the remainder ? */
638
639  if (res == BIG_OK)
640    res = big_exptmod (&base, &sh_srp.a, &sh_srp.p, &t);
641
642  if (res == BIG_OK)
643    str = big_string (&t, 16);
644  else
645    str = NULL;
646 
647  if (str != NULL)
648    combi = sh_util_strdup(str);
649  else
650    combi = NULL;
651 
652  big_destroy(&z1);         
653  big_destroy(&z2);         
654  big_destroy(&base);       
655  big_destroy(&t);     
656  big_destroy(&v);     
657  big_destroy(&A);     
658  big_destroy(&u);     
659 
660  SL_RETURN(combi, _("sh_srp_S_s"));
661}
662
663/* #ifdef SH_WITH_SERVER */
664#endif 
665
666
667char * sh_srp_verifier (void)
668{
669  bignum   x, v;
670  char    *combi;
671  char    *str;
672  bigerr_t res;
673 
674  SL_ENTER(_("sh_srp_verifier"));
675 
676  res = big_create(&x);
677  if (res == BIG_OK)
678    res = big_create(&v);
679 
680  if (res == BIG_OK)
681    res = big_set_string (sh_srp.x,               16, &x);
682 
683  if (res == BIG_OK)
684    res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &v);
685 
686  if (res == BIG_OK)
687    str = big_string (&v, 16);
688  else
689    str = NULL;
690 
691  if (str != NULL)
692    combi = sh_util_strdup(str);
693  else
694    combi = NULL;
695 
696  big_destroy(&x);           
697  big_destroy(&v);           
698 
699  SL_RETURN(combi, _("sh_srp_verifier"));
700}
701 
702
703/* #if (defined (SH_WITH_CLIENT) || defined (SH_WITH_SERVER)) */
704
705#endif
706
707/* #ifdef USE_SRP_PROTOCOL */
708
709#endif
710
711
712
713
Note: See TracBrowser for help on using the repository browser.