source: trunk/src/sh_srp.c @ 34

Last change on this file since 34 was 34, checked in by rainer, 13 years ago

Code cleanup and minor fixes

File size: 14.3 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
203  SL_ENTER(_("sh_srp_x"));
204
205  /* patch by Andreas Piesk
206   */
207  if (password == NULL)
208    dez = (unsigned char *) &(skey->pw[0]);
209  else 
210    dez = (unsigned char *) password;
211
212  for (i = 0; i < PW_LEN; ++i)
213    {
214      skey->vernam[i] = (char)(*dez); 
215      ++dez;
216    }
217  skey->vernam[PW_LEN] = '\0';
218
219  (void) sl_strlcpy (skey->vernam,
220                     sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN), KEY_LEN);
221  skey->vernam[KEY_LEN] = '\0';
222
223  len = sl_strlen(salt) + 1;
224  l2  = sl_strlen(skey->vernam);
225  if (sl_ok_adds(len, l2))
226    len += l2;
227
228  /* H(s,P)
229   */
230  combi = SH_ALLOC(len);
231  (void) sl_strlcpy (combi, salt, len);
232  (void) sl_strlcat (combi, skey->vernam, len);
233  (void) sl_strlcpy (sh_srp.x, 
234                     sh_tiger_hash(combi, TIGER_DATA, 
235                                   (unsigned long) sl_strlen(combi)),
236                     KEY_LEN+1);
237  SH_FREE (combi);
238
239  SL_RET0(_("sh_srp_x"));
240}
241
242char * sh_srp_M (char * x1, char * x2, char * x3)
243{
244  char           *combi;
245  size_t          len, l2, l3;
246  static char     hash[KEY_LEN+1];
247 
248  SL_ENTER(_("sh_srp_M"));
249
250  ASSERT_RET((x1 != NULL && x2 != NULL && x3 !=NULL),
251             _("x1 != NULL && x2 != NULL && x3 !=NULL"), NULL);
252
253  len = sl_strlen(x1) + 1;
254  l2  = sl_strlen(x2); 
255  l3  = sl_strlen(x3);
256
257  if (sl_ok_adds(len, l2))
258    len += l2;
259  if (sl_ok_adds(len, l3))
260    len += l3;
261 
262  /* H(x1,x2,x3)
263   */
264  combi = SH_ALLOC(len);
265  (void) sl_strlcpy (combi, x1, len);
266  (void) sl_strlcat (combi, x2, len);
267  (void) sl_strlcat (combi, x3, len);
268  (void) sl_strlcpy (hash, 
269                     sh_tiger_hash(combi, TIGER_DATA, (unsigned long) (len-1)),
270                     KEY_LEN+1);
271  SH_FREE (combi);
272 
273  SL_RETURN(hash, _("sh_srp_M"));
274}
275
276
277void sh_srp_exit()
278{
279  SL_ENTER(_("sh_srp_exit"));
280  big_destroy(&sh_srp.g);           
281  big_destroy(&sh_srp.p);
282  big_destroy(&sh_srp.a);
283
284  big_release_pkg();
285
286  big_errno = BIG_OK;
287  SL_RET0(_("sh_srp_exit"));
288}
289
290
291int sh_srp_init()
292{
293  bigerr_t res;
294  char     modulus[80*4];
295
296  SL_ENTER(_("sh_srp_init"));
297 
298  big_errno = BIG_OK; 
299
300  res = big_init_pkg();
301 
302  if (res == BIG_OK)
303    {
304      res = big_create(&sh_srp.p);
305      if (res == BIG_OK)
306        res = big_create(&sh_srp.g);
307      if (res == BIG_OK)
308        res = big_create(&sh_srp.a);
309      if (res == BIG_OK)
310        {
311          (void) sl_strlcpy(modulus, SRP_MODULUS_1024_1, sizeof(modulus));
312          (void) sl_strlcat(modulus, SRP_MODULUS_1024_2, sizeof(modulus));
313          (void) sl_strlcat(modulus, SRP_MODULUS_1024_3, sizeof(modulus));
314          (void) sl_strlcat(modulus, SRP_MODULUS_1024_4, sizeof(modulus));
315        }
316      if (res == BIG_OK)
317        res = big_set_string (modulus,                  16, &sh_srp.p);
318      if (res == BIG_OK)
319        res = big_set_string (SRP_GENERATOR_1024,       16, &sh_srp.g);
320      if (res == BIG_OK)
321        {
322          SL_RETURN (0, _("sh_srp_init"));
323        }
324      else
325        sh_srp_exit();
326    }
327  SL_RETURN ((-1), _("sh_srp_init"));
328}
329
330
331int sh_srp_make_a ()
332{
333  UINT32 randl[6];
334  int    i;
335  int    res;
336  char   hash[KEY_LEN+1];
337
338  SL_ENTER(_("sh_srp_make_a"));
339
340  for (i = 0; i < 6; ++i)
341    randl[i] = (UINT32) taus_get (&(skey->rng0[0]), 
342                                  &(skey->rng1[0]),
343                                  &(skey->rng2[0]));
344  (void) sl_strlcpy (hash, 
345                     sh_tiger_hash((char *)&randl[0], TIGER_DATA, 
346                                   (unsigned long) 6*sizeof(UINT32)), 
347                     KEY_LEN+1);
348
349  hash[KEY_LEN] = '\0';
350
351  res = big_set_string (hash,       16, &sh_srp.a);
352  if (res == BIG_OK)
353    {
354      SL_RETURN((0), _("sh_srp_make_a"));
355    }
356  else
357    {
358      SL_RETURN((-1), _("sh_srp_make_a"));
359    }
360}
361
362/* return 0 if AB is NOT zero
363 */
364int sh_srp_check_zero (char * AB_str)
365{
366  bignum   AB, q, r;
367  bigerr_t res;
368  int      val;
369
370  SL_ENTER(_("sh_srp_check_zero"));
371
372  ASSERT_RET((AB_str != NULL), _("AB_str != NULL"), (-1));
373
374  res = big_create(&AB);
375  if (res == BIG_OK)
376    res = big_create(&q);
377  if (res == BIG_OK)
378    res = big_create(&r);
379
380  if (res == BIG_OK)
381    res = big_set_string (AB_str,       16, &AB);
382  if (res == BIG_OK)
383    res = big_trunc(&AB, &sh_srp.p, &q, &r); /* is last one the remainder ? */
384 
385  if (res != BIG_OK)             val = (-1);
386  else if (0 != big_zerop(&AB) ) val = (-1); /* 0 != (sign == 0) */
387  else                           val =    0;
388
389  big_destroy(&AB);     
390  big_destroy(&q);     
391  big_destroy(&r);     
392 
393  SL_RETURN((val), _("sh_srp_check_zero"));
394}
395
396#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
397 
398
399char * sh_srp_A ()
400{
401  bignum   A;
402  char    *str;
403  char    *combi;
404  bigerr_t res;
405
406  SL_ENTER(_("sh_srp_A"));
407
408  res = big_create(&A);
409 
410  if (res == BIG_OK)
411    res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &A);
412 
413  if (res == BIG_OK)
414    str = big_string (&A, 16);
415  else
416    str = NULL;
417 
418  if (str != NULL)
419    combi = sh_util_strdup(str);
420  else
421    combi = NULL;
422 
423  big_destroy(&A);           
424  SL_RETURN(combi, _("sh_srp_A"));
425}
426
427/* #ifdef SH_WITH_CLIENT */
428#endif 
429 
430#ifdef SH_WITH_SERVER
431
432char * sh_srp_B (char * verifier)
433{
434  bignum   B, v, t, dummy;
435  char    *str;
436  char    *combi;
437  bigerr_t res;
438
439  SL_ENTER(_("sh_srp_B"));
440
441  ASSERT_RET((verifier != NULL), _("verifier != NULL"), (NULL));
442
443  res = big_create(&dummy);
444
445  if (res == BIG_OK)
446    res = big_create(&t);
447  if (res == BIG_OK)
448    res = big_create(&v);
449  if (res == BIG_OK)
450    res = big_create(&B);
451
452  if (res == BIG_OK)
453    res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &t);
454 
455  if (res == BIG_OK)
456    big_set_string (verifier,       16, &v);
457
458  if (res == BIG_OK)
459    res = big_add (&t, &v, &dummy);
460
461  if (res == BIG_OK)
462    {
463      if ( big_greaterp(&dummy, &sh_srp.p) ) 
464        res = big_sub(&dummy, &sh_srp.p, &B);
465      else                                   
466        res = big_set_big(&dummy, &B);
467    }
468
469  if (res == BIG_OK)
470    str = big_string (&B, 16);
471  else
472    str = NULL;
473 
474  if (str != NULL)
475    combi = sh_util_strdup(str);
476  else
477    combi = NULL;
478 
479  big_destroy(&B);     
480  big_destroy(&v);     
481  big_destroy(&t);     
482  big_destroy(&dummy); 
483 
484  SL_RETURN(combi, _("sh_srp_B"));
485}
486/* #ifdef SH_WITH_SERVER */
487#endif 
488 
489 
490#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
491 
492char * sh_srp_S_c (char * u_str, char * B_str)
493{
494  bignum   u, B, x, t, base, z1, z2;
495  char    *str;
496  char    *combi;
497  bigerr_t res;
498
499  SL_ENTER(_("sh_srp_S_c"));
500
501  ASSERT_RET((u_str != NULL && B_str != NULL),
502             _("u_str != NULL && B_str != NULL"), (NULL));
503
504  big_errno = BIG_OK;
505
506  res = big_create(&z2);
507  if (res == BIG_OK)
508   res = big_create(&z1);
509  if (res == BIG_OK)
510   res = big_create(&base);
511  if (res == BIG_OK)
512   res = big_create(&t);
513  if (res == BIG_OK)
514   res = big_create(&x);
515  if (res == BIG_OK)
516   res = big_create(&B);
517  if (res == BIG_OK)
518   res = big_create(&u);
519 
520  if (res == BIG_OK)
521   res = big_set_string (B_str,          16, &B);
522  if (res == BIG_OK)
523   res = big_set_string (sh_srp.x,       16, &x);
524  if (res == BIG_OK)
525   res = big_set_string (u_str,          16, &u);
526 
527  /* the base  (B - g^x)
528   */
529  if (res == BIG_OK)
530    res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &t);
531
532  if (res == BIG_OK)
533    {
534      if ( big_greaterp(&B, &t) != 0) 
535        {
536          res = big_sub(&B, &t, &base);
537        }
538      else 
539        {
540          res = big_add(&B, &sh_srp.p, &z2);
541          if (res == BIG_OK)
542            res = big_sub(&z2, &t, &base);
543        }
544    }
545
546  /* the exponent (a + ux)
547   */
548  if (res == BIG_OK)
549    res = big_mul (&u, &x, &t);
550  if (res == BIG_OK)
551    res = big_trunc(&t, &sh_srp.p, &z1, &z2); /* is last one the remainder ? */
552  if (res == BIG_OK)
553    res = big_add(&sh_srp.a, &z2, &z1);
554  if (res == BIG_OK)
555    {
556      if ( big_greaterp(&z1, &sh_srp.p) != 0) 
557        res = big_sub(&z1, &sh_srp.p, &z2);
558      else 
559        res = big_set_big(&z1, &z2);
560    }
561
562  if (res == BIG_OK)
563    res = big_exptmod (&base, &z2, &sh_srp.p, &t);
564
565  if (res == BIG_OK)
566    str = big_string (&t, 16);
567  else
568    str = NULL;
569
570  if (str != NULL)
571    combi = sh_util_strdup(str);
572  else
573    combi = NULL;
574
575  big_destroy(&z1);         
576  big_destroy(&z2);         
577  big_destroy(&base);       
578  big_destroy(&t);     
579  big_destroy(&x);     
580  big_destroy(&B);     
581  big_destroy(&u);     
582 
583  SL_RETURN(combi, _("sh_srp_S_c"));
584}
585 
586/* #ifdef SH_WITH_CLIENT */
587#endif 
588 
589#ifdef SH_WITH_SERVER
590
591 
592char * sh_srp_S_s (char * u_str, char * A_str, char * v_str)
593{
594  bignum   u, A, v, t, base, z1, z2;
595  char    *str;
596  char    *combi;
597  bigerr_t res;
598
599  SL_ENTER(_("sh_srp_S_s"));
600
601  ASSERT_RET((u_str != NULL && A_str != NULL && v_str != NULL),
602             _("u_str != NULL && A_str != NULL && v_str != NULL"),
603             (NULL));
604
605  big_errno = BIG_OK;
606
607  res = big_create(&z2);
608  if (res == BIG_OK)
609    res = big_create(&z1);
610  if (res == BIG_OK)
611    res = big_create(&base);
612  if (res == BIG_OK)
613    res = big_create(&t);
614  if (res == BIG_OK)
615    res = big_create(&v);
616  if (res == BIG_OK)
617    res = big_create(&A);
618  if (res == BIG_OK)
619    res = big_create(&u);
620 
621  if (res == BIG_OK)
622    res = big_set_string (A_str,          16, &A);
623  if (res == BIG_OK)
624    res = big_set_string (v_str,          16, &v);
625  if (res == BIG_OK)
626    res = big_set_string (u_str,          16, &u);
627 
628  /* the base  (Av^u)
629   */
630  if (res == BIG_OK)
631    res = big_exptmod (&v, &u, &sh_srp.p, &t);
632  if (res == BIG_OK)
633    res = big_mul (&A, &t, &z1);
634  if (res == BIG_OK)
635    res = big_trunc(&z1, &sh_srp.p, &z2, &base); /* is last the remainder ? */
636
637  if (res == BIG_OK)
638    res = big_exptmod (&base, &sh_srp.a, &sh_srp.p, &t);
639
640  if (res == BIG_OK)
641    str = big_string (&t, 16);
642  else
643    str = NULL;
644 
645  if (str != NULL)
646    combi = sh_util_strdup(str);
647  else
648    combi = NULL;
649 
650  big_destroy(&z1);         
651  big_destroy(&z2);         
652  big_destroy(&base);       
653  big_destroy(&t);     
654  big_destroy(&v);     
655  big_destroy(&A);     
656  big_destroy(&u);     
657 
658  SL_RETURN(combi, _("sh_srp_S_s"));
659}
660
661/* #ifdef SH_WITH_SERVER */
662#endif 
663
664
665char * sh_srp_verifier (void)
666{
667  bignum   x, v;
668  char    *combi;
669  char    *str;
670  bigerr_t res;
671 
672  SL_ENTER(_("sh_srp_verifier"));
673 
674  res = big_create(&x);
675  if (res == BIG_OK)
676    res = big_create(&v);
677 
678  if (res == BIG_OK)
679    res = big_set_string (sh_srp.x,               16, &x);
680 
681  if (res == BIG_OK)
682    res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &v);
683 
684  if (res == BIG_OK)
685    str = big_string (&v, 16);
686  else
687    str = NULL;
688 
689  if (str != NULL)
690    combi = sh_util_strdup(str);
691  else
692    combi = NULL;
693 
694  big_destroy(&x);           
695  big_destroy(&v);           
696 
697  SL_RETURN(combi, _("sh_srp_verifier"));
698}
699 
700
701/* #if (defined (SH_WITH_CLIENT) || defined (SH_WITH_SERVER)) */
702
703#endif
704
705/* #ifdef USE_SRP_PROTOCOL */
706
707#endif
708
709
710
711
Note: See TracBrowser for help on using the repository browser.