source: trunk/src/sh_srp.c@ 562

Last change on this file since 562 was 560, checked in by katerina, 4 years ago

Fix for ticket #449 (gcc 10 compile issues).

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