source: trunk/src/sh_srp.c@ 25

Last change on this file since 25 was 22, checked in by rainer, 19 years ago

Minor code revisions.

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