source: trunk/src/sh_srp.c@ 519

Last change on this file since 519 was 474, checked in by katerina, 9 years ago

Fix for ticket #372 (Replace obsolete smatch by clang in test suite).

File size: 16.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
88static
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 = calloc(1,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 {
117 char * ptr = realloc (get_str_internal, size);
118 if (ptr)
119 get_str_internal = ptr;
120 else
121 { free(get_str_internal); get_str_internal = NULL; }
122 }
123 if (get_str_internal == NULL)
124 {
125 free(str);
126 return NULL;
127 }
128 siz_str_internal = size;
129 sl_strlcpy (get_str_internal, str, siz_str_internal);
130 for (i = 0; i < (size-1); ++i)
131 if (get_str_internal[i] >= 'a' && get_str_internal[i] <= 'f' )
132 get_str_internal[i] = get_str_internal[i] - 'a' + 'A';
133 free (str);
134 }
135 return get_str_internal;
136}
137
138inline
139int big_add(bignum * a, bignum * b, bignum * c)
140{
141 mpz_add(c, a, b);
142 return 0;
143}
144
145inline
146int big_sub(bignum * a, bignum * b, bignum * c)
147{
148 mpz_sub(c, a, b);
149 return 0;
150}
151
152inline
153int big_mul(bignum * a, bignum * b, bignum * c)
154{
155 mpz_mul(c, a, b);
156 return 0;
157}
158
159inline
160int big_greaterp(bignum * a, bignum * b)
161{
162 return mpz_cmp(a, b) > 0;
163}
164
165inline
166int big_set_big(bignum * a, bignum * b)
167{
168 mpz_set(b, a);
169 return 0;
170}
171
172
173inline
174int big_set_string(const char * str, int base, bignum * a)
175{
176 mpz_set_str (a, str, base);
177 return 0;
178}
179
180
181#define big_init_pkg() 0
182#define big_release_pkg()
183#define big_destroy mpz_clear
184
185/* #if defined(HAVE_LIBGMP)
186 */
187#endif
188
189#undef FIL__
190#define FIL__ _("sh_srp.c")
191
192typedef struct sh_srp_struc {
193 char x[KEY_LEN+1];
194 bignum a;
195 bignum p;
196 bignum g;
197} sh_srp_t;
198
199static sh_srp_t sh_srp;
200
201void sh_srp_x (char * salt, char * password)
202{
203
204 char *combi;
205 size_t len, l2;
206 register int i;
207 unsigned char * dez = NULL;
208 char hashbuf[KEYBUF_SIZE];
209
210 SL_ENTER(_("sh_srp_x"));
211
212 /* patch by Andreas Piesk
213 */
214 if (password == NULL)
215 dez = (unsigned char *) &(skey->pw[0]);
216 else
217 dez = (unsigned char *) password;
218
219 for (i = 0; i < PW_LEN; ++i)
220 {
221 skey->vernam[i] = (char)(*dez);
222 ++dez;
223 }
224 skey->vernam[PW_LEN] = '\0';
225
226 (void) sl_strlcpy (skey->vernam,
227 sh_tiger_hash(skey->vernam, TIGER_DATA, PW_LEN,
228 hashbuf, sizeof(hashbuf)),
229 KEY_LEN);
230 skey->vernam[KEY_LEN] = '\0';
231
232 len = sl_strlen(salt) + 1;
233 l2 = sl_strlen(skey->vernam);
234 if (sl_ok_adds(len, l2))
235 len += l2;
236
237 /* H(s,P)
238 */
239 combi = SH_ALLOC(len);
240 (void) sl_strlcpy (combi, salt, len);
241 (void) sl_strlcat (combi, skey->vernam, len);
242 (void) sl_strlcpy (sh_srp.x,
243 sh_tiger_hash(combi, TIGER_DATA,
244 (unsigned long) sl_strlen(combi),
245 hashbuf, sizeof(hashbuf)),
246 KEY_LEN+1);
247 SH_FREE (combi);
248
249 SL_RET0(_("sh_srp_x"));
250}
251
252char * sh_srp_M (char * x1, char * x2, char * x3, char * hash, size_t size)
253{
254 char *combi;
255 size_t len, l2, l3;
256
257 SL_ENTER(_("sh_srp_M"));
258
259 ASSERT_RET((x1 != NULL && x2 != NULL && x3 !=NULL),
260 _("x1 != NULL && x2 != NULL && x3 !=NULL"), NULL);
261
262 len = sl_strlen(x1) + 1;
263 l2 = sl_strlen(x2);
264 l3 = sl_strlen(x3);
265
266 if (sl_ok_adds(len, l2))
267 len += l2;
268 if (sl_ok_adds(len, l3))
269 len += l3;
270
271 /* H(x1,x2,x3)
272 */
273 combi = SH_ALLOC(len);
274 (void) sl_strlcpy (combi, x1, len);
275 (void) sl_strlcat (combi, x2, len);
276 (void) sl_strlcat (combi, x3, len);
277 (void) sh_tiger_hash(combi, TIGER_DATA, (unsigned long) (len-1),
278 hash, size);
279 SH_FREE (combi);
280
281 SL_RETURN(hash, _("sh_srp_M"));
282}
283
284
285void sh_srp_exit()
286{
287 SL_ENTER(_("sh_srp_exit"));
288 big_destroy(&sh_srp.g);
289 big_destroy(&sh_srp.p);
290 big_destroy(&sh_srp.a);
291
292 big_release_pkg();
293
294 big_errno = BIG_OK;
295 SL_RET0(_("sh_srp_exit"));
296}
297
298
299int sh_srp_init()
300{
301 bigerr_t res;
302 char modulus[80*4];
303
304 SL_ENTER(_("sh_srp_init"));
305
306 big_errno = BIG_OK;
307
308 res = big_init_pkg();
309
310 if (res == BIG_OK)
311 {
312 res = big_create(&sh_srp.p);
313 if (res == BIG_OK)
314 res = big_create(&sh_srp.g);
315 if (res == BIG_OK)
316 res = big_create(&sh_srp.a);
317 if (res == BIG_OK)
318 {
319 (void) sl_strlcpy(modulus, SRP_MODULUS_1024_1, sizeof(modulus));
320 (void) sl_strlcat(modulus, SRP_MODULUS_1024_2, sizeof(modulus));
321 (void) sl_strlcat(modulus, SRP_MODULUS_1024_3, sizeof(modulus));
322 (void) sl_strlcat(modulus, SRP_MODULUS_1024_4, sizeof(modulus));
323 }
324 if (res == BIG_OK)
325 res = big_set_string (modulus, 16, &sh_srp.p);
326 if (res == BIG_OK)
327 res = big_set_string (SRP_GENERATOR_1024, 16, &sh_srp.g);
328 if (res == BIG_OK)
329 {
330 SL_RETURN (0, _("sh_srp_init"));
331 }
332 else
333 sh_srp_exit();
334 }
335 SL_RETURN ((-1), _("sh_srp_init"));
336}
337
338
339int sh_srp_make_a ()
340{
341 UINT32 randl[6];
342 int i;
343 int res;
344 char hash[KEY_LEN+1];
345 char hashbuf[KEYBUF_SIZE];
346
347 SL_ENTER(_("sh_srp_make_a"));
348
349 for (i = 0; i < 6; ++i)
350 randl[i] = (UINT32) taus_get ();
351
352 (void) sl_strlcpy (hash,
353 sh_tiger_hash((char *)&randl[0], TIGER_DATA,
354 (unsigned long) 6*sizeof(UINT32),
355 hashbuf, sizeof(hashbuf)),
356 KEY_LEN+1);
357
358 hash[KEY_LEN] = '\0';
359
360 res = big_set_string (hash, 16, &sh_srp.a);
361 if (res == BIG_OK)
362 {
363 SL_RETURN((0), _("sh_srp_make_a"));
364 }
365 else
366 {
367 SL_RETURN((-1), _("sh_srp_make_a"));
368 }
369}
370
371/* return 0 if AB is NOT zero
372 */
373int sh_srp_check_zero (char * AB_str)
374{
375 bignum AB, q, r;
376 bigerr_t res;
377 int val;
378
379 SL_ENTER(_("sh_srp_check_zero"));
380
381 ASSERT_RET((AB_str != NULL), _("AB_str != NULL"), (-1));
382
383 res = big_create(&AB);
384 if (res == BIG_OK)
385 res = big_create(&q);
386 if (res == BIG_OK)
387 res = big_create(&r);
388
389 if (res == BIG_OK)
390 res = big_set_string (AB_str, 16, &AB);
391 if (res == BIG_OK)
392 res = big_trunc(&AB, &sh_srp.p, &q, &r); /* is last one the remainder ? */
393
394 if (res != BIG_OK) val = (-1);
395 else if (0 != big_zerop(&AB) ) val = (-1); /* 0 != (sign == 0) */
396 else if (0 != big_zerop(&r) ) val = (-1); /* 0 != (sign == 0) */
397 else val = 0;
398
399 big_destroy(&AB);
400 big_destroy(&q);
401 big_destroy(&r);
402
403 SL_RETURN((val), _("sh_srp_check_zero"));
404}
405
406#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
407
408
409char * sh_srp_A ()
410{
411 bignum A;
412 char *str;
413 char *combi;
414 bigerr_t res;
415
416 SL_ENTER(_("sh_srp_A"));
417
418 res = big_create(&A);
419
420 if (res == BIG_OK)
421 res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &A);
422
423 if (res == BIG_OK)
424 str = big_string (&A, 16);
425 else
426 str = NULL;
427
428 if (str != NULL)
429 combi = sh_util_strdup(str);
430 else
431 combi = NULL;
432
433 big_destroy(&A);
434 SL_RETURN(combi, _("sh_srp_A"));
435}
436
437/* #ifdef SH_WITH_CLIENT */
438#endif
439
440#ifdef SH_WITH_SERVER
441
442char * sh_srp_B (char * verifier)
443{
444 bignum B, v, t, dummy;
445 char *str;
446 char *combi;
447 bigerr_t res;
448
449 SL_ENTER(_("sh_srp_B"));
450
451 ASSERT_RET((verifier != NULL), _("verifier != NULL"), (NULL));
452
453 res = big_create(&dummy);
454
455 if (res == BIG_OK)
456 res = big_create(&t);
457 if (res == BIG_OK)
458 res = big_create(&v);
459 if (res == BIG_OK)
460 res = big_create(&B);
461
462 if (res == BIG_OK)
463 res = big_exptmod (&sh_srp.g, &sh_srp.a, &sh_srp.p, &t);
464
465 if (res == BIG_OK)
466 big_set_string (verifier, 16, &v);
467
468 if (res == BIG_OK)
469 res = big_add (&t, &v, &dummy);
470
471 if (res == BIG_OK)
472 {
473 if ( big_greaterp(&dummy, &sh_srp.p) )
474 res = big_sub(&dummy, &sh_srp.p, &B);
475 else
476 res = big_set_big(&dummy, &B);
477 }
478
479 if (res == BIG_OK)
480 str = big_string (&B, 16);
481 else
482 str = NULL;
483
484 if (str != NULL)
485 combi = sh_util_strdup(str);
486 else
487 combi = NULL;
488
489 big_destroy(&B);
490 big_destroy(&v);
491 big_destroy(&t);
492 big_destroy(&dummy);
493
494 SL_RETURN(combi, _("sh_srp_B"));
495}
496/* #ifdef SH_WITH_SERVER */
497#endif
498
499
500#if defined(SH_WITH_CLIENT) || defined(SH_WITH_SERVER)
501
502char * sh_srp_S_c (char * u_str, char * B_str)
503{
504 bignum u, B, x, t, base, z1, z2;
505 char *str;
506 char *combi;
507 bigerr_t res;
508
509 SL_ENTER(_("sh_srp_S_c"));
510
511 ASSERT_RET((u_str != NULL && B_str != NULL),
512 _("u_str != NULL && B_str != NULL"), (NULL));
513
514 big_errno = BIG_OK;
515
516 res = big_create(&z2);
517 if (res == BIG_OK)
518 res = big_create(&z1);
519 if (res == BIG_OK)
520 res = big_create(&base);
521 if (res == BIG_OK)
522 res = big_create(&t);
523 if (res == BIG_OK)
524 res = big_create(&x);
525 if (res == BIG_OK)
526 res = big_create(&B);
527 if (res == BIG_OK)
528 res = big_create(&u);
529
530 if (res == BIG_OK)
531 res = big_set_string (B_str, 16, &B);
532 if (res == BIG_OK)
533 res = big_set_string (sh_srp.x, 16, &x);
534 if (res == BIG_OK)
535 res = big_set_string (u_str, 16, &u);
536
537 /* the base (B - g^x)
538 */
539 if (res == BIG_OK)
540 res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &t);
541
542 if (res == BIG_OK)
543 {
544 if ( big_greaterp(&B, &t) != 0)
545 {
546 res = big_sub(&B, &t, &base);
547 }
548 else
549 {
550 res = big_add(&B, &sh_srp.p, &z2);
551 if (res == BIG_OK)
552 res = big_sub(&z2, &t, &base);
553 }
554 }
555
556 /* the exponent (a + ux)
557 */
558 if (res == BIG_OK)
559 res = big_mul (&u, &x, &t);
560 if (res == BIG_OK)
561 res = big_trunc(&t, &sh_srp.p, &z1, &z2); /* is last one the remainder ? */
562 if (res == BIG_OK)
563 res = big_add(&sh_srp.a, &z2, &z1);
564 if (res == BIG_OK)
565 {
566 if ( big_greaterp(&z1, &sh_srp.p) != 0)
567 res = big_sub(&z1, &sh_srp.p, &z2);
568 else
569 res = big_set_big(&z1, &z2);
570 }
571
572 if (res == BIG_OK)
573 res = big_exptmod (&base, &z2, &sh_srp.p, &t);
574
575 if (res == BIG_OK)
576 str = big_string (&t, 16);
577 else
578 str = NULL;
579
580 if (str != NULL)
581 combi = sh_util_strdup(str);
582 else
583 combi = NULL;
584
585 big_destroy(&z1);
586 big_destroy(&z2);
587 big_destroy(&base);
588 big_destroy(&t);
589 big_destroy(&x);
590 big_destroy(&B);
591 big_destroy(&u);
592
593 SL_RETURN(combi, _("sh_srp_S_c"));
594}
595
596/* #ifdef SH_WITH_CLIENT */
597#endif
598
599#ifdef SH_WITH_SERVER
600
601
602char * sh_srp_S_s (char * u_str, char * A_str, char * v_str)
603{
604 bignum u, A, v, t, base, z1, z2;
605 char *str;
606 char *combi;
607 bigerr_t res;
608
609 SL_ENTER(_("sh_srp_S_s"));
610
611 ASSERT_RET((u_str != NULL && A_str != NULL && v_str != NULL),
612 _("u_str != NULL && A_str != NULL && v_str != NULL"),
613 (NULL));
614
615 big_errno = BIG_OK;
616
617 res = big_create(&z2);
618 if (res == BIG_OK)
619 res = big_create(&z1);
620 if (res == BIG_OK)
621 res = big_create(&base);
622 if (res == BIG_OK)
623 res = big_create(&t);
624 if (res == BIG_OK)
625 res = big_create(&v);
626 if (res == BIG_OK)
627 res = big_create(&A);
628 if (res == BIG_OK)
629 res = big_create(&u);
630
631 if (res == BIG_OK)
632 res = big_set_string (A_str, 16, &A);
633 if (res == BIG_OK)
634 res = big_set_string (v_str, 16, &v);
635 if (res == BIG_OK)
636 res = big_set_string (u_str, 16, &u);
637
638 /* the base (Av^u)
639 */
640 if (res == BIG_OK)
641 res = big_exptmod (&v, &u, &sh_srp.p, &t);
642 if (res == BIG_OK)
643 res = big_mul (&A, &t, &z1);
644 if (res == BIG_OK)
645 res = big_trunc(&z1, &sh_srp.p, &z2, &base); /* is last the remainder ? */
646
647 if (res == BIG_OK)
648 res = big_exptmod (&base, &sh_srp.a, &sh_srp.p, &t);
649
650 if (res == BIG_OK)
651 str = big_string (&t, 16);
652 else
653 str = NULL;
654
655 if (str != NULL)
656 combi = sh_util_strdup(str);
657 else
658 combi = NULL;
659
660 big_destroy(&z1);
661 big_destroy(&z2);
662 big_destroy(&base);
663 big_destroy(&t);
664 big_destroy(&v);
665 big_destroy(&A);
666 big_destroy(&u);
667
668 SL_RETURN(combi, _("sh_srp_S_s"));
669}
670
671/* #ifdef SH_WITH_SERVER */
672#endif
673
674
675char * sh_srp_verifier (void)
676{
677 bignum x, v;
678 char *combi;
679 char *str;
680 bigerr_t res;
681
682 SL_ENTER(_("sh_srp_verifier"));
683
684 res = big_create(&x);
685 if (res == BIG_OK)
686 res = big_create(&v);
687
688 if (res == BIG_OK)
689 res = big_set_string (sh_srp.x, 16, &x);
690
691 if (res == BIG_OK)
692 res = big_exptmod (&sh_srp.g, &x, &sh_srp.p, &v);
693
694 if (res == BIG_OK)
695 str = big_string (&v, 16);
696 else
697 str = NULL;
698
699 if (str != NULL)
700 combi = sh_util_strdup(str);
701 else
702 combi = NULL;
703
704 big_destroy(&x);
705 big_destroy(&v);
706
707 SL_RETURN(combi, _("sh_srp_verifier"));
708}
709
710
711/* #if (defined (SH_WITH_CLIENT) || defined (SH_WITH_SERVER)) */
712
713#endif
714
715/* #ifdef USE_SRP_PROTOCOL */
716
717#endif
718
719
720#ifdef SH_CUTEST
721#include "CuTest.h"
722
723void Test_srp (CuTest *tc)
724{
725#if defined(USE_SRP_PROTOCOL) && (defined (SH_WITH_CLIENT) || defined (SH_WITH_SERVER))
726
727 int result;
728 char modulus[80*4];
729 bignum a, b, c;
730 bigerr_t res;
731 char *str = NULL;
732
733 res = sh_srp_init();
734 CuAssertTrue(tc, res == 0);
735
736 (void) sl_strlcpy(modulus, SRP_MODULUS_1024_1, sizeof(modulus));
737 (void) sl_strlcat(modulus, SRP_MODULUS_1024_2, sizeof(modulus));
738 (void) sl_strlcat(modulus, SRP_MODULUS_1024_3, sizeof(modulus));
739 (void) sl_strlcat(modulus, SRP_MODULUS_1024_4, sizeof(modulus));
740
741 res = big_create(&a);
742 CuAssertTrue(tc, res == BIG_OK);
743
744 /* Check plain zero
745 */
746 result = sh_srp_check_zero ("0");
747 CuAssertTrue(tc, result != 0);
748
749 res = big_set_string ("0", 16, &a);
750 CuAssertTrue(tc, res == BIG_OK);
751
752 result = sh_srp_check_zero (big_string(&a, 16));
753 CuAssertTrue(tc, result != 0);
754
755 /* Check modulus (equals 0 % M)
756 */
757 result = sh_srp_check_zero (modulus);
758 CuAssertTrue(tc, result != 0);
759
760 res = big_set_string (modulus, 16, &a);
761 CuAssertTrue(tc, res == BIG_OK);
762
763 result = sh_srp_check_zero (big_string(&a, 16));
764 CuAssertTrue(tc, result != 0);
765
766 /* Check non-zero
767 */
768 modulus[0] = 'a';
769
770 result = sh_srp_check_zero (modulus);
771 CuAssertTrue(tc, result == 0);
772
773 res = big_set_string (modulus, 16, &a);
774 CuAssertTrue(tc, res == BIG_OK);
775
776 result = sh_srp_check_zero (big_string(&a, 16));
777 CuAssertTrue(tc, result == 0);
778
779 modulus[0] = 'f';
780
781 /* Check multiple of modulus
782 */
783 res = big_set_string (modulus, 16, &a);
784 CuAssertTrue(tc, res == BIG_OK);
785
786 res = big_create(&b);
787 CuAssertTrue(tc, res == BIG_OK);
788
789 res = big_create(&c);
790 CuAssertTrue(tc, res == BIG_OK);
791
792 res = big_set_string ("deadbeef", 16, &b);
793 CuAssertTrue(tc, res == BIG_OK);
794
795 res = big_mul (&a, &b, &c);
796 CuAssertTrue(tc, res == BIG_OK);
797
798 str = strdup(big_string (&c, 16));
799 CuAssertPtrNotNull(tc, str);
800
801 result = sh_srp_check_zero (str);
802 CuAssertTrue(tc, result != 0);
803
804#else
805 (void) tc; /* fix compiler warning */
806#endif
807 return;
808}
809#endif
810
811
812
Note: See TracBrowser for help on using the repository browser.