From edc032b5e3f3ebb1006a9c89e0ae00504f47966f Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sat, 12 Mar 2011 17:01:19 +0000 Subject: Add SRP support. --- crypto/srp/.cvsignore | 2 + crypto/srp/Makefile | 96 ++++++++ crypto/srp/srp.h | 172 +++++++++++++ crypto/srp/srp_grps.h | 517 +++++++++++++++++++++++++++++++++++++++ crypto/srp/srp_lcl.h | 83 +++++++ crypto/srp/srp_lib.c | 357 +++++++++++++++++++++++++++ crypto/srp/srp_vfy.c | 660 ++++++++++++++++++++++++++++++++++++++++++++++++++ crypto/srp/srptest.c | 162 +++++++++++++ 8 files changed, 2049 insertions(+) create mode 100644 crypto/srp/.cvsignore create mode 100644 crypto/srp/Makefile create mode 100644 crypto/srp/srp.h create mode 100644 crypto/srp/srp_grps.h create mode 100644 crypto/srp/srp_lcl.h create mode 100644 crypto/srp/srp_lib.c create mode 100644 crypto/srp/srp_vfy.c create mode 100644 crypto/srp/srptest.c (limited to 'crypto/srp') diff --git a/crypto/srp/.cvsignore b/crypto/srp/.cvsignore new file mode 100644 index 0000000000..695fdd0059 --- /dev/null +++ b/crypto/srp/.cvsignore @@ -0,0 +1,2 @@ +Makefile.save +lib diff --git a/crypto/srp/Makefile b/crypto/srp/Makefile new file mode 100644 index 0000000000..d37d46c260 --- /dev/null +++ b/crypto/srp/Makefile @@ -0,0 +1,96 @@ +DIR= srp +TOP= ../.. +CC= cc +INCLUDES= -I.. -I$(TOP) -I../../include +CFLAG=-g +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKEDEPPROG= makedepend +MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG) +MAKEFILE= Makefile.ssl +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=srptest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=srp_lib.c srp_vfy.c +LIBOBJ=srp_lib.o srp_vfy.o + +SRC= $(LIBSRC) + +EXHEADER= srp.h +HEADER= $(EXHEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +srptest: top srptest.c $(LIB) + $(CC) $(CFLAGS) -Wall -Werror -g -o srptest srptest.c $(LIB) + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +srp_lib.o: ../../e_os.h ../../include/openssl/asn1.h +srp_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +srp_lib.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +srp_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +srp_lib.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +srp_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +srp_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +srp_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h +srp_lib.o: ../../include/openssl/sha.h ../../include/openssl/srp.h +srp_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +srp_lib.o: ../cryptlib.h srp_grps.h srp_lcl.h srp_lib.c +srp_vfy.o: ../../e_os.h ../../include/openssl/asn1.h +srp_vfy.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +srp_vfy.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +srp_vfy.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +srp_vfy.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +srp_vfy.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +srp_vfy.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +srp_vfy.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h +srp_vfy.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +srp_vfy.o: ../../include/openssl/srp.h ../../include/openssl/stack.h +srp_vfy.o: ../../include/openssl/symhacks.h ../../include/openssl/txt_db.h +srp_vfy.o: ../cryptlib.h srp_lcl.h srp_vfy.c diff --git a/crypto/srp/srp.h b/crypto/srp/srp.h new file mode 100644 index 0000000000..7ec7825cad --- /dev/null +++ b/crypto/srp/srp.h @@ -0,0 +1,172 @@ +/* crypto/srp/srp.h */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef __SRP_H__ +#define __SRP_H__ + +#ifndef OPENSSL_NO_SRP + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +typedef struct SRP_gN_cache_st + { + char *b64_bn; + BIGNUM *bn; + } SRP_gN_cache; + + +DECLARE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st + { + char *id; + BIGNUM *s; + BIGNUM *v; + const BIGNUM *g; + const BIGNUM *N; + char *info; + } SRP_user_pwd; + +DECLARE_STACK_OF(SRP_user_pwd) + +typedef struct SRP_VBASE_st + { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + BIGNUM *default_g; + BIGNUM *default_N; + } SRP_VBASE; + + +/*Structure interne pour retenir les couples N et g*/ +typedef struct SRP_gN_st + { + char *id; + BIGNUM *g; + BIGNUM *N; + } SRP_gN; + +DECLARE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +int SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char * verifier_file); +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g); + + +#define SRP_NO_ERROR 0 +#define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +#define SRP_ERR_VBASE_BN_LIB 2 +#define SRP_ERR_OPEN_FILE 3 +#define SRP_ERR_MEMORY 4 + +#define DB_srptype 0 +#define DB_srpverifier 1 +#define DB_srpsalt 2 +#define DB_srpid 3 +#define DB_srpgN 4 +#define DB_srpinfo 5 +#undef DB_NUMBER +#define DB_NUMBER 6 + +#define DB_SRP_INDEX 'I' +#define DB_SRP_VALID 'V' +#define DB_SRP_REVOKED 'R' +#define DB_SRP_MODIF 'v' + + +/* see srp.c */ +char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N); +SRP_gN *SRP_get_default_gN(const char * id) ; + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N); +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) ; + + + +/* client side .... */ +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u); +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); + +#define SRP_MINIMAL_N 1024 + +#ifdef __cplusplus +} +#endif + +#endif +#endif diff --git a/crypto/srp/srp_grps.h b/crypto/srp/srp_grps.h new file mode 100644 index 0000000000..d77c9fff4b --- /dev/null +++ b/crypto/srp/srp_grps.h @@ -0,0 +1,517 @@ +/* start of generated data */ + +static BN_ULONG bn_group_1024_value[] = { + bn_pack4(9FC6,1D2F,C0EB,06E3), + bn_pack4(FD51,38FE,8376,435B), + bn_pack4(2FD4,CBF4,976E,AA9A), + bn_pack4(68ED,BC3C,0572,6CC0), + bn_pack4(C529,F566,660E,57EC), + bn_pack4(8255,9B29,7BCF,1885), + bn_pack4(CE8E,F4AD,69B1,5D49), + bn_pack4(5DC7,D7B4,6154,D6B6), + bn_pack4(8E49,5C1D,6089,DAD1), + bn_pack4(E0D5,D8E2,50B9,8BE4), + bn_pack4(383B,4813,D692,C6E0), + bn_pack4(D674,DF74,96EA,81D3), + bn_pack4(9EA2,314C,9C25,6576), + bn_pack4(6072,6187,75FF,3C0B), + bn_pack4(9C33,F80A,FA8F,C5E8), + bn_pack4(EEAF,0AB9,ADB3,8DD6) +}; +static BIGNUM bn_group_1024 = { + bn_group_1024_value, + (sizeof bn_group_1024_value)/sizeof(BN_ULONG), + (sizeof bn_group_1024_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_1536_value[] = { + bn_pack4(CF76,E3FE,D135,F9BB), + bn_pack4(1518,0F93,499A,234D), + bn_pack4(8CE7,A28C,2442,C6F3), + bn_pack4(5A02,1FFF,5E91,479E), + bn_pack4(7F8A,2FE9,B8B5,292E), + bn_pack4(837C,264A,E3A9,BEB8), + bn_pack4(E442,734A,F7CC,B7AE), + bn_pack4(6577,2E43,7D6C,7F8C), + bn_pack4(DB2F,D53D,24B7,C486), + bn_pack4(6EDF,0195,3934,9627), + bn_pack4(158B,FD3E,2B9C,8CF5), + bn_pack4(764E,3F4B,53DD,9DA1), + bn_pack4(4754,8381,DBC5,B1FC), + bn_pack4(9B60,9E0B,E3BA,B63D), + bn_pack4(8134,B1C8,B979,8914), + bn_pack4(DF02,8A7C,EC67,F0D0), + bn_pack4(80B6,55BB,9A22,E8DC), + bn_pack4(1558,903B,A0D0,F843), + bn_pack4(51C6,A94B,E460,7A29), + bn_pack4(5F4F,5F55,6E27,CBDE), + bn_pack4(BEEE,A961,4B19,CC4D), + bn_pack4(DBA5,1DF4,99AC,4C80), + bn_pack4(B1F1,2A86,17A4,7BBB), + bn_pack4(9DEF,3CAF,B939,277A) +}; +static BIGNUM bn_group_1536 = { + bn_group_1536_value, + (sizeof bn_group_1536_value)/sizeof(BN_ULONG), + (sizeof bn_group_1536_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_2048_value[] = { + bn_pack4(0FA7,111F,9E4A,FF73), + bn_pack4(9B65,E372,FCD6,8EF2), + bn_pack4(35DE,236D,525F,5475), + bn_pack4(94B5,C803,D89F,7AE4), + bn_pack4(71AE,35F8,E9DB,FBB6), + bn_pack4(2A56,98F3,A8D0,C382), + bn_pack4(9CCC,041C,7BC3,08D8), + bn_pack4(AF87,4E73,03CE,5329), + bn_pack4(6160,2790,04E5,7AE6), + bn_pack4(032C,FBDB,F52F,B378), + bn_pack4(5EA7,7A27,75D2,ECFA), + bn_pack4(5445,23B5,24B0,D57D), + bn_pack4(5B9D,32E6,88F8,7748), + bn_pack4(F1D2,B907,8717,461A), + bn_pack4(76BD,207A,436C,6481), + bn_pack4(CA97,B43A,23FB,8016), + bn_pack4(1D28,1E44,6B14,773B), + bn_pack4(7359,D041,D5C3,3EA7), + bn_pack4(A80D,740A,DBF4,FF74), + bn_pack4(55F9,7993,EC97,5EEA), + bn_pack4(2918,A996,2F0B,93B8), + bn_pack4(661A,05FB,D5FA,AAE8), + bn_pack4(CF60,9517,9A16,3AB3), + bn_pack4(E808,3969,EDB7,67B0), + bn_pack4(CD7F,48A9,DA04,FD50), + bn_pack4(D523,12AB,4B03,310D), + bn_pack4(8193,E075,7767,A13D), + bn_pack4(A373,29CB,B4A0,99ED), + bn_pack4(FC31,9294,3DB5,6050), + bn_pack4(AF72,B665,1987,EE07), + bn_pack4(F166,DE5E,1389,582F), + bn_pack4(AC6B,DB41,324A,9A9B) +}; +static BIGNUM bn_group_2048 = { + bn_group_2048_value, + (sizeof bn_group_2048_value)/sizeof(BN_ULONG), + (sizeof bn_group_2048_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_3072_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(4B82,D120,A93A,D2CA), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_3072 = { + bn_group_3072_value, + (sizeof bn_group_3072_value)/sizeof(BN_ULONG), + (sizeof bn_group_3072_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_4096_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(4DF4,35C9,3406,3199), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_4096 = { + bn_group_4096_value, + (sizeof bn_group_4096_value)/sizeof(BN_ULONG), + (sizeof bn_group_4096_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_6144_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(E694,F91E,6DCC,4024), + bn_pack4(12BF,2D5B,0B74,74D6), + bn_pack4(043E,8F66,3F48,60EE), + bn_pack4(387F,E8D7,6E3C,0468), + bn_pack4(DA56,C9EC,2EF2,9632), + bn_pack4(EB19,CCB1,A313,D55C), + bn_pack4(F550,AA3D,8A1F,BFF0), + bn_pack4(06A1,D58B,B7C5,DA76), + bn_pack4(A797,15EE,F29B,E328), + bn_pack4(14CC,5ED2,0F80,37E0), + bn_pack4(CC8F,6D7E,BF48,E1D8), + bn_pack4(4BD4,07B2,2B41,54AA), + bn_pack4(0F1D,45B7,FF58,5AC5), + bn_pack4(23A9,7A7E,36CC,88BE), + bn_pack4(59E7,C97F,BEC7,E8F3), + bn_pack4(B5A8,4031,900B,1C9E), + bn_pack4(D55E,702F,4698,0C82), + bn_pack4(F482,D7CE,6E74,FEF6), + bn_pack4(F032,EA15,D172,1D03), + bn_pack4(5983,CA01,C64B,92EC), + bn_pack4(6FB8,F401,378C,D2BF), + bn_pack4(3320,5151,2BD7,AF42), + bn_pack4(DB7F,1447,E6CC,254B), + bn_pack4(44CE,6CBA,CED4,BB1B), + bn_pack4(DA3E,DBEB,CF9B,14ED), + bn_pack4(1797,27B0,865A,8918), + bn_pack4(B06A,53ED,9027,D831), + bn_pack4(E5DB,382F,4130,01AE), + bn_pack4(F8FF,9406,AD9E,530E), + bn_pack4(C975,1E76,3DBA,37BD), + bn_pack4(C1D4,DCB2,6026,46DE), + bn_pack4(36C3,FAB4,D27C,7026), + bn_pack4(4DF4,35C9,3402,8492), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_6144 = { + bn_group_6144_value, + (sizeof bn_group_6144_value)/sizeof(BN_ULONG), + (sizeof bn_group_6144_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_8192_value[] = { + bn_pack4(FFFF,FFFF,FFFF,FFFF), + bn_pack4(60C9,80DD,98ED,D3DF), + bn_pack4(C81F,56E8,80B9,6E71), + bn_pack4(9E30,50E2,7656,94DF), + bn_pack4(9558,E447,5677,E9AA), + bn_pack4(C919,0DA6,FC02,6E47), + bn_pack4(889A,002E,D5EE,382B), + bn_pack4(4009,438B,481C,6CD7), + bn_pack4(3590,46F4,EB87,9F92), + bn_pack4(FAF3,6BC3,1ECF,A268), + bn_pack4(B1D5,10BD,7EE7,4D73), + bn_pack4(F9AB,4819,5DED,7EA1), + bn_pack4(64F3,1CC5,0846,851D), + bn_pack4(4597,E899,A025,5DC1), + bn_pack4(DF31,0EE0,74AB,6A36), + bn_pack4(6D2A,13F8,3F44,F82D), + bn_pack4(062B,3CF5,B3A2,78A6), + bn_pack4(7968,3303,ED5B,DD3A), + bn_pack4(FA9D,4B7F,A2C0,87E8), + bn_pack4(4BCB,C886,2F83,85DD), + bn_pack4(3473,FC64,6CEA,306B), + bn_pack4(13EB,57A8,1A23,F0C7), + bn_pack4(2222,2E04,A403,7C07), + bn_pack4(E3FD,B8BE,FC84,8AD9), + bn_pack4(238F,16CB,E39D,652D), + bn_pack4(3423,B474,2BF1,C978), + bn_pack4(3AAB,639C,5AE4,F568), + bn_pack4(2576,F693,6BA4,2466), + bn_pack4(741F,A7BF,8AFC,47ED), + bn_pack4(3BC8,32B6,8D9D,D300), + bn_pack4(D8BE,C4D0,73B9,31BA), + bn_pack4(3877,7CB6,A932,DF8C), + bn_pack4(74A3,926F,12FE,E5E4), + bn_pack4(E694,F91E,6DBE,1159), + bn_pack4(12BF,2D5B,0B74,74D6), + bn_pack4(043E,8F66,3F48,60EE), + bn_pack4(387F,E8D7,6E3C,0468), + bn_pack4(DA56,C9EC,2EF2,9632), + bn_pack4(EB19,CCB1,A313,D55C), + bn_pack4(F550,AA3D,8A1F,BFF0), + bn_pack4(06A1,D58B,B7C5,DA76), + bn_pack4(A797,15EE,F29B,E328), + bn_pack4(14CC,5ED2,0F80,37E0), + bn_pack4(CC8F,6D7E,BF48,E1D8), + bn_pack4(4BD4,07B2,2B41,54AA), + bn_pack4(0F1D,45B7,FF58,5AC5), + bn_pack4(23A9,7A7E,36CC,88BE), + bn_pack4(59E7,C97F,BEC7,E8F3), + bn_pack4(B5A8,4031,900B,1C9E), + bn_pack4(D55E,702F,4698,0C82), + bn_pack4(F482,D7CE,6E74,FEF6), + bn_pack4(F032,EA15,D172,1D03), + bn_pack4(5983,CA01,C64B,92EC), + bn_pack4(6FB8,F401,378C,D2BF), + bn_pack4(3320,5151,2BD7,AF42), + bn_pack4(DB7F,1447,E6CC,254B), + bn_pack4(44CE,6CBA,CED4,BB1B), + bn_pack4(DA3E,DBEB,CF9B,14ED), + bn_pack4(1797,27B0,865A,8918), + bn_pack4(B06A,53ED,9027,D831), + bn_pack4(E5DB,382F,4130,01AE), + bn_pack4(F8FF,9406,AD9E,530E), + bn_pack4(C975,1E76,3DBA,37BD), + bn_pack4(C1D4,DCB2,6026,46DE), + bn_pack4(36C3,FAB4,D27C,7026), + bn_pack4(4DF4,35C9,3402,8492), + bn_pack4(86FF,B7DC,90A6,C08F), + bn_pack4(93B4,EA98,8D8F,DDC1), + bn_pack4(D006,9127,D5B0,5AA9), + bn_pack4(B81B,DD76,2170,481C), + bn_pack4(1F61,2970,CEE2,D7AF), + bn_pack4(233B,A186,515B,E7ED), + bn_pack4(99B2,964F,A090,C3A2), + bn_pack4(287C,5947,4E6B,C05D), + bn_pack4(2E8E,FC14,1FBE,CAA6), + bn_pack4(DBBB,C2DB,04DE,8EF9), + bn_pack4(2583,E9CA,2AD4,4CE8), + bn_pack4(1A94,6834,B615,0BDA), + bn_pack4(99C3,2718,6AF4,E23C), + bn_pack4(8871,9A10,BDBA,5B26), + bn_pack4(1A72,3C12,A787,E6D7), + bn_pack4(4B82,D120,A921,0801), + bn_pack4(43DB,5BFC,E0FD,108E), + bn_pack4(08E2,4FA0,74E5,AB31), + bn_pack4(7709,88C0,BAD9,46E2), + bn_pack4(BBE1,1757,7A61,5D6C), + bn_pack4(521F,2B18,177B,200C), + bn_pack4(D876,0273,3EC8,6A64), + bn_pack4(F12F,FA06,D98A,0864), + bn_pack4(CEE3,D226,1AD2,EE6B), + bn_pack4(1E8C,94E0,4A25,619D), + bn_pack4(ABF5,AE8C,DB09,33D7), + bn_pack4(B397,0F85,A6E1,E4C7), + bn_pack4(8AEA,7157,5D06,0C7D), + bn_pack4(ECFB,8504,58DB,EF0A), + bn_pack4(A855,21AB,DF1C,BA64), + bn_pack4(AD33,170D,0450,7A33), + bn_pack4(1572,8E5A,8AAA,C42D), + bn_pack4(15D2,2618,98FA,0510), + bn_pack4(3995,497C,EA95,6AE5), + bn_pack4(DE2B,CBF6,9558,1718), + bn_pack4(B5C5,5DF0,6F4C,52C9), + bn_pack4(9B27,83A2,EC07,A28F), + bn_pack4(E39E,772C,180E,8603), + bn_pack4(3290,5E46,2E36,CE3B), + bn_pack4(F174,6C08,CA18,217C), + bn_pack4(670C,354E,4ABC,9804), + bn_pack4(9ED5,2907,7096,966D), + bn_pack4(1C62,F356,2085,52BB), + bn_pack4(8365,5D23,DCA3,AD96), + bn_pack4(6916,3FA8,FD24,CF5F), + bn_pack4(98DA,4836,1C55,D39A), + bn_pack4(C200,7CB8,A163,BF05), + bn_pack4(4928,6651,ECE4,5B3D), + bn_pack4(AE9F,2411,7C4B,1FE6), + bn_pack4(EE38,6BFB,5A89,9FA5), + bn_pack4(0BFF,5CB6,F406,B7ED), + bn_pack4(F44C,42E9,A637,ED6B), + bn_pack4(E485,B576,625E,7EC6), + bn_pack4(4FE1,356D,6D51,C245), + bn_pack4(302B,0A6D,F25F,1437), + bn_pack4(EF95,19B3,CD3A,431B), + bn_pack4(514A,0879,8E34,04DD), + bn_pack4(020B,BEA6,3B13,9B22), + bn_pack4(2902,4E08,8A67,CC74), + bn_pack4(C4C6,628B,80DC,1CD1), + bn_pack4(C90F,DAA2,2168,C234), + bn_pack4(FFFF,FFFF,FFFF,FFFF) +}; +static BIGNUM bn_group_8192 = { + bn_group_8192_value, + (sizeof bn_group_8192_value)/sizeof(BN_ULONG), + (sizeof bn_group_8192_value)/sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_generator_19_value[] = {19} ; +static BIGNUM bn_generator_19 = { + bn_generator_19_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_5_value[] = {5} ; +static BIGNUM bn_generator_5 = { + bn_generator_5_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_2_value[] = {2} ; +static BIGNUM bn_generator_2 = { + bn_generator_2_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; + +static SRP_gN knowngN[] = { + {"8192",&bn_generator_19 , &bn_group_8192}, + {"6144",&bn_generator_5 , &bn_group_6144}, + {"4096",&bn_generator_5 , &bn_group_4096}, + {"3072",&bn_generator_5 , &bn_group_3072}, + {"2048",&bn_generator_2 , &bn_group_2048}, + {"1536",&bn_generator_2 , &bn_group_1536}, + {"1024",&bn_generator_2 , &bn_group_1024}, +}; +#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) + +/* end of generated data */ diff --git a/crypto/srp/srp_lcl.h b/crypto/srp/srp_lcl.h new file mode 100644 index 0000000000..42bda3f148 --- /dev/null +++ b/crypto/srp/srp_lcl.h @@ -0,0 +1,83 @@ +/* crypto/srp/srp_lcl.h */ +/* Written by Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_SRP_LCL_H +#define HEADER_SRP_LCL_H + +#include +#include + +#if 0 +#define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ + fprintf(stderr,"\n");} +#else +#define srp_bn_print(a) +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/crypto/srp/srp_lib.c b/crypto/srp/srp_lib.c new file mode 100644 index 0000000000..dbf464bbf4 --- /dev/null +++ b/crypto/srp/srp_lib.c @@ -0,0 +1,357 @@ +/* crypto/srp/srp_lib.c */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +#include "cryptlib.h" +#include "srp_lcl.h" +#include +#include + +#if (BN_BYTES == 8) +#define bn_pack4(a1,a2,a3,a4) 0x##a1##a2##a3##a4##ul +#endif +#if (BN_BYTES == 4) +#define bn_pack4(a1,a2,a3,a4) 0x##a3##a4##ul, 0x##a1##a2##ul +#endif +#if (BN_BYTES == 2) +#define bn_pack4(a1,a2,a3,a4) 0x##a4##u,0x##a3##u,0x##a2##u,0x##a1##u +#endif + + +#include "srp_grps.h" + +static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) + { + /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ + + unsigned char digest[SHA_DIGEST_LENGTH]; + unsigned char *tmp; + EVP_MD_CTX ctxt; + int longg ; + int longN = BN_num_bytes(N); + + if ((tmp = OPENSSL_malloc(longN)) == NULL) + return NULL; + BN_bn2bin(N,tmp) ; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, tmp, longN); + + memset(tmp, 0, longN); + longg = BN_bn2bin(g,tmp) ; + /* use the zeros behind to pad on left */ + EVP_DigestUpdate(&ctxt, tmp + longg, longN-longg); + EVP_DigestUpdate(&ctxt, tmp, longg); + OPENSSL_free(tmp); + + EVP_DigestFinal_ex(&ctxt, digest, NULL); + EVP_MD_CTX_cleanup(&ctxt); + return BN_bin2bn(digest, sizeof(digest), NULL); + } + +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) + { + /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ + + BIGNUM *u; + unsigned char cu[SHA_DIGEST_LENGTH]; + unsigned char *cAB; + EVP_MD_CTX ctxt; + int longN; + if ((A == NULL) ||(B == NULL) || (N == NULL)) + return NULL; + + longN= BN_num_bytes(N); + + if ((cAB = OPENSSL_malloc(2*longN)) == NULL) + return NULL; + + memset(cAB, 0, longN); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A,cAB+longN), longN); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B,cAB+longN), longN); + OPENSSL_free(cAB); + EVP_DigestFinal_ex(&ctxt, cu, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) + return NULL; + if (!BN_is_zero(u)) + return u; + BN_free(u); + return NULL; +} + +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, BIGNUM *N) + { + BIGNUM *tmp = NULL, *S = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) + return NULL; + + if ((bn_ctx = BN_CTX_new()) == NULL || + (tmp = BN_new()) == NULL || + (S = BN_new()) == NULL ) + goto err; + + /* S = (A*v**u) ** b */ + + if (!BN_mod_exp(tmp,v,u,N,bn_ctx)) + goto err; + if (!BN_mod_mul(tmp,A,tmp,N,bn_ctx)) + goto err; + if (!BN_mod_exp(S,tmp,b,N,bn_ctx)) + goto err; +err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + return S; + } + +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) + { + BIGNUM *kv = NULL, *gb = NULL; + BIGNUM *B = NULL, *k = NULL; + BN_CTX *bn_ctx; + + if (b == NULL || N == NULL || g == NULL || v == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ( (kv = BN_new()) == NULL || + (gb = BN_new()) == NULL || + (B = BN_new())== NULL) + goto err; + + /* B = g**b + k*v */ + + if (!BN_mod_exp(gb,g,b,N,bn_ctx) || + !(k = srp_Calc_k(N,g)) || + !BN_mod_mul(kv,v,k,N,bn_ctx) || + !BN_mod_add(B,gb,kv,N,bn_ctx)) + { + BN_free(B); + B = NULL; + } +err: + BN_CTX_free(bn_ctx); + BN_clear_free(kv); + BN_clear_free(gb); + BN_free(k); + return B; + } + +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) + { + unsigned char dig[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + unsigned char *cs; + + if ((s == NULL) || + (user == NULL) || + (pass == NULL)) + return NULL; + + if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) + return NULL; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, user, strlen(user)); + EVP_DigestUpdate(&ctxt, ":", 1); + EVP_DigestUpdate(&ctxt, pass, strlen(pass)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + BN_bn2bin(s,cs); + EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); + OPENSSL_free(cs); + EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + return BN_bin2bn(dig, sizeof(dig), NULL); + } + +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) + { + BN_CTX *bn_ctx; + BIGNUM * A = NULL; + + if (a == NULL || N == NULL || g == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((A = BN_new()) != NULL && + !BN_mod_exp(A,g,a,N,bn_ctx)) + { + BN_free(A); + A = NULL; + } + BN_CTX_free(bn_ctx); + return A; + } + + +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, BIGNUM *a, BIGNUM *u) + { + BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL , *k = NULL, *K = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL || a == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((tmp = BN_new()) == NULL || + (tmp2 = BN_new())== NULL || + (tmp3 = BN_new())== NULL || + (K = BN_new()) == NULL) + goto err; + + if (!BN_mod_exp(tmp,g,x,N,bn_ctx)) + goto err; + if (!(k = srp_Calc_k(N,g))) + goto err; + if (!BN_mod_mul(tmp2,tmp,k,N,bn_ctx)) + goto err; + if (!BN_mod_sub(tmp,B,tmp2,N,bn_ctx)) + goto err; + + if (!BN_mod_mul(tmp3,u,x,N,bn_ctx)) + goto err; + if (!BN_mod_add(tmp2,a,tmp3,N,bn_ctx)) + goto err; + if (!BN_mod_exp(K,tmp,tmp2,N,bn_ctx)) + goto err; + +err : + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + BN_clear_free(tmp2); + BN_clear_free(tmp3); + BN_free(k); + return K; + } + +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) + { + BIGNUM *r; + BN_CTX *bn_ctx; + int ret = 0; + + if (B == NULL || N == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return 0; + + if ((r = BN_new()) == NULL) + goto err; + /* Checks if B % N == 0 */ + if (!BN_nnmod(r,B,N,bn_ctx)) + goto err; + ret = !BN_is_zero(r); +err: + BN_CTX_free(bn_ctx); + BN_free(r); + return ret; + } + +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) + { + /* Checks if A % N == 0 */ + return SRP_Verify_B_mod_N(A,N) ; + } + + +/* Check if G and N are kwown parameters. + The values have been generated from the ietf-tls-srp draft version 8 +*/ +char * SRP_check_known_gN_param(BIGNUM* g, BIGNUM* N) + { + int i; + if ((g == NULL) || (N == NULL)) + return 0; + + srp_bn_print(g); + srp_bn_print(N); + + for(i = 0; i < KNOWN_GN_NUMBER; i++) + { + if (BN_cmp(knowngN[i].g,g) == 0 && BN_cmp(knowngN[i].N,N) == 0) + return knowngN[i].id; + } + return NULL; + } + +SRP_gN *SRP_get_default_gN(const char * id) + { + int i; + + if (id == NULL) + return knowngN; + for(i = 0; i < KNOWN_GN_NUMBER; i++) + { + if (strcmp(knowngN[i].id,id)==0) + return knowngN+i; + } + return NULL; + } +#endif diff --git a/crypto/srp/srp_vfy.c b/crypto/srp/srp_vfy.c new file mode 100644 index 0000000000..8b96a20d56 --- /dev/null +++ b/crypto/srp/srp_vfy.c @@ -0,0 +1,660 @@ +/* crypto/srp/srp_vfy.c */ +/* Written by Christophe Renou (christophe.renou@edelweb.fr) with + * the precious help of Peter Sylvester (peter.sylvester@edelweb.fr) + * for the EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +#include "cryptlib.h" +#include "srp_lcl.h" +#include +#include +#include +#include +#include + +#define SRP_RANDOM_SALT_LEN 20 +#define MAX_LEN 2500 + +static char b64table[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + +/* the following two conversion routines have been inspired by code from Stanford */ + +/* + * Convert a base64 string into raw byte array representation. + */ +static int t_fromb64(unsigned char *a, const char *src) + { + char *loc; + int i, j; + int size; + + while(*src && (*src == ' ' || *src == '\t' || *src == '\n')) + ++src; + size = strlen((const char *)src); + i = 0; + while(i < size) + { + loc = strchr(b64table, src[i]); + if(loc == (char *) 0) break; + else a[i] = loc - b64table; + ++i; + } + size = i; + i = size - 1; + j = size; + while(1) + { + a[j] = a[i]; + if(--i < 0) break; + a[j] |= (a[i] & 3) << 6; + --j; + a[j] = (unsigned char) ((a[i] & 0x3c) >> 2); + if(--i < 0) break; + a[j] |= (a[i] & 0xf) << 4; + --j; + a[j] = (unsigned char) ((a[i] & 0x30) >> 4); + if(--i < 0) break; + a[j] |= (a[i] << 2); + + a[--j] = 0; + if(--i < 0) break; + } + while(a[j] == 0 && j <= size) ++j; + i = 0; + while (j <= size) a[i++] = a[j++]; + return i; + } + + +/* + * Convert a raw byte string into a null-terminated base64 ASCII string. + */ +static char *t_tob64(char *dst, const unsigned char *src, int size) + { + int c, pos = size % 3; + unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0; + char *olddst = dst; + + switch(pos) + { + case 1: + b2 = src[0]; + break; + case 2: + b1 = src[0]; + b2 = src[1]; + break; + } + + while(1) + { + c = (b0 & 0xfc) >> 2; + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4); + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6); + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + c = b2 & 0x3f; + if(notleading || c != 0) + { + *dst++ = b64table[c]; + notleading = 1; + } + if(pos >= size) break; + else + { + b0 = src[pos++]; + b1 = src[pos++]; + b2 = src[pos++]; + } + } + + *dst++ = '\0'; + return olddst; + } + +static void SRP_user_pwd_free(SRP_user_pwd *user_pwd) + { + if (user_pwd == NULL) + return; + BN_free(user_pwd->s); + BN_clear_free(user_pwd->v); + OPENSSL_free(user_pwd->id); + OPENSSL_free(user_pwd->info); + OPENSSL_free(user_pwd); + } + +static SRP_user_pwd * SRP_user_pwd_new(void) + { + SRP_user_pwd * ret = OPENSSL_malloc(sizeof(SRP_user_pwd)); + if (ret == NULL) + return NULL; + ret->N = NULL; + ret->g = NULL; + ret->s = NULL; + ret->v = NULL; + ret->id = NULL ; + ret->info = NULL; + return ret; + } + +static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, + const BIGNUM *N) + { + vinfo->N = N; + vinfo->g = g; + } + +static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, + const char *info) + { + if (id != NULL && NULL == (vinfo->id = BUF_strdup(id))) + return 0; + return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))) ; + } + +static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, + const char *v) + { + unsigned char tmp[MAX_LEN]; + int len; + + if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) + return 0; + len = t_fromb64(tmp, v); + if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)) ) + return 0; + len = t_fromb64(tmp, s); + return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL) ; + } + +static int SRP_user_pwd_set_sv_BN(SRP_user_pwd * vinfo, BIGNUM * s, BIGNUM * v) + { + vinfo->v = v; + vinfo->s = s; + return (vinfo->s != NULL && vinfo->v != NULL) ; + } + +SRP_VBASE *SRP_VBASE_new(char *seed_key) + { + SRP_VBASE *vb = (SRP_VBASE *) OPENSSL_malloc(sizeof(SRP_VBASE)); + + if (vb == NULL) + return NULL; + if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) || + !(vb->gN_cache = sk_SRP_gN_cache_new_null())) + { + OPENSSL_free(vb); + return NULL; + } + vb->default_g = NULL; + vb->default_N = NULL; + vb->seed_key = NULL; + if ((seed_key != NULL) && + (vb->seed_key = BUF_strdup(seed_key)) == NULL) + { + sk_SRP_user_pwd_free(vb->users_pwd); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb); + return NULL; + } + return vb; + } + + +int SRP_VBASE_free(SRP_VBASE *vb) + { + sk_SRP_user_pwd_pop_free(vb->users_pwd,SRP_user_pwd_free); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb->seed_key); + OPENSSL_free(vb); + return 0; + } + + +static SRP_gN_cache *SRP_gN_new_init(const char *ch) + { + unsigned char tmp[MAX_LEN]; + int len; + + SRP_gN_cache *newgN = (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache)); + if (newgN == NULL) + return NULL; + + if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) + goto err; + + len = t_fromb64(tmp, ch); + if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) + return newgN; + + OPENSSL_free(newgN->b64_bn); +err: + OPENSSL_free(newgN); + return NULL; + } + + +static void SRP_gN_free(SRP_gN_cache *gN_cache) + { + if (gN_cache == NULL) + return; + OPENSSL_free(gN_cache->b64_bn); + BN_free(gN_cache->bn); + OPENSSL_free(gN_cache); + } + +static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) + { + int i; + + SRP_gN *gN; + if (gN_tab != NULL) + for(i = 0; i < sk_SRP_gN_num(gN_tab); i++) + { + gN = sk_SRP_gN_value(gN_tab, i); + if (gN && (id == NULL || strcmp(gN->id,id)==0)) + return gN; + } + + return SRP_get_default_gN(id); + } + +static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) + { + int i; + if (gN_cache == NULL) + return NULL; + + /* search if we have already one... */ + for(i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) + { + SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); + if (strcmp(cache->b64_bn,ch)==0) + return cache->bn; + } + { /* it is the first time that we find it */ + SRP_gN_cache *newgN = SRP_gN_new_init(ch); + if (newgN) + { + if (sk_SRP_gN_cache_insert(gN_cache,newgN,0)>0) + return newgN->bn; + SRP_gN_free(newgN); + } + } + return NULL; + } + +/* this function parses verifier file. Format is: + * string(index):base64(N):base64(g):0 + * string(username):base64(v):base64(salt):int(index) + */ + + +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) + { + int error_code ; + STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); + char *last_index = NULL; + int i; + char **pp; + + SRP_gN *gN = NULL; + SRP_user_pwd *user_pwd = NULL ; + + TXT_DB *tmpdb = NULL; + BIO *in = BIO_new(BIO_s_file()); + + error_code = SRP_ERR_OPEN_FILE; + + if (in == NULL || BIO_read_filename(in,verifier_file) <= 0) + goto err; + + error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; + + if ((tmpdb =TXT_DB_read(in,DB_NUMBER)) == NULL) + goto err; + + error_code = SRP_ERR_MEMORY; + + + if (vb->seed_key) + { + last_index = SRP_get_default_gN(NULL)->id; + } + for (i=0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) + { + pp=sk_OPENSSL_PSTRING_value(tmpdb->data,i); + if (pp[DB_srptype][0] == DB_SRP_INDEX) + { + /*we add this couple in the internal Stack */ + + if ((gN = (SRP_gN *)OPENSSL_malloc(sizeof(SRP_gN))) == NULL) + goto err; + + if (!(gN->id = BUF_strdup(pp[DB_srpid])) + || !(gN->N = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpverifier])) + || !(gN->g = SRP_gN_place_bn(vb->gN_cache,pp[DB_srpsalt])) + || sk_SRP_gN_insert(SRP_gN_tab,gN,0) == 0) + goto err; + + gN = NULL; + + if (vb->seed_key != NULL) + { + last_index = pp[DB_srpid]; + } + } + else if (pp[DB_srptype][0] == DB_SRP_VALID) + { + /* it is a user .... */ + SRP_gN *gN; + if ((gN = SRP_get_gN_by_id(pp[DB_srpgN],SRP_gN_tab))!=NULL) + { + error_code = SRP_ERR_MEMORY; + if ((user_pwd = SRP_user_pwd_new()) == NULL) + goto err; + + SRP_user_pwd_set_gN(user_pwd,gN->g,gN->N); + if (!SRP_user_pwd_set_ids(user_pwd, pp[DB_srpid], + pp[DB_srpinfo])) + goto err; + + error_code = SRP_ERR_VBASE_BN_LIB; + if (!SRP_user_pwd_set_sv(user_pwd, pp[DB_srpsalt], + pp[DB_srpverifier])) + goto err; + + if (sk_SRP_user_pwd_insert(vb->users_pwd,user_pwd,0) == 0) + goto err; + user_pwd = NULL; /* abandon responsability */ + } + } + } + + if (last_index != NULL) + { + /* this means that we want to simulate a default user */ + + if (((gN = SRP_get_gN_by_id(last_index,SRP_gN_tab))==NULL)) + { + error_code = SRP_ERR_VBASE_BN_LIB; + goto err; + } + vb->default_g = gN->g ; + vb->default_N = gN->N ; + gN = NULL ; + } + error_code = SRP_NO_ERROR; + + err: + /* there may be still some leaks to fix, if this fails, the application terminates most likely */ + + if (gN != NULL) + { + OPENSSL_free(gN->id); + OPENSSL_free(gN); + } + + SRP_user_pwd_free(user_pwd); + + if (tmpdb) TXT_DB_free(tmpdb); + if (in) BIO_free_all(in); + + sk_SRP_gN_free(SRP_gN_tab); + + return error_code; + + } + + +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) + { + int i; + SRP_user_pwd *user; + unsigned char digv[SHA_DIGEST_LENGTH]; + unsigned char digs[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + + if (vb == NULL) + return NULL; + for(i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) + { + user = sk_SRP_user_pwd_value(vb->users_pwd, i); + if (strcmp(user->id,username)==0) + return user; + } + if ((vb->seed_key == NULL) || + (vb->default_g == NULL) || + (vb->default_N == NULL)) + return NULL; + +/* if the user is unknown we set parameters as well if we have a seed_key */ + + if ((user = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(user,vb->default_g,vb->default_N); + + if (!SRP_user_pwd_set_ids(user,username,NULL)) + goto err; + + RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH); + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key)); + EVP_DigestUpdate(&ctxt, username, strlen(username)); + EVP_DigestFinal_ex(&ctxt, digs, NULL); + EVP_MD_CTX_cleanup(&ctxt); + if (SRP_user_pwd_set_sv_BN(user, BN_bin2bn(digs,SHA_DIGEST_LENGTH,NULL), BN_bin2bn(digv,SHA_DIGEST_LENGTH, NULL))) + return user; + +err: SRP_user_pwd_free(user); + return NULL; + } + + +/* + create a verifier (*salt,*verifier,g and N are in base64) +*/ +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g) + { + int len; + char * result=NULL; + char *vf; + BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL; + unsigned char tmp[MAX_LEN]; + unsigned char tmp2[MAX_LEN]; + char * defgNid = NULL; + + if ((user == NULL)|| + (pass == NULL)|| + (salt == NULL)|| + (verifier == NULL)) + goto err; + + if (N) + { + if (!(len = t_fromb64(tmp, N))) goto err; + N_bn = BN_bin2bn(tmp,len,NULL); + if (!(len = t_fromb64(tmp, g))) goto err; + g_bn = BN_bin2bn(tmp, len, NULL); + defgNid = "*"; + } + else + { + SRP_gN * gN = SRP_get_gN_by_id(g, NULL) ; + if (gN == NULL) + goto err; + N_bn = gN->N; + g_bn = gN->g; + defgNid = gN->id; + } + + if (*salt == NULL) + { + RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN); + + s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); + } + else + { + if (!(len = t_fromb64(tmp2, *salt))) + goto err; + s = BN_bin2bn(tmp2,len,NULL); + } + + + if(!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) goto err; + + BN_bn2bin(v,tmp); + if (((vf = OPENSSL_malloc(BN_num_bytes(v)*2)) == NULL)) + goto err; + t_tob64(vf, tmp, BN_num_bytes(v)); + + *verifier = vf; + if (*salt == NULL) + { + char *tmp_salt; + + if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN*2)) == NULL) + { + OPENSSL_free(vf); + goto err; + } + t_tob64(tmp_salt,tmp2,SRP_RANDOM_SALT_LEN); + *salt = tmp_salt; + } + + result=defgNid; + +err: + if(N) + { + BN_free(N_bn); + BN_free(g_bn); + } + return result; + } + +/* + create a verifier (*salt,*verifier,g and N are BIGNUMs) +*/ +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, BIGNUM **verifier, BIGNUM *N, BIGNUM *g) + { + int result=0; + BIGNUM *x = NULL; + BN_CTX *bn_ctx = BN_CTX_new(); + unsigned char tmp2[MAX_LEN]; + + if ((user == NULL)|| + (pass == NULL)|| + (salt == NULL)|| + (verifier == NULL)|| + (N == NULL)|| + (g == NULL)|| + (bn_ctx == NULL)) + goto err; + + srp_bn_print(N); + srp_bn_print(g); + + if (*salt == NULL) + { + RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN); + + *salt = BN_bin2bn(tmp2,SRP_RANDOM_SALT_LEN,NULL); + } + + x = SRP_Calc_x(*salt,user,pass); + + *verifier = BN_new(); + if(*verifier == NULL) goto err; + + if (!BN_mod_exp(*verifier,g,x,N,bn_ctx)) + { + BN_clear_free(*verifier); + goto err; + } + + srp_bn_print(*verifier); + + result=1; + +err: + + BN_clear_free(x); + BN_CTX_free(bn_ctx); + return result; + } + + + +#endif diff --git a/crypto/srp/srptest.c b/crypto/srp/srptest.c new file mode 100644 index 0000000000..04b66b4544 --- /dev/null +++ b/crypto/srp/srptest.c @@ -0,0 +1,162 @@ +#include +#ifdef OPENSSL_NO_SRP + +#include + +int main(int argc, char *argv[]) + { + printf("No SRP support\n"); + return(0); + } + +#else + +#include +#include +#include + +static void showbn(const char *name, const BIGNUM *bn) + { + fputs(name, stdout); + fputs(" = ", stdout); + BN_print_fp(stdout, bn); + putc('\n', stdout); + } + +#define RANDOM_SIZE 32 /* use 256 bits on each side */ + +static int run_srp(const char *username, const char *client_pass, const char *server_pass) + { + int ret=-1; + BIGNUM *s = NULL; + BIGNUM *v = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *u = NULL; + BIGNUM *x = NULL; + BIGNUM *Apub = NULL; + BIGNUM *Bpub = NULL; + BIGNUM *Kclient = NULL; + BIGNUM *Kserver = NULL; + unsigned char rand_tmp[RANDOM_SIZE]; + /* use builtin 1024-bit params */ + SRP_gN *GN = SRP_get_default_gN("1024"); + + if(GN == NULL) + { + fprintf(stderr, "Failed to get SRP parameters\n"); + return -1; + } + /* Set up server's password entry */ + if(!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) + { + fprintf(stderr, "Failed to create SRP verifier\n"); + return -1; + } + + showbn("N", GN->N); + showbn("g", GN->g); + showbn("Salt", s); + showbn("Verifier", v); + + /* Server random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check b != 0 */ + showbn("b", b); + + /* Server's first message */ + Bpub = SRP_Calc_B(b, GN->N, GN->g, v); + showbn("B", Bpub); + + if(!SRP_Verify_B_mod_N(Bpub, GN->N)) + { + fprintf(stderr, "Invalid B\n"); + return -1; + } + + /* Client random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check a != 0 */ + showbn("a", a); + + /* Client's response */ + Apub = SRP_Calc_A(a, GN->N, GN->g); + showbn("A", Apub); + + if(!SRP_Verify_A_mod_N(Apub, GN->N)) + { + fprintf(stderr, "Invalid A\n"); + return -1; + } + + /* Both sides calculate u */ + u = SRP_Calc_u(Apub, Bpub, GN->N); + + /* Client's key */ + x = SRP_Calc_x(s, username, client_pass); + Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); + showbn("Client's key", Kclient); + + /* Server's key */ + Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); + showbn("Server's key", Kserver); + + if(BN_cmp(Kclient, Kserver) == 0) + { + ret = 0; + } + else + { + fprintf(stderr, "Keys mismatch\n"); + ret = 1; + } + + BN_clear_free(Kclient); + BN_clear_free(Kserver); + BN_clear_free(x); + BN_free(u); + BN_free(Apub); + BN_clear_free(a); + BN_free(Bpub); + BN_clear_free(b); + BN_free(s); + BN_clear_free(v); + + return ret; + } + +int main(int argc, char **argv) + { + BIO *bio_err; + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /* "Negative" test, expect a mismatch */ + if(run_srp("alice", "password1", "password2") == 0) + { + fprintf(stderr, "Mismatched SRP run failed\n"); + return 1; + } + + /* "Positive" test, should pass */ + if(run_srp("alice", "password", "password") != 0) + { + fprintf(stderr, "Plain SRP run failed\n"); + return 1; + } + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + + return 0; + } +#endif -- cgit v1.2.3