From: Dmitry Belyavskiy Date: Sat, 15 Aug 2015 11:29:47 +0000 (+0300) Subject: Merge branch 'no_gost94_sig' into gost12_algs X-Git-Tag: v1.1.0.2~53 X-Git-Url: http://www.wagner.pp.ru/gitweb/?a=commitdiff_plain;h=57d07eb0dc22bee10aebb0bd37cbdf2258413564;hp=-c;p=openssl-gost%2Fengine.git Merge branch 'no_gost94_sig' into gost12_algs Conflicts: Makefile e_gost_err.c e_gost_err.h gost2001.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_eng.c gost_lcl.h gost_params.c gost_params.h gost_pmeth.c gost_sign.c --- 57d07eb0dc22bee10aebb0bd37cbdf2258413564 diff --combined Makefile index 9004e12,3c1e4f9..10e41ce --- a/Makefile +++ b/Makefile @@@ -8,16 -8,16 +8,16 @@@ AR= ar CFLAGS= $(INCLUDES) $(CFLAG) LIB=$(TOP)/libcrypto.a - LIBSRC= gost_md2012.c gosthash2012.c gost_ec_sign.c gost_ec_keyx.c gost89.c gost94_keyx.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c gost_sign.c -LIBSRC= gost2001.c gost2001_keyx.c gost89.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_pmeth.c gost_params.c ++LIBSRC= gost_md2012.c gosthash2012.c gost_ec_sign.c gost_ec_keyx.c gost89.c gost_ameth.c gost_asn1.c gost_crypt.c gost_ctl.c gost_eng.c gosthash.c gost_keywrap.c gost_md.c gost_params.c gost_pmeth.c - LIBOBJ= gost_md2012.o gosthash2012.o e_gost_err.o gost_ec_keyx.o gost_ec_sign.o gost89.o gost94_keyx.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o gost_sign.o -LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.o gost89.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_pmeth.o gost_params.o ++LIBOBJ= gost_md2012.o gosthash2012.o e_gost_err.o gost_ec_keyx.o gost_ec_sign.o gost89.o gost_ameth.o gost_asn1.o gost_crypt.o gost_ctl.o gost_eng.o gosthash.o gost_keywrap.o gost_md.o gost_params.o gost_pmeth.o SRC=$(LIBSRC) LIBNAME=gost top: - (cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all) + (cd $(TOP); $(MAKE) DIRS=engines sub_all) all: lib @@@ -50,7 -50,6 +50,6 @@@ install cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \ else \ case "$(CFLAGS)" in \ - *DSO_BEOS*) sfx=".so";; \ *DSO_DLFCN*) sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;; \ *DSO_DL*) sfx=".sl";; \ *DSO_WIN32*) sfx="eay32.dll"; pfx=;; \ @@@ -62,8 -61,6 +61,6 @@@ mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx; \ fi - links: - tests: update: local_depend @@@ -85,80 -82,46 +82,14 @@@ dclean mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll *.dylib # DO NOT DELETE THIS LINE -- make depend depends on it. - gost_ec_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h - gost_ec_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h - gost_ec_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h - gost_ec_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h - gost_ec_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h - gost_ec_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h - gost_ec_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h - gost_ec_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h - gost_ec_sign.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h - gost_ec_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h - gost_ec_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h - gost_ec_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h - gost_ec_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h - gost_ec_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h - gost_ec_sign.o: e_gost_err.h gost_ec_sign.c gost89.h gost_lcl.h gost_params.h - gost_ec_sign.o: gosthash.h - gost_ec_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h - gost_ec_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h - gost_ec_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h - gost_ec_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h - gost_ec_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h - gost_ec_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h - gost_ec_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h - gost_ec_keyx.o: ../../include/openssl/obj_mac.h - gost_ec_keyx.o: ../../include/openssl/objects.h - gost_ec_keyx.o: ../../include/openssl/opensslconf.h - gost_ec_keyx.o: ../../include/openssl/opensslv.h - gost_ec_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h - gost_ec_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h - gost_ec_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h - gost_ec_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h - gost_ec_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost_ec_keyx.c - gost_ec_keyx.o: gost89.h gost_keywrap.h gost_lcl.h gosthash.h - gosthash2012.o: gosthash2012_const.h - gosthash2012.o: gosthash2012.c gosthash2012.h - gosthash2012.o: gosthash2012_precalc.h gosthash2012_ref.h - gost_md2012.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h - gost_md2012.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h - gost_md2012.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h - gost_md2012.o: ../../include/openssl/objects.h - gost_md2012.o: ../../include/openssl/opensslconf.h - gost_md2012.o: ../../include/openssl/opensslv.h - gost_md2012.o: ../../include/openssl/ossl_typ.h - gost_md2012.o: ../../include/openssl/safestack.h - gost_md2012.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h - gost_md2012.o: gosthash2012_const.h - gost_md2012.o: gosthash2012.h gosthash2012_precalc.h - gost_md2012.o: gosthash2012_ref.h gost_md2012.c -gost2001.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h -gost2001.o: ../../include/openssl/bio.h ../../include/openssl/bn.h -gost2001.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -gost2001.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h -gost2001.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h -gost2001.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h -gost2001.o: ../../include/openssl/err.h ../../include/openssl/evp.h -gost2001.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h -gost2001.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h -gost2001.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h -gost2001.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h -gost2001.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h -gost2001.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h -gost2001.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h -gost2001.o: e_gost_err.h gost2001.c gost89.h gost_lcl.h gosthash.h -gost2001_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h -gost2001_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h -gost2001_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h -gost2001_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h -gost2001_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h -gost2001_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h -gost2001_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h -gost2001_keyx.o: ../../include/openssl/obj_mac.h -gost2001_keyx.o: ../../include/openssl/objects.h -gost2001_keyx.o: ../../include/openssl/opensslconf.h -gost2001_keyx.o: ../../include/openssl/opensslv.h -gost2001_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h -gost2001_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h -gost2001_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h -gost2001_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h -gost2001_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost2001_keyx.c -gost2001_keyx.o: gost2001_keyx.h gost89.h gost_keywrap.h gost_lcl.h gosthash.h gost89.o: gost89.c gost89.h - gost94_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h - gost94_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h - gost94_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h - gost94_keyx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h - gost94_keyx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h - gost94_keyx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h - gost94_keyx.o: ../../include/openssl/engine.h ../../include/openssl/evp.h - gost94_keyx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h - gost94_keyx.o: ../../include/openssl/objects.h - gost94_keyx.o: ../../include/openssl/opensslconf.h - gost94_keyx.o: ../../include/openssl/opensslv.h - gost94_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h - gost94_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h - gost94_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h - gost94_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h - gost94_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h - gost94_keyx.o: gost94_keyx.c gost_keywrap.h gost_lcl.h gosthash.h gost_ameth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h gost_ameth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h - gost_ameth.o: ../../include/openssl/conf.h gost_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h gost_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h gost_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h @@@ -170,9 -133,8 +101,8 @@@ gost_ameth.o: ../../include/openssl/ope gost_ameth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h gost_ameth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h gost_ameth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h - gost_ameth.o: ../../include/openssl/x509v3.h gost_ameth.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h - gost_ameth.o: gost_ameth.c gost_lcl.h gost_params.h gosthash.h + gost_ameth.o: gost_ameth.c gost_lcl.h gosthash.h gost_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h gost_asn1.o: ../../include/openssl/bio.h ../../include/openssl/bn.h gost_asn1.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h @@@ -194,8 -156,9 +124,9 @@@ gost_crypt.o: ../../include/openssl/buf gost_crypt.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h gost_crypt.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h gost_crypt.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h - gost_crypt.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h - gost_crypt.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h + gost_crypt.o: ../../include/openssl/err.h ../../include/openssl/evp.h + gost_crypt.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h + gost_crypt.o: ../../include/openssl/objects.h gost_crypt.o: ../../include/openssl/opensslconf.h gost_crypt.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h gost_crypt.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h @@@ -218,6 -181,6 +149,39 @@@ gost_ctl.o: ../../include/openssl/sha. gost_ctl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h gost_ctl.o: ../../include/openssl/x509_vfy.h gost89.h gost_ctl.c gost_lcl.h gost_ctl.o: gosthash.h ++gost_ec_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h ++gost_ec_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h ++gost_ec_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h ++gost_ec_keyx.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h ++gost_ec_keyx.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h ++gost_ec_keyx.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h ++gost_ec_keyx.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h ++gost_ec_keyx.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h ++gost_ec_keyx.o: ../../include/openssl/opensslconf.h ++gost_ec_keyx.o: ../../include/openssl/opensslv.h ++gost_ec_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h ++gost_ec_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h ++gost_ec_keyx.o: ../../include/openssl/sha.h ../../include/openssl/stack.h ++gost_ec_keyx.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h ++gost_ec_keyx.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h ++gost_ec_keyx.o: gost_ec_keyx.c gost_keywrap.h gost_lcl.h gosthash.h ++gost_ec_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h ++gost_ec_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h ++gost_ec_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h ++gost_ec_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h ++gost_ec_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h ++gost_ec_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h ++gost_ec_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h ++gost_ec_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h ++gost_ec_sign.o: ../../include/openssl/objects.h ++gost_ec_sign.o: ../../include/openssl/opensslconf.h ++gost_ec_sign.o: ../../include/openssl/opensslv.h ++gost_ec_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h ++gost_ec_sign.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h ++gost_ec_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h ++gost_ec_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h ++gost_ec_sign.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h ++gost_ec_sign.o: gost_ec_sign.c gost_lcl.h gosthash.h gost_eng.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h gost_eng.o: ../../include/openssl/bio.h ../../include/openssl/bn.h gost_eng.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h @@@ -248,47 -211,35 +212,63 @@@ gost_md.o: ../../include/openssl/safest gost_md.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h gost_md.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h gost_md.o: e_gost_err.h gost89.h gost_lcl.h gost_md.c gosthash.h - gost_params.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h - gost_params.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++gost_md2012.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h ++gost_md2012.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h ++gost_md2012.o: ../../include/openssl/evp.h ../../include/openssl/obj_mac.h ++gost_md2012.o: ../../include/openssl/objects.h ++gost_md2012.o: ../../include/openssl/opensslconf.h ++gost_md2012.o: ../../include/openssl/opensslv.h ++gost_md2012.o: ../../include/openssl/ossl_typ.h ++gost_md2012.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h ++gost_md2012.o: ../../include/openssl/symhacks.h gost_md2012.c gosthash2012.h ++gost_md2012.o: gosthash2012_const.h gosthash2012_precalc.h gosthash2012_sse2.h + gost_params.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h + gost_params.o: ../../include/openssl/bio.h ../../include/openssl/bn.h + gost_params.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h + gost_params.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h + gost_params.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h + gost_params.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h + gost_params.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h gost_params.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h gost_params.o: ../../include/openssl/opensslconf.h gost_params.o: ../../include/openssl/opensslv.h - gost_params.o: ../../include/openssl/ossl_typ.h - gost_params.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h - gost_params.o: ../../include/openssl/symhacks.h gost_params.c gost_params.h + gost_params.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h + gost_params.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h + gost_params.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h + gost_params.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h + gost_params.o: gost89.h gost_lcl.h gost_params.c gosthash.h gost_pmeth.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h gost_pmeth.o: ../../include/openssl/bio.h ../../include/openssl/bn.h gost_pmeth.o: ../../include/openssl/buffer.h ../../include/openssl/conf.h - gost_pmeth.o: ../../include/openssl/cms.h ../../include/openssl/err.h gost_pmeth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h gost_pmeth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h gost_pmeth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h - gost_pmeth.o: ../../include/openssl/engine.h ../../include/openssl/evp.h - gost_pmeth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h - gost_pmeth.o: ../../include/openssl/objects.h + gost_pmeth.o: ../../include/openssl/engine.h ../../include/openssl/err.h + gost_pmeth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h + gost_pmeth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h gost_pmeth.o: ../../include/openssl/opensslconf.h gost_pmeth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h gost_pmeth.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h gost_pmeth.o: ../../include/openssl/sha.h ../../include/openssl/stack.h gost_pmeth.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h gost_pmeth.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h - gost_pmeth.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_pmeth.c - gost_pmeth.o: gosthash.h + gost_pmeth.o: e_gost_err.h gost89.h gost_lcl.h gost_pmeth.c gosthash.h +gost_sign.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +gost_sign.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +gost_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +gost_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_sign.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_sign.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h +gost_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +gost_sign.o: ../../include/openssl/objects.h +gost_sign.o: ../../include/openssl/opensslconf.h +gost_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +gost_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h +gost_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +gost_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +gost_sign.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h - gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_params.h gost_sign.c - gost_sign.o: gosthash.h ++gost_sign.o: e_gost_err.h gost89.h gost_lcl.h gost_sign.c gosthash.h gosthash.o: gost89.h gosthash.c gosthash.h ++gosthash2012.o: gosthash2012.c gosthash2012.h gosthash2012_const.h ++gosthash2012.o: gosthash2012_precalc.h gosthash2012_sse2.h diff --combined e_gost_err.c index b313c53,d05ef61..c641c60 --- a/e_gost_err.c +++ b/e_gost_err.c @@@ -72,51 -72,35 +72,51 @@@ static ERR_STRING_DATA GOST_str_functs[] = { {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, {ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST_EC_PARAMS), "FILL_GOST_EC_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, + {ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, ++ {ERR_FUNC(GOST_F_FILL_GOST_EC_PARAMS), "FILL_GOST_EC_PARAMS"}, {ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"}, - {ERR_FUNC(GOST_F_GOST_EC_COMPUTE_PUBLIC), "GOST_EC_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST_EC_SIGN), "GOST_EC_SIGN"}, - {ERR_FUNC(GOST_F_GOST_EC_VERIFY), "GOST_EC_VERIFY"}, - {ERR_FUNC(GOST_F_GOST_EC_KEYGEN), "GOST_EC_KEYGEN"}, - {ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, - {ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, - {ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"}, {ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), "GOST89_GET_ASN1_PARAMETERS"}, {ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "GOST89_SET_ASN1_PARAMETERS"}, + {ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"}, {ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"}, + {ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, + {ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, ++ {ERR_FUNC(GOST_F_GOST_EC_COMPUTE_PUBLIC), "GOST_EC_COMPUTE_PUBLIC"}, ++ {ERR_FUNC(GOST_F_GOST_EC_KEYGEN), "GOST_EC_KEYGEN"}, ++ {ERR_FUNC(GOST_F_GOST_EC_SIGN), "GOST_EC_SIGN"}, ++ {ERR_FUNC(GOST_F_GOST_EC_VERIFY), "GOST_EC_VERIFY"}, {ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"}, {ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"}, {ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"}, + {ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST_EC), "PARAM_COPY_GOST_EC"}, - {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, - {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_DECRYPT), "PKEY_GOST_ECCP_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_ENCRYPT), "PKEY_GOST_ECCP_ENCRYPT"}, {ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST_EC_DERIVE), "PKEY_GOST_EC_DERIVE"}, - {ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"}, + {ERR_FUNC(GOST_F_PKEY_GOST12_PARAMGEN), "PKEY_GOST12_PARAMGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "PKEY_GOST94CP_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "PKEY_GOST94CP_ENCRYPT"}, ++ {ERR_FUNC(GOST_F_PKEY_GOST94_CTRL_STR), "PKEY_GOST94_CTRL_STR"}, + {ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"}, {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, - {ERR_FUNC(GOST_F_PKEY_GOST94_CTRL_STR), "PKEY_GOST94_CTRL_STR"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, ++ {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_DECRYPT), "PKEY_GOST_ECCP_DECRYPT"}, ++ {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_ENCRYPT), "PKEY_GOST_ECCP_ENCRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST_EC_CTRL_STR_256), "PKEY_GOST_EC_CTRL_STR_256"}, + {ERR_FUNC(GOST_F_PKEY_GOST_EC_CTRL_STR_512), "PKEY_GOST_EC_CTRL_STR_512"}, ++ {ERR_FUNC(GOST_F_PKEY_GOST_EC_DERIVE), "PKEY_GOST_EC_DERIVE"}, {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL), "PKEY_GOST_MAC_CTRL"}, {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"}, {ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"}, - {ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"}, + {ERR_FUNC(GOST_F_PRINT_GOST_EC_PUB), "PRINT_GOST_EC_PUB"}, {ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"}, - {ERR_FUNC(GOST_F_PUB_DECODE_GOST_EC), "PUB_DECODE_GOST_EC"}, + {ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, + {ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, - {ERR_FUNC(GOST_F_PUB_ENCODE_GOST_EC), "PUB_ENCODE_GOST_EC"}, ++ {ERR_FUNC(GOST_F_PUB_DECODE_GOST_EC), "PUB_DECODE_GOST_EC"}, + {ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, + {ERR_FUNC(GOST_F_PUB_ENCODE_GOST94), "PUB_ENCODE_GOST94"}, ++ {ERR_FUNC(GOST_F_PUB_ENCODE_GOST_EC), "PUB_ENCODE_GOST_EC"}, + {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, + {ERR_FUNC(GOST_F_VKO_COMPUTE_KEY), "VKO_COMPUTE_KEY"}, {0, NULL} }; @@@ -130,8 -114,6 +130,6 @@@ static ERR_STRING_DATA GOST_str_reasons {ERR_REASON(GOST_R_CTRL_CALL_FAILED), "ctrl call failed"}, {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY), "error computing shared key"}, - {ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO), - "error packing key transport info"}, {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO), "error parsing key transport info"}, {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS), "incompatible algorithms"}, @@@ -139,16 -121,12 +137,15 @@@ {ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS), "invalid cipher params"}, {ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID), "invalid cipher param oid"}, {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE), "invalid digest type"}, - {ERR_REASON(GOST_R_INVALID_GOST94_PARMSET), "invalid gost94 parmset"}, {ERR_REASON(GOST_R_INVALID_IV_LENGTH), "invalid iv length"}, {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"}, {ERR_REASON(GOST_R_INVALID_PARAMSET), "invalid paramset"}, + {ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED), "key is not initalized"}, {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED), "key is not initialized"}, {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING), "key parameters missing"}, {ERR_REASON(GOST_R_MAC_KEY_NOT_SET), "mac key not set"}, + {ERR_REASON(GOST_R_MALLOC_FAILURE), "malloc failure"}, + {ERR_REASON(GOST_R_NO_MEMORY), "no memory"}, {ERR_REASON(GOST_R_NO_PARAMETERS_SET), "no parameters set"}, {ERR_REASON(GOST_R_NO_PEER_KEY), "no peer key"}, {ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR), diff --combined e_gost_err.h index 574742b,b183957..5e7e8e4 --- a/e_gost_err.h +++ b/e_gost_err.h @@@ -1,12 -1,12 +1,12 @@@ /* ==================================================================== -- * Copyright (c) 2001-2005 The OpenSSL Project. All rights reserved. ++ * Copyright (c) 2001-2015 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. ++ * 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 @@@ -53,7 -53,7 +53,7 @@@ */ #ifndef HEADER_GOST_ERR_H --# define HEADER_GOST_ERR_H ++#define HEADER_GOST_ERR_H #ifdef __cplusplus extern "C" { @@@ -72,87 -72,84 +72,85 @@@ void ERR_GOST_error(int function, int r /* Error codes for the GOST functions. */ /* Function codes. */ --# define GOST_F_DECODE_GOST_ALGOR_PARAMS 99 --# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100 - # define GOST_F_FILL_GOST_EC_PARAMS 101 -# define GOST_F_FILL_GOST2001_PARAMS 101 ++# define GOST_F_DECODE_GOST_ALGOR_PARAMS 100 ++# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 101 # define GOST_F_FILL_GOST94_PARAMS 102 --# define GOST_F_GET_ENCRYPTION_PARAMS 103 - # define GOST_F_GOST_EC_COMPUTE_PUBLIC 104 - # define GOST_F_GOST_EC_SIGN 105 - # define GOST_F_GOST_EC_VERIFY 106 - # define GOST_F_GOST_EC_KEYGEN 107 -# define GOST_F_GOST2001_COMPUTE_PUBLIC 104 -# define GOST_F_GOST2001_DO_SIGN 105 -# define GOST_F_GOST2001_DO_VERIFY 106 -# define GOST_F_GOST2001_KEYGEN 107 --# define GOST_F_GOST89_GET_ASN1_PARAMETERS 108 --# define GOST_F_GOST89_SET_ASN1_PARAMETERS 109 --# define GOST_F_GOST94_COMPUTE_PUBLIC 110 --# define GOST_F_GOST_CIPHER_CTL 111 --# define GOST_F_GOST_DO_SIGN 112 --# define GOST_F_GOST_DO_VERIFY 113 --# define GOST_F_GOST_IMIT_CTRL 114 - # define GOST_F_GOST_IMIT_FINAL 120 -# define GOST_F_GOST_IMIT_FINAL 140 --# define GOST_F_GOST_IMIT_UPDATE 115 --# define GOST_F_GOST_SIGN_KEYGEN 142 - # define GOST_F_PARAM_COPY_GOST_EC 116 -# define GOST_F_PARAM_COPY_GOST01 116 --# define GOST_F_PARAM_COPY_GOST94 117 - # define GOST_F_PKEY_GOST_ECCP_DECRYPT 118 - # define GOST_F_PKEY_GOST_ECCP_ENCRYPT 119 -# define GOST_F_PKEY_GOST01CP_DECRYPT 118 -# define GOST_F_PKEY_GOST01CP_ENCRYPT 119 -# define GOST_F_PKEY_GOST01CP_KEYGEN 120 --# define GOST_F_PKEY_GOST01_PARAMGEN 138 - # define GOST_F_PKEY_GOST12_PARAMGEN 143 - # define GOST_F_PKEY_GOST_EC_DERIVE 121 -# define GOST_F_PKEY_GOST2001_DERIVE 121 --# define GOST_F_PKEY_GOST94CP_DECRYPT 122 --# define GOST_F_PKEY_GOST94CP_ENCRYPT 123 -# define GOST_F_PKEY_GOST94CP_KEYGEN 124 --# define GOST_F_PKEY_GOST94_PARAMGEN 139 ++# define GOST_F_FILL_GOST_EC_PARAMS 103 ++# define GOST_F_GET_ENCRYPTION_PARAMS 104 ++# define GOST_F_GOST89_GET_ASN1_PARAMETERS 105 ++# define GOST_F_GOST89_SET_ASN1_PARAMETERS 106 ++# define GOST_F_GOST94_COMPUTE_PUBLIC 107 ++# define GOST_F_GOST_CIPHER_CTL 108 ++# define GOST_F_GOST_DO_SIGN 109 ++# define GOST_F_GOST_DO_VERIFY 110 ++# define GOST_F_GOST_EC_COMPUTE_PUBLIC 111 ++# define GOST_F_GOST_EC_KEYGEN 112 ++# define GOST_F_GOST_EC_SIGN 113 ++# define GOST_F_GOST_EC_VERIFY 114 ++# define GOST_F_GOST_IMIT_CTRL 115 ++# define GOST_F_GOST_IMIT_FINAL 116 ++# define GOST_F_GOST_IMIT_UPDATE 117 ++# define GOST_F_GOST_SIGN_KEYGEN 118 ++# define GOST_F_PARAM_COPY_GOST01 119 ++# define GOST_F_PARAM_COPY_GOST_EC 120 ++# define GOST_F_PKEY_GOST01_PARAMGEN 121 ++# define GOST_F_PKEY_GOST12_PARAMGEN 122 ++# define GOST_F_PKEY_GOST94_CTRL_STR 123 ++# define GOST_F_PKEY_GOST94_PARAMGEN 124 # define GOST_F_PKEY_GOST_CTRL 125 - # define GOST_F_PKEY_GOST94_CTRL_STR 126 - # define GOST_F_PKEY_GOST_EC_CTRL_STR_256 127 - # define GOST_F_PKEY_GOST_EC_CTRL_STR_512 140 -# define GOST_F_PKEY_GOST_CTRL01_STR 126 -# define GOST_F_PKEY_GOST_CTRL94_STR 127 --# define GOST_F_PKEY_GOST_MAC_CTRL 128 --# define GOST_F_PKEY_GOST_MAC_CTRL_STR 129 --# define GOST_F_PKEY_GOST_MAC_KEYGEN 130 - # define GOST_F_PRINT_GOST_EC_PUB 131 -# define GOST_F_PRINT_GOST_01 131 --# define GOST_F_PRIV_DECODE_GOST 132 - # define GOST_F_PUB_DECODE_GOST_EC 133 -# define GOST_F_PUB_DECODE_GOST01 133 --# define GOST_F_PUB_DECODE_GOST94 134 - # define GOST_F_PUB_ENCODE_GOST_EC 135 - # define GOST_F_PUB_ENCODE_GOST94 124 -# define GOST_F_PUB_ENCODE_GOST01 135 -# define GOST_F_PUB_ENCODE_GOST94 141 --# define GOST_F_UNPACK_CC_SIGNATURE 136 --# define GOST_F_UNPACK_CP_SIGNATURE 137 - # define GOST_F_VKO_COMPUTE_KEY 141 ++# define GOST_F_PKEY_GOST_ECCP_DECRYPT 126 ++# define GOST_F_PKEY_GOST_ECCP_ENCRYPT 127 ++# define GOST_F_PKEY_GOST_EC_CTRL_STR_256 128 ++# define GOST_F_PKEY_GOST_EC_CTRL_STR_512 129 ++# define GOST_F_PKEY_GOST_EC_DERIVE 130 ++# define GOST_F_PKEY_GOST_MAC_CTRL 131 ++# define GOST_F_PKEY_GOST_MAC_CTRL_STR 132 ++# define GOST_F_PKEY_GOST_MAC_KEYGEN 133 ++# define GOST_F_PRINT_GOST_EC_PUB 134 ++# define GOST_F_PRIV_DECODE_GOST 135 ++# define GOST_F_PUB_DECODE_GOST01 136 ++# define GOST_F_PUB_DECODE_GOST94 137 ++# define GOST_F_PUB_DECODE_GOST_EC 138 ++# define GOST_F_PUB_ENCODE_GOST01 139 ++# define GOST_F_PUB_ENCODE_GOST94 140 ++# define GOST_F_PUB_ENCODE_GOST_EC 141 ++# define GOST_F_UNPACK_CC_SIGNATURE 142 ++# define GOST_F_UNPACK_CP_SIGNATURE 143 ++# define GOST_F_VKO_COMPUTE_KEY 144 /* Reason codes. */ --# define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99 --# define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100 --# define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101 --# define GOST_R_CTRL_CALL_FAILED 132 --# define GOST_R_ERROR_COMPUTING_SHARED_KEY 102 --# define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103 --# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104 --# define GOST_R_INCOMPATIBLE_ALGORITHMS 105 --# define GOST_R_INCOMPATIBLE_PEER_KEY 131 --# define GOST_R_INVALID_CIPHER_PARAMS 106 --# define GOST_R_INVALID_CIPHER_PARAM_OID 107 --# define GOST_R_INVALID_DIGEST_TYPE 108 --# define GOST_R_INVALID_GOST94_PARMSET 109 --# define GOST_R_INVALID_IV_LENGTH 110 --# define GOST_R_INVALID_MAC_KEY_LENGTH 111 --# define GOST_R_INVALID_PARAMSET 112 --# define GOST_R_KEY_IS_NOT_INITALIZED 113 --# define GOST_R_KEY_IS_NOT_INITIALIZED 114 --# define GOST_R_KEY_PARAMETERS_MISSING 115 --# define GOST_R_MAC_KEY_NOT_SET 116 - # define GOST_R_MALLOC_FAILURE 117 - # define GOST_R_NO_MEMORY 118 --# define GOST_R_NO_PARAMETERS_SET 119 --# define GOST_R_NO_PEER_KEY 120 --# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121 --# define GOST_R_PUBLIC_KEY_UNDEFINED 122 --# define GOST_R_RANDOM_GENERATOR_ERROR 123 --# define GOST_R_RANDOM_GENERATOR_FAILURE 124 --# define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125 --# define GOST_R_SIGNATURE_MISMATCH 126 --# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127 --# define GOST_R_UKM_NOT_SET 128 --# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129 --# define GOST_R_UNSUPPORTED_PARAMETER_SET 130 ++# define GOST_R_BAD_KEY_PARAMETERS_FORMAT 100 ++# define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 101 ++# define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 102 ++# define GOST_R_CTRL_CALL_FAILED 103 ++# define GOST_R_ERROR_COMPUTING_SHARED_KEY 104 ++# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 105 ++# define GOST_R_INCOMPATIBLE_ALGORITHMS 106 ++# define GOST_R_INCOMPATIBLE_PEER_KEY 107 ++# define GOST_R_INVALID_CIPHER_PARAMS 108 ++# define GOST_R_INVALID_CIPHER_PARAM_OID 109 ++# define GOST_R_INVALID_DIGEST_TYPE 110 ++# define GOST_R_INVALID_IV_LENGTH 111 ++# define GOST_R_INVALID_MAC_KEY_LENGTH 112 ++# define GOST_R_INVALID_PARAMSET 113 ++# define GOST_R_KEY_IS_NOT_INITALIZED 114 ++# define GOST_R_KEY_IS_NOT_INITIALIZED 115 ++# define GOST_R_KEY_PARAMETERS_MISSING 116 ++# define GOST_R_MAC_KEY_NOT_SET 117 ++# define GOST_R_MALLOC_FAILURE 118 ++# define GOST_R_NO_MEMORY 119 ++# define GOST_R_NO_PARAMETERS_SET 120 ++# define GOST_R_NO_PEER_KEY 121 ++# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 122 ++# define GOST_R_PUBLIC_KEY_UNDEFINED 123 ++# define GOST_R_RANDOM_GENERATOR_ERROR 124 ++# define GOST_R_RANDOM_GENERATOR_FAILURE 125 ++# define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 126 ++# define GOST_R_SIGNATURE_MISMATCH 127 ++# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 128 ++# define GOST_R_UKM_NOT_SET 129 ++# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 130 ++# define GOST_R_UNSUPPORTED_PARAMETER_SET 131 #ifdef __cplusplus } diff --combined gost_ameth.c index 24984c7,4f3bd90..c8d7e4f --- a/gost_ameth.c +++ b/gost_ameth.c @@@ -16,115 -16,71 +16,131 @@@ #ifndef OPENSSL_NO_CMS # include #endif - #include "gost_params.h" #include "gost_lcl.h" #include "e_gost_err.h" - static int pkey_bits_gost(const EVP_PKEY *pk); - -/* Convert little-endian byte array into bignum */ -BIGNUM *hashsum2bn(const unsigned char *dgst) -{ - unsigned char buf[32]; - - BUF_reverse(buf, (unsigned char*)dgst, 32); - return BN_bin2bn(buf, 32, NULL); -} - + /* + * Pack bignum into byte buffer of given size, filling all leading bytes by + * zeros + */ + int store_bignum(BIGNUM *bn, unsigned char *buf, int len) + { + int bytes = BN_num_bytes(bn); + + if (bytes > len) + return 0; + memset(buf, 0, len); + BN_bn2bin(bn, buf + len - bytes); + return 1; + } - int gost94_nid_by_params(DSA *p) ++/* Convert byte buffer to bignum, skipping leading zeros*/ ++BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len) +{ - R3410_params *gost_params; - BIGNUM *q = BN_new(); - for (gost_params = R3410_paramset; gost_params->nid != NID_undef; - gost_params++) { - BN_dec2bn(&q, gost_params->q); - if (!BN_cmp(q, p->q)) - break; ++ BIGNUM *b; ++ ++ while (*buf == 0 && len > 0) { ++ buf++; ++ len--; + } - BN_free(q); - return gost_params->nid; ++ if (len) ++ return BN_bin2bn(buf, len, NULL); ++ b = BN_new(); ++ BN_zero(b); ++ return b; ++} ++ ++static int pkey_bits_gost(const EVP_PKEY *pk) ++{ ++ if (!pk) ++ return -1; ++ ++ switch (EVP_PKEY_base_id(pk)) { ++ case NID_id_GostR3410_2001: ++ case NID_id_GostR3410_2012_256: ++ return 256; ++ case NID_id_GostR3410_2012_512: ++ return 512; ++ } ++ ++ return -1; +} + static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) { ASN1_STRING *params = ASN1_STRING_new(); GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); int pkey_param_nid = NID_undef; + void *key_ptr = EVP_PKEY_get0((EVP_PKEY *)key); + int result = 0; if (!params || !gkp) { GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - params = NULL; goto err; } switch (EVP_PKEY_base_id(key)) { + case NID_id_GostR3410_2012_256: + pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr)); + gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_2012_256); + break; + case NID_id_GostR3410_2012_512: + pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr)); + gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_2012_512); + break; case NID_id_GostR3410_2001: - pkey_param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)key))); + pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(key_ptr)); + gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); break; - case NID_id_GostR3410_94: - pkey_param_nid = (int)gost94_nid_by_params(key_ptr); - gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); - break; } + + if (pkey_param_nid == NID_undef) { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, GOST_R_INVALID_PARAMSET); + goto err; + } + gkp->key_params = OBJ_nid2obj(pkey_param_nid); - gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); /* * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); */ params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); if (params->length <= 0) { GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - params = NULL; goto err; } params->type = V_ASN1_SEQUENCE; + result = 1; err: - GOST_KEY_PARAMS_free(gkp); + if (gkp) + GOST_KEY_PARAMS_free(gkp); + if (result == 0) { /* if error */ + if (params) + ASN1_STRING_free(params); + return NULL; + } return params; } +static int gost_decode_nid_params(EVP_PKEY *pkey, int pkey_nid, int param_nid) +{ + void *key_ptr = EVP_PKEY_get0(pkey); + + switch (pkey_nid) { + case NID_id_GostR3410_2012_256: + case NID_id_GostR3410_2012_512: + case NID_id_GostR3410_2001: + if (!key_ptr) { + key_ptr = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey, pkey_nid, key_ptr)) { + EC_KEY_free(key_ptr); + break; + } + } + return fill_GOST_EC_params(key_ptr, param_nid); - - case NID_id_GostR3410_94: - if (!key_ptr) { - key_ptr = DSA_new(); - if (!EVP_PKEY_assign(pkey, pkey_nid, key_ptr)) { - DSA_free(key_ptr); - break; - } - } - return fill_GOST94_params(key_ptr, param_nid); + } + + return 0; +} + /* * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting * NID and parameters @@@ -134,13 -90,13 +150,13 @@@ static int decode_gost_algor_params(EVP ASN1_OBJECT *palg_obj = NULL; int ptype = V_ASN1_UNDEF; int pkey_nid = NID_undef, param_nid = NID_undef; - void *_pval; ASN1_STRING *pval = NULL; const unsigned char *p; GOST_KEY_PARAMS *gkp = NULL; - X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); - pval = _pval; + if (!pkey || !palg) + return 0; + X509_ALGOR_get0(&palg_obj, &ptype, (void **)&pval, palg); if (ptype != V_ASN1_SEQUENCE) { GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, GOST_R_BAD_KEY_PARAMETERS_FORMAT); @@@ -161,27 -117,26 +177,14 @@@ GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); return 0; } - switch (pkey_nid) { - case NID_id_GostR3410_2001: - { - EC_KEY *ec = EVP_PKEY_get0(pkey); - if (!ec) { - ec = EC_KEY_new(); - if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) - return 0; - } - if (!fill_GOST2001_params(ec, param_nid)) - return 0; - } - } -- - return 1; + return gost_decode_nid_params(pkey, pkey_nid, param_nid); } static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) { switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - { - DSA *dsa = EVP_PKEY_get0(pkey); - if (!dsa) { - dsa = DSA_new(); - EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); - } - dsa->priv_key = BN_dup(priv); - if (!EVP_PKEY_missing_parameters(pkey)) - gost94_compute_public(dsa); - break; - } + case NID_id_GostR3410_2012_512: + case NID_id_GostR3410_2012_256: case NID_id_GostR3410_2001: { EC_KEY *ec = EVP_PKEY_get0(pkey); @@@ -192,11 -147,9 +195,11 @@@ if (!EC_KEY_set_private_key(ec, priv)) return 0; if (!EVP_PKEY_missing_parameters(pkey)) - gost2001_compute_public(ec); + gost_ec_compute_public(ec); break; } + default: + return 0; } return 1; } @@@ -204,95 -157,83 +207,88 @@@ BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) { switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - { - DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); - if (dsa) - return dsa->priv_key; - break; - } + case NID_id_GostR3410_2012_512: + case NID_id_GostR3410_2012_256: case NID_id_GostR3410_2001: { EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); - const BIGNUM *priv; - if (!ec) { - return NULL; - } - if ((priv = EC_KEY_get0_private_key(ec)) == NULL) - return NULL; - return (BIGNUM *)priv; + if (ec) + return (BIGNUM *)EC_KEY_get0_private_key(ec); + break; } } return NULL; } +/* + * Control function + */ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) { + int nid = EVP_PKEY_base_id(pkey), md_nid = NID_undef; + X509_ALGOR *alg1 = NULL, *alg2 = NULL; + + switch (nid) { + case NID_id_GostR3410_2012_512: + md_nid = NID_id_GostR3411_2012_512; + break; + case NID_id_GostR3410_2012_256: + md_nid = NID_id_GostR3411_2012_256; + break; + case NID_id_GostR3410_2001: + case NID_id_GostR3410_94: + md_nid = NID_id_GostR3411_94; + break; + default: + return -1; + } + switch (op) { case ASN1_PKEY_CTRL_PKCS7_SIGN: if (arg1 == 0) { - X509_ALGOR *alg1 = NULL, *alg2 = NULL; - int nid = EVP_PKEY_base_id(pkey); - PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, - NULL, &alg1, &alg2); - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), - V_ASN1_NULL, 0); - if (nid == NID_undef) { - return (-1); - } + PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, NULL, + &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0); X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_SIGN: if (arg1 == 0) { - X509_ALGOR *alg1 = NULL, *alg2 = NULL; - int nid = EVP_PKEY_base_id(pkey); - CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, - NULL, NULL, &alg1, &alg2); - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), - V_ASN1_NULL, 0); - if (nid == NID_undef) { - return (-1); - } + CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, NULL, NULL, + &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(md_nid), V_ASN1_NULL, 0); X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); } return 1; #endif case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: if (arg1 == 0) { - X509_ALGOR *alg; ASN1_STRING *params = encode_gost_algor_params(pkey); if (!params) { return -1; } - PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); - X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), + PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg1); + X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, params); } return 1; #ifndef OPENSSL_NO_CMS case ASN1_PKEY_CTRL_CMS_ENVELOPE: if (arg1 == 0) { - X509_ALGOR *alg = NULL; ASN1_STRING *params = encode_gost_algor_params(pkey); if (!params) { return -1; } CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, - NULL, &alg); - X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, + NULL, &alg1); + X509_ALGOR_set0(alg1, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, params); } return 1; #endif case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_id_GostR3411_94; + *(int *)arg2 = md_nid; return 2; } @@@ -300,64 -241,12 +296,55 @@@ } /* --------------------- free functions * ------------------------------*/ - static void pkey_free_gost94(EVP_PKEY *key) - { - if (key->pkey.dsa) { - DSA_free(key->pkey.dsa); - } - } - -static void pkey_free_gost01(EVP_PKEY *key) +static void pkey_free_gost_ec(EVP_PKEY *key) { - if (key->pkey.ec) { - EC_KEY_free(key->pkey.ec); - } + EC_KEY_free(key->pkey.ec); } /* ------------------ private key functions -----------------------------*/ + +static BIGNUM *unmask_priv_key(EVP_PKEY *pk, + const unsigned char *buf, int len, + int num_masks) +{ + BIGNUM *pknum_masked = NULL, *q = NULL; + const EC_KEY *key_ptr = (pk) ? EVP_PKEY_get0(pk) : NULL; + const EC_GROUP *group = (key_ptr) ? EC_KEY_get0_group(key_ptr) : NULL; + + pknum_masked = hashsum2bn(buf, len); + if (!pknum_masked) + return NULL; + + if (num_masks > 0) { + /* + * XXX Remove sign by gost94 + */ + const unsigned char *p = buf + num_masks * len; + + q = BN_new(); + if (!q || !group || EC_GROUP_get_order(group, q, NULL) <= 0) { + BN_free(pknum_masked); + pknum_masked = NULL; + goto end; + } + + for (; p != buf; p -= len) { + BIGNUM *mask = hashsum2bn(p, len); + BN_CTX *ctx = BN_CTX_new(); + + BN_mod_mul(pknum_masked, pknum_masked, mask, q, ctx); + + BN_CTX_free(ctx); + BN_free(mask); + } + } + + end: + if (q) + BN_free(q); + return pknum_masked; +} + static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) { const unsigned char *pkey_buf = NULL, *p = NULL; @@@ -367,7 -256,6 +354,7 @@@ X509_ALGOR *palg = NULL; ASN1_OBJECT *palg_obj = NULL; ASN1_INTEGER *priv_key = NULL; + int expected_key_len = 32; if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) return 0; @@@ -375,63 -263,30 +362,63 @@@ if (!decode_gost_algor_params(pk, palg)) { return 0; } - if (V_ASN1_OCTET_STRING == *p) { + + expected_key_len = pkey_bits_gost(pk) > 0 ? pkey_bits_gost(pk) / 8 : 0; + if (expected_key_len == 0) { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; + } + + if (priv_len % expected_key_len == 0) { + /* Key is not wrapped but masked */ + pk_num = unmask_priv_key(pk, pkey_buf, expected_key_len, + priv_len / expected_key_len - 1); + } else if (V_ASN1_OCTET_STRING == *p) { /* New format - Little endian octet string */ - unsigned char rev_buf[32]; - int i; ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); - if (!s || s->length != 32) { + if (!s || ((s->length != 32) && (s->length != 64))) { + ASN1_STRING_free(s); GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } - for (i = 0; i < 32; i++) { - rev_buf[31 - i] = s->data[i]; - } + pk_num = hashsum2bn(s->data, s->length); ASN1_STRING_free(s); - pk_num = getbnfrombuf(rev_buf, 32); - } else { + } else if (V_ASN1_INTEGER == *p) { priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); - if (!priv_key) + if (!priv_key) { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; - ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); + } + pk_num = ASN1_INTEGER_to_BN(priv_key, NULL); ASN1_INTEGER_free(priv_key); - if (!ret) { + } else if ((V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED) == *p) { + MASKED_GOST_KEY *mgk = NULL; + mgk = d2i_MASKED_GOST_KEY(NULL, &p, priv_len); + + if (!mgk) { GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); return 0; } + + priv_len = mgk->masked_priv_key->length; + if (priv_len % expected_key_len) { + MASKED_GOST_KEY_free(mgk); + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; + } + + pk_num = unmask_priv_key(pk, mgk->masked_priv_key->data, + expected_key_len, + priv_len / expected_key_len - 1); + MASKED_GOST_KEY_free(mgk); + } else { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; + } + + if (pk_num == NULL) { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; } ret = gost_set_priv_key(pk, pk_num); @@@ -444,213 -299,104 +431,160 @@@ static int priv_encode_gost(PKCS8_PRIV_ { ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); ASN1_STRING *params = encode_gost_algor_params(pk); - unsigned char *priv_buf = NULL; - int priv_len; + unsigned char *priv_buf = NULL, *buf = NULL; + int key_len = pkey_bits_gost(pk), priv_len = 0, i = 0; - ASN1_INTEGER *asn1key = NULL; + ASN1_STRING *octet = NULL; if (!params) { return 0; } - asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); - priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); - ASN1_INTEGER_free(asn1key); + + key_len = (key_len < 0) ? 0 : key_len / 8; + if (key_len == 0 || !(buf = OPENSSL_malloc(key_len))) { + return 0; + } + + if (!store_bignum(gost_get0_priv_key(pk), buf, key_len)) { + OPENSSL_free(buf); + return 0; + } + + /* Convert buf to Little-endian */ + for (i = 0; i < key_len / 2; i++) { + unsigned char tmp = buf[i]; + buf[i] = buf[key_len - 1 - i]; + buf[key_len - 1 - i] = tmp; + } + + octet = ASN1_STRING_new(); - M_ASN1_OCTET_STRING_set(octet, buf, key_len); ++ ASN1_OCTET_STRING_set(octet, buf, key_len); + + priv_len = i2d_ASN1_OCTET_STRING(octet, &priv_buf); + ASN1_STRING_free(octet); + OPENSSL_free(buf); + return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, priv_buf, priv_len); } /* --------- printing keys --------------------------------*/ -static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx, int type) +static int print_gost_priv(BIO *out, const EVP_PKEY *pkey, int indent) { - int param_nid = NID_undef; - if (type == 2) { - BIGNUM *key; + BIGNUM *key; - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Private key: "); - key = gost_get0_priv_key(pkey); - if (!key) - BIO_printf(out, ""); + else + BN_print(out, key); + BIO_printf(out, "\n"); + + return 1; +} + +static int print_gost_ec_pub(BIO *out, const EVP_PKEY *pkey, int indent) +{ + BN_CTX *ctx; + BIGNUM *X, *Y; + const EC_POINT *pubkey; + const EC_GROUP *group; + EC_KEY *key = (EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey); + int ok = 0; + + ctx = BN_CTX_new(); + if (!ctx) { + GOSTerr(GOST_F_PRINT_GOST_EC_PUB, ERR_R_MALLOC_FAILURE); + return 0; } - if (type >= 1) { - BN_CTX *ctx = BN_CTX_new(); - BIGNUM *X, *Y; - const EC_POINT *pubkey; - const EC_GROUP *group; - if (!ctx) { - GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); - return 0; - } - BN_CTX_start(ctx); - X = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); - pubkey = - EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); - group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); - if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { - GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); - BN_CTX_free(ctx); - return 0; - } - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Public key:\n"); - if (!BIO_indent(out, indent + 3, 128)) - return 0; - BIO_printf(out, "X:"); - BN_print(out, X); - BIO_printf(out, "\n"); - BIO_indent(out, indent + 3, 128); - BIO_printf(out, "Y:"); - BN_print(out, Y); - BIO_printf(out, "\n"); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)pkey))); + BN_CTX_start(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + pubkey = (key) ? EC_KEY_get0_public_key(key) : NULL; + group = (key) ? EC_KEY_get0_group(key) : NULL; + if (!pubkey || !group) + goto err; + + if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { + GOSTerr(GOST_F_PRINT_GOST_EC_PUB, ERR_R_EC_LIB); + goto err; + } + if (!BIO_indent(out, indent, 128)) + goto err; + BIO_printf(out, "Public key:\n"); + if (!BIO_indent(out, indent + 3, 128)) + goto err; + BIO_printf(out, "X:"); + BN_print(out, X); + BIO_printf(out, "\n"); + if (!BIO_indent(out, indent + 3, 128)) + goto err; + BIO_printf(out, "Y:"); + BN_print(out, Y); + BIO_printf(out, "\n"); + ok = 1; + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + + return ok; +} + +static int print_gost_ec_param(BIO *out, const EVP_PKEY *pkey, int indent) +{ + EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); + const EC_GROUP *group = (ec) ? EC_KEY_get0_group(ec) : NULL; + int param_nid; + + if (!group) + return 0; + + param_nid = EC_GROUP_get_curve_name(group); if (!BIO_indent(out, indent, 128)) return 0; BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); + return 1; } - static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx, int type) - { - int param_nid = NID_undef; - - if (type == 2) { - if (print_gost_priv(out, pkey, indent) == 0) - return 0; - } - if (type >= 1) { - BIGNUM *pubkey; - - pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; - BIO_indent(out, indent, 128); - BIO_printf(out, "Public key: "); - BN_print(out, pubkey); - BIO_printf(out, "\n"); - } - - param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); - BIO_indent(out, indent, 128); - BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); - return 1; - } - - static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, -static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, -- ASN1_PCTX *pctx) - { - return print_gost_94(out, pkey, indent, pctx, 0); - } - - static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) - { - return print_gost_94(out, pkey, indent, pctx, 1); - } - - static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) - { - return print_gost_94(out, pkey, indent, pctx, 2); - } - +static int print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) { - return print_gost_01(out, pkey, indent, pctx, 0); + if (type == 2) { + if (print_gost_priv(out, pkey, indent) == 0) + return 0; + } + if (type >= 1) { + if (print_gost_ec_pub(out, pkey, indent) == 0) + return 0; + } + + return print_gost_ec_param(out, pkey, indent); } -static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) +static int param_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { - return print_gost_01(out, pkey, indent, pctx, 1); + return print_gost_ec(out, pkey, indent, pctx, 0); } -static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, +static int pub_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - return print_gost_01(out, pkey, indent, pctx, 2); + return print_gost_ec(out, pkey, indent, pctx, 1); +} + +static int priv_print_gost_ec(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_ec(out, pkey, indent, pctx, 2); } /* ---------------------------------------------------------------------*/ - static int param_missing_gost94(const EVP_PKEY *pk) - { - const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); - if (!dsa) - return 1; - if (!dsa->q) - return 1; - return 0; - } - -static int param_missing_gost01(const EVP_PKEY *pk) +static int param_missing_gost_ec(const EVP_PKEY *pk) { const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); if (!ec) @@@ -660,175 -406,55 +594,62 @@@ return 0; } - static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) - { - const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); - DSA *dto = EVP_PKEY_get0(to); - if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { - GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); - return 0; - } - if (!dfrom) { - GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); - return 0; - } - if (!dto) { - dto = DSA_new(); - EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); - } - #define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); - COPYBIGNUM(dto, dfrom, p) - COPYBIGNUM(dto, dfrom, q) - COPYBIGNUM(dto, dfrom, g) - - if (dto->priv_key) - gost94_compute_public(dto); - return 1; - } -static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) +static int param_copy_gost_ec(EVP_PKEY *to, const EVP_PKEY *from) { EC_KEY *eto = EVP_PKEY_get0(to); const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); + GOSTerr(GOST_F_PARAM_COPY_GOST_EC, GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; } if (!efrom) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); + GOSTerr(GOST_F_PARAM_COPY_GOST_EC, GOST_R_KEY_PARAMETERS_MISSING); return 0; } if (!eto) { eto = EC_KEY_new(); if (!eto) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); + GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_MALLOC_FAILURE); return 0; } if (!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); + GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_INTERNAL_ERROR); + EC_KEY_free(eto); return 0; } } if (!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); + GOSTerr(GOST_F_PARAM_COPY_GOST_EC, ERR_R_INTERNAL_ERROR); return 0; } if (EC_KEY_get0_private_key(eto)) { - gost2001_compute_public(eto); + return gost_ec_compute_public(eto); } return 1; } - static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) - { - const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); - const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); - if (!da || !db) - return 0; - return (BN_cmp(da->q, db->q) == 0) ? 1 : 0; - } - -static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +static int param_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b) { - if (EC_GROUP_get_curve_name - (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)b)))) { + const EC_GROUP *group_a, *group_b; + EC_KEY *ec_a = EVP_PKEY_get0((EVP_PKEY *)a); + EC_KEY *ec_b = EVP_PKEY_get0((EVP_PKEY *)b); + if (!ec_a || !ec_b) + return 0; + + group_a = EC_KEY_get0_group(ec_a); + group_b = EC_KEY_get0_group(ec_b); + if (!group_a || !group_b) + return 0; + + if (EC_GROUP_get_curve_name(group_a) == EC_GROUP_get_curve_name(group_b)) { return 1; } return 0; - } /* ---------- Public key functions * --------------------------------------*/ - static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) - { - X509_ALGOR *palg = NULL; - const unsigned char *pubkey_buf = NULL; - unsigned char *databuf; - ASN1_OBJECT *palgobj = NULL; - int pub_len, i, j; - DSA *dsa; - ASN1_OCTET_STRING *octet = NULL; - - if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) - return 0; - EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); - if (!decode_gost_algor_params(pk, palg)) - return 0; - octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); - if (!octet) { - GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); - return 0; - } - databuf = OPENSSL_malloc(octet->length); - if (databuf == NULL) { - GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); - ASN1_OCTET_STRING_free(octet); - return 0; - } - for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { - databuf[j] = octet->data[i]; - } - dsa = EVP_PKEY_get0(pk); - dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); - ASN1_OCTET_STRING_free(octet); - OPENSSL_free(databuf); - return 1; - - } - - static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) - { - ASN1_OBJECT *algobj = NULL; - ASN1_OCTET_STRING *octet = NULL; - void *pval = NULL; - unsigned char *buf = NULL, *databuf, *sptr; - int i, j, data_len, ret = 0; - - int ptype = V_ASN1_UNDEF; - DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); - algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); - if (pk->save_parameters) { - ASN1_STRING *params = encode_gost_algor_params(pk); - pval = params; - ptype = V_ASN1_SEQUENCE; - } - data_len = BN_num_bytes(dsa->pub_key); - databuf = OPENSSL_malloc(data_len); - if (databuf == NULL) { - GOSTerr(GOST_F_PUB_ENCODE_GOST94, ERR_R_MALLOC_FAILURE); - return 0; - } - BN_bn2bin(dsa->pub_key, databuf); - octet = ASN1_OCTET_STRING_new(); - if (octet == NULL) { - GOSTerr(GOST_F_PUB_ENCODE_GOST94, ERR_R_MALLOC_FAILURE); - OPENSSL_free(databuf); - return 0; - } - ASN1_STRING_set(octet, NULL, data_len); - sptr = ASN1_STRING_data(octet); - for (i = 0, j = data_len - 1; i < data_len; i++, j--) { - sptr[i] = databuf[j]; - } - OPENSSL_free(databuf); - ret = i2d_ASN1_OCTET_STRING(octet, &buf); - ASN1_BIT_STRING_free(octet); - if (ret < 0) - return 0; - return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); - } -- -static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) +static int pub_decode_gost_ec(EVP_PKEY *pk, X509_PUBKEY *pub) { X509_ALGOR *palg = NULL; const unsigned char *pubkey_buf = NULL; @@@ -849,12 -475,12 +670,12 @@@ group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); if (!octet) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); + GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_MALLOC_FAILURE); return 0; } databuf = OPENSSL_malloc(octet->length); if (databuf == NULL) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); + GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_MALLOC_FAILURE); ASN1_OCTET_STRING_free(octet); return 0; } @@@ -869,7 -495,7 +690,7 @@@ OPENSSL_free(databuf); pub_key = EC_POINT_new(group); if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_EC_LIB); EC_POINT_free(pub_key); BN_free(X); BN_free(Y); @@@ -878,7 -504,7 +699,7 @@@ BN_free(X); BN_free(Y); if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + GOSTerr(GOST_F_PUB_DECODE_GOST_EC, ERR_R_EC_LIB); EC_POINT_free(pub_key); return 0; } @@@ -887,15 -513,15 +708,15 @@@ } -static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) +static int pub_encode_gost_ec(X509_PUBKEY *pub, const EVP_PKEY *pk) { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; - unsigned char *buf = NULL, *databuf, *sptr; - int i, j, data_len, ret = 0; + unsigned char *buf = NULL, *databuf = NULL, *sptr; + int i, j, data_len, ret = -1; const EC_POINT *pub_key; - BIGNUM *X, *Y, *order; + BIGNUM *X = NULL, *Y = NULL, *order = NULL; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); int ptype = V_ASN1_UNDEF; @@@ -906,165 -532,107 +727,127 @@@ ptype = V_ASN1_SEQUENCE; } order = BN_new(); + if (!order) { + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE); + goto err; + } EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); pub_key = EC_KEY_get0_public_key(ec); if (!pub_key) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); - BN_free(order); - return 0; + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, GOST_R_PUBLIC_KEY_UNDEFINED); + goto err; } X = BN_new(); Y = BN_new(); if (!X || !Y) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - BN_free(X); - BN_free(Y); - BN_free(order); - return 0; + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE); + goto err; } if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), - pub_key, X, Y, NULL)) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); - BN_free(X); - BN_free(Y); - BN_free(order); - return 0; + pub_key, X, Y, NULL)) { + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_INTERNAL_ERROR); + goto err; } data_len = 2 * BN_num_bytes(order); - BN_free(order); databuf = OPENSSL_malloc(data_len); if (databuf == NULL) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - BN_free(X); - BN_free(Y); - return 0; + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE); + goto err; } memset(databuf, 0, data_len); store_bignum(X, databuf + data_len / 2, data_len / 2); store_bignum(Y, databuf, data_len / 2); - BN_free(X); - BN_free(Y); octet = ASN1_OCTET_STRING_new(); if (octet == NULL) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - OPENSSL_free(databuf); - return 0; + GOSTerr(GOST_F_PUB_ENCODE_GOST_EC, ERR_R_MALLOC_FAILURE); + goto err; } ASN1_STRING_set(octet, NULL, data_len); sptr = ASN1_STRING_data(octet); for (i = 0, j = data_len - 1; i < data_len; i++, j--) { sptr[i] = databuf[j]; } - OPENSSL_free(databuf); + ret = i2d_ASN1_OCTET_STRING(octet, &buf); ASN1_BIT_STRING_free(octet); +err: + if (X) + BN_free(X); + if (Y) + BN_free(Y); + if (order) + BN_free(order); + if (databuf) + OPENSSL_free(databuf); + if (ret < 0) return 0; return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); } - static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) - { - const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); - const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); - if (!da || !db) - return 0; - - if (!da->pub_key || !db->pub_key) - return 0; - - return (BN_cmp(da->pub_key, db->pub_key) == 0) ? 1 : 0; - } - -static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +static int pub_cmp_gost_ec(const EVP_PKEY *a, const EVP_PKEY *b) { const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); const EC_POINT *ka, *kb; - int ret = 0; if (!ea || !eb) return 0; ka = EC_KEY_get0_public_key(ea); kb = EC_KEY_get0_public_key(eb); if (!ka || !kb) return 0; - ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); - return ret; + return (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); } static int pkey_size_gost(const EVP_PKEY *pk) { - return 64; -} + if (!pk) + return -1; -static int pkey_bits_gost(const EVP_PKEY *pk) -{ - return 256; + switch (EVP_PKEY_base_id(pk)) { + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2012_256: + return 64; + case NID_id_GostR3410_2012_512: + return 128; + } + + return -1; } - static int pkey_bits_gost(const EVP_PKEY *pk) - { - if (!pk) - return -1; - - switch (EVP_PKEY_base_id(pk)) { - case NID_id_GostR3410_94: - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2012_256: - return 256; - case NID_id_GostR3410_2012_512: - return 512; - } - - return -1; - } - /* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ static void mackey_free_gost(EVP_PKEY *pk) { - if (pk->pkey.ptr) { - OPENSSL_free(pk->pkey.ptr); - } + OPENSSL_free(pk->pkey.ptr); } static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_id_Gost28147_89_MAC; - return 2; + if (arg2) { + *(int *)arg2 = NID_id_Gost28147_89_MAC; + return 2; + } + } + return -2; +} + +static int mac_ctrl_gost_12(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + if (arg2) { + *(int *)arg2 = NID_gost_mac_12; + return 2; + } } return -2; } - static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) - { - int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); - return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); - } - static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) { int nid = @@@ -1073,32 -641,25 +856,18 @@@ return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); } - static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, - int derlen) - { - ASN1_OBJECT *obj = NULL; - int nid; - if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { - return 0; - } - nid = OBJ_obj2nid(obj); - ASN1_OBJECT_free(obj); - - return gost_decode_nid_params(pkey, NID_id_GostR3410_94, nid); - } - static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, int derlen) { ASN1_OBJECT *obj = NULL; int nid; - EC_KEY *ec = EVP_PKEY_get0(pkey); if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { return 0; } nid = OBJ_obj2nid(obj); ASN1_OBJECT_free(obj); - if (!ec) { - ec = EC_KEY_new(); - if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) - return 0; - } - if (!fill_GOST2001_params(ec, nid)) - return 0; - return 1; + + return gost_decode_nid_params(pkey, NID_id_GostR3410_2001, nid); } /* ----------------------------------------------------------------------*/ @@@ -1109,55 -670,19 +878,38 @@@ int register_ameth_gost(int nid, EVP_PK if (!*ameth) return 0; switch (nid) { - case NID_id_GostR3410_94: - EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); - EVP_PKEY_asn1_set_private(*ameth, - priv_decode_gost, priv_encode_gost, - priv_print_gost94); - - EVP_PKEY_asn1_set_param(*ameth, - gost94_param_decode, gost94_param_encode, - param_missing_gost94, param_copy_gost94, - param_cmp_gost94, param_print_gost94); - EVP_PKEY_asn1_set_public(*ameth, - pub_decode_gost94, pub_encode_gost94, - pub_cmp_gost94, pub_print_gost94, - pkey_size_gost, pkey_bits_gost); - - EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); - break; case NID_id_GostR3410_2001: - EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); + EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost_ec); EVP_PKEY_asn1_set_private(*ameth, priv_decode_gost, priv_encode_gost, - priv_print_gost01); + priv_print_gost_ec); EVP_PKEY_asn1_set_param(*ameth, gost2001_param_decode, gost2001_param_encode, - param_missing_gost01, param_copy_gost01, - param_cmp_gost01, param_print_gost01); + param_missing_gost_ec, param_copy_gost_ec, + param_cmp_gost_ec, param_print_gost_ec); + EVP_PKEY_asn1_set_public(*ameth, + pub_decode_gost_ec, pub_encode_gost_ec, + pub_cmp_gost_ec, pub_print_gost_ec, + pkey_size_gost, pkey_bits_gost); + + EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); + break; + case NID_id_GostR3410_2012_256: + case NID_id_GostR3410_2012_512: + EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost_ec); + EVP_PKEY_asn1_set_private(*ameth, + priv_decode_gost, priv_encode_gost, + priv_print_gost_ec); + + EVP_PKEY_asn1_set_param(*ameth, + NULL, NULL, + param_missing_gost_ec, param_copy_gost_ec, + param_cmp_gost_ec, NULL); + EVP_PKEY_asn1_set_public(*ameth, - pub_decode_gost01, pub_encode_gost01, - pub_cmp_gost01, pub_print_gost01, + pub_decode_gost_ec, pub_encode_gost_ec, + pub_cmp_gost_ec, pub_print_gost_ec, pkey_size_gost, pkey_bits_gost); EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); @@@ -1166,10 -691,6 +918,10 @@@ EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); break; + case NID_gost_mac_12: + EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); + EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12); + break; } return 1; } diff --combined gost_crypt.c index a32d489,e2a2ff6..0c207cd --- a/gost_crypt.c +++ b/gost_crypt.c @@@ -8,6 -8,7 +8,7 @@@ **********************************************************************/ #include #include "gost89.h" + #include #include #include "e_gost_err.h" #include "gost_lcl.h" @@@ -23,9 -24,6 +24,9 @@@ static int gost_cipher_init(EVP_CIPHER_ const unsigned char *iv, int enc); static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc); +static int gost_cipher_init_cp_12(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc); /* Handles block of data in CFB mode */ static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl); @@@ -74,27 -72,9 +75,27 @@@ EVP_CIPHER cipher_gost_cpacnt = NULL, }; +EVP_CIPHER cipher_gost_cpcnt_12 = { + NID_gost89_cnt_12, + 1, /* block_size */ + 32, /* key_size */ + 8, /* iv_len */ + EVP_CIPH_OFB_MODE | EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init_cp_12, + gost_cipher_do_cnt, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, +}; + /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ /* Init functions which set specific parameters */ static int gost_imit_init_cpa(EVP_MD_CTX *ctx); +static int gost_imit_init_cp_12(EVP_MD_CTX *ctx); /* process block of data */ static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count); /* Return computed value */ @@@ -123,24 -103,6 +124,24 @@@ EVP_MD imit_gost_cpa = gost_imit_ctrl }; +EVP_MD imit_gost_cp_12 = { + NID_gost_mac_12, + NID_undef, + 4, + 0, + gost_imit_init_cp_12, + gost_imit_update, + gost_imit_final, + gost_imit_copy, + gost_imit_cleanup, + NULL, + NULL, + {0, 0, 0, 0, 0}, + 8, + sizeof(struct ossl_gost_imit_ctx), + gost_imit_ctrl +}; + /* * Correspondence between gost parameter OIDs and substitution blocks * NID field is filed by register_gost_NID function in engine.c @@@ -156,7 -118,6 +157,6 @@@ struct gost_cipher_info gost_cipher_lis /* * {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0}, */ - {NID_id_Gost28147_89_cc, &GostR3411_94_CryptoProParamSet, 0}, {NID_id_Gost28147_89_CryptoPro_A_ParamSet, &Gost28147_CryptoProParamSetA, 1}, {NID_id_Gost28147_89_CryptoPro_B_ParamSet, &Gost28147_CryptoProParamSetB, @@@ -165,7 -126,6 +165,7 @@@ 1}, {NID_id_Gost28147_89_CryptoPro_D_ParamSet, &Gost28147_CryptoProParamSetD, 1}, + {NID_id_tc26_gost_28147_param_Z, &Gost28147_TC26ParamSetZ, 1}, {NID_id_Gost28147_89_TestParamSet, &Gost28147_TestParamSet, 1}, {NID_undef, NULL, 0} }; @@@ -183,7 -143,7 +183,7 @@@ const struct gost_cipher_info *get_encr if (!obj) { const char *params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS); if (!params || !strlen(params)) - return &gost_cipher_list[1]; + return &gost_cipher_list[5]; nid = OBJ_txt2nid(params); if (nid == NID_undef) { @@@ -239,13 -199,11 +239,13 @@@ static int gost_cipher_init_param(EVP_C return 1; } -static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) +static int gost_cipher_init_cnt(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + gost_subst_block * block) { struct ossl_gost_cipher_ctx *c = ctx->cipher_data; - gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); + gost_init(&(c->cctx), block); c->key_meshing = 1; c->count = 0; if (key) @@@ -256,19 -214,6 +256,19 @@@ return 1; } +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + return gost_cipher_init_cnt(ctx, key, iv, &Gost28147_CryptoProParamSetA); +} + +static int gost_cipher_init_cp_12(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return gost_cipher_init_cnt(ctx, key, iv, &Gost28147_TC26ParamSetZ); +} + /* Initializes EVP_CIPHER_CTX with default values */ int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@@ -453,14 -398,6 +453,14 @@@ int gost_cipher_cleanup(EVP_CIPHER_CTX int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { switch (type) { + case EVP_CTRL_INIT: + { + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + if (c == NULL) { + return -1; + } + return gost_cipher_set_param(c, arg); + } case EVP_CTRL_RAND_KEY: { if (RAND_bytes((unsigned char *)ptr, ctx->key_len) <= 0) { @@@ -472,18 -409,7 +472,18 @@@ } case EVP_CTRL_PBE_PRF_NID: if (ptr) { - *((int *)ptr) = NID_id_HMACGostR3411_94; + const char *params = get_gost_engine_param(GOST_PARAM_PBE_PARAMS); + int nid = NID_id_tc26_hmac_gost_3411_2012_512; + + if (params) { + if (!strcmp("md_gost12_256", params)) + nid = NID_id_tc26_hmac_gost_3411_2012_256; + else if (!strcmp("md_gost12_512", params)) + nid = NID_id_tc26_hmac_gost_3411_2012_512; + else if (!strcmp("md_gost94", params)) + nid = NID_id_HMACGostR3411_94; + } + *((int *)ptr) = nid; return 1; } else { return 0; @@@ -507,22 -433,22 +507,22 @@@ int gost89_set_asn1_parameters(EVP_CIPH GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); ASN1_OCTET_STRING *os = NULL; if (!gcp) { - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) { GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } ASN1_OBJECT_free(gcp->enc_param_set); gcp->enc_param_set = OBJ_nid2obj(c->paramNID); len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); - p = buf = (unsigned char *)OPENSSL_malloc(len); + p = buf = OPENSSL_malloc(len); if (!buf) { GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } i2d_GOST_CIPHER_PARAMS(gcp, &p); @@@ -532,7 -458,7 +532,7 @@@ if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) { OPENSSL_free(buf); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE); return 0; } OPENSSL_free(buf); @@@ -549,8 -475,6 +549,8 @@@ int gost89_get_asn1_parameters(EVP_CIPH GOST_CIPHER_PARAMS *gcp = NULL; unsigned char *p; struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + int nid; + if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) { return ret; } @@@ -566,16 -490,7 +566,16 @@@ GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, GOST_R_INVALID_IV_LENGTH); return -1; } - if (!gost_cipher_set_param(c, OBJ_obj2nid(gcp->enc_param_set))) { + + nid = OBJ_obj2nid(gcp->enc_param_set); + if (nid == NID_undef) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, + GOST_R_INVALID_CIPHER_PARAM_OID); + return -1; + } + + if (!gost_cipher_set_param(c, nid)) { GOST_CIPHER_PARAMS_free(gcp); return -1; } @@@ -586,7 -501,7 +586,7 @@@ return 1; } -int gost_imit_init_cpa(EVP_MD_CTX *ctx) +static int gost_imit_init(EVP_MD_CTX *ctx, gost_subst_block * block) { struct ossl_gost_imit_ctx *c = ctx->md_data; memset(c->buffer, 0, sizeof(c->buffer)); @@@ -594,20 -509,10 +594,20 @@@ c->count = 0; c->bytes_left = 0; c->key_meshing = 1; - gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); + gost_init(&(c->cctx), block); return 1; } +static int gost_imit_init_cpa(EVP_MD_CTX *ctx) +{ + return gost_imit_init(ctx, &Gost28147_CryptoProParamSetA); +} + +static int gost_imit_init_cp_12(EVP_MD_CTX *ctx) +{ + return gost_imit_init(ctx, &Gost28147_TC26ParamSetZ); +} + static void mac_block_mesh(struct ossl_gost_imit_ctx *c, const unsigned char *data) { diff --combined gost_ctl.c index caf3bd5,31b95a0..8e3c1c6 --- a/gost_ctl.c +++ b/gost_ctl.c @@@ -15,28 -15,34 +15,28 @@@ #include "gost_lcl.h" static char *gost_params[GOST_PARAM_MAX + 1] = { NULL }; -static const char *gost_envnames[] = { "CRYPT_PARAMS" }; +static const char *gost_envnames[] = { "CRYPT_PARAMS", "GOST_PBE_HMAC" }; const ENGINE_CMD_DEFN gost_cmds[] = { -/*- { GOST_CTRL_RNG, - "RNG", - "Type of random number generator to use", - ENGINE_CMD_FLAG_STRING - }, - { GOST_CTRL_RNG_PARAMS, - "RNG_PARAMS", - "Parameter for random number generator", - ENGINE_CMD_FLAG_STRING - }, -*/ {GOST_CTRL_CRYPT_PARAMS, - "CRYPT_PARAMS", - "OID of default GOST 28147-89 parameters", - ENGINE_CMD_FLAG_STRING}, + {GOST_CTRL_CRYPT_PARAMS, + "CRYPT_PARAMS", + "OID of default GOST 28147-89 parameters", + ENGINE_CMD_FLAG_STRING}, + {GOST_CTRL_PBE_PARAMS, + "PBE_PARAMS", + "Shortname of default digest alg for PBE", + ENGINE_CMD_FLAG_STRING}, {0, NULL, NULL, 0} }; void gost_param_free() { int i; - for (i = 0; i <= GOST_PARAM_MAX; i++) - if (gost_params[i] != NULL) { - OPENSSL_free(gost_params[i]); - gost_params[i] = NULL; - } + + for (i = 0; i <= GOST_PARAM_MAX; i++) { + OPENSSL_free(gost_params[i]); + gost_params[i] = NULL; + } } @@@ -60,8 -66,7 +60,7 @@@ const char *get_gost_engine_param(int p } tmp = getenv(gost_envnames[param]); if (tmp) { - if (gost_params[param]) - OPENSSL_free(gost_params[param]); + OPENSSL_free(gost_params[param]); gost_params[param] = BUF_strdup(tmp); return gost_params[param]; } @@@ -79,8 -84,7 +78,7 @@@ int gost_set_default_param(int param, c */ if (!tmp) tmp = value; - if (gost_params[param]) - OPENSSL_free(gost_params[param]); + OPENSSL_free(gost_params[param]); gost_params[param] = BUF_strdup(tmp); return 1; diff --combined gost_ec_keyx.c index 2dd0d3a,0000000..7a80d23 mode 100644,000000..100644 --- a/gost_ec_keyx.c +++ b/gost_ec_keyx.c @@@ -1,339 -1,0 +1,337 @@@ +/********************************************************************** + * gost_ec_keyx.c * + * Copyright (c) 2005-2013 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * VK0 34.10-2001 key exchange and GOST R 34.10-2001 * + * based PKCS7/SMIME support * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include +#include +#include +#include "gost89.h" +#include "e_gost_err.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" + +/* Implementation of CryptoPro VKO 34.10-2001/2012 algorithm */ +static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size, + const EC_POINT *pub_key, EC_KEY *priv_key, + const unsigned char *ukm, int dgst_nid) +{ + unsigned char *databuf = NULL, *hashbuf = NULL; + BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; + const BIGNUM *key = EC_KEY_get0_private_key(priv_key); + EC_POINT *pnt = EC_POINT_new(EC_KEY_get0_group(priv_key)); + int i; + BN_CTX *ctx = BN_CTX_new(); + EVP_MD_CTX mdctx; + const EVP_MD *md; + int effective_dgst_nid = (dgst_nid == NID_id_GostR3411_2012_512) ? + NID_id_GostR3411_2012_256 : dgst_nid; + int buf_len = (dgst_nid == NID_id_GostR3411_2012_512) ? 128 : 64, + half_len = buf_len >> 1; + + if (!ctx) { + GOSTerr(GOST_F_VKO_COMPUTE_KEY, GOST_R_NO_MEMORY); + return 0; + } + BN_CTX_start(ctx); + + databuf = OPENSSL_malloc(buf_len); + hashbuf = OPENSSL_malloc(buf_len); + if (!databuf || !hashbuf) { + GOSTerr(GOST_F_VKO_COMPUTE_KEY, GOST_R_MALLOC_FAILURE); + goto err; + } + + md = EVP_get_digestbynid(effective_dgst_nid); + if (!md) { + GOSTerr(GOST_F_VKO_COMPUTE_KEY, GOST_R_INVALID_DIGEST_TYPE); + goto err; + } + + UKM = hashsum2bn(ukm, 8); + p = BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + EC_GROUP_get_order(EC_KEY_get0_group(priv_key), order, ctx); + BN_mod_mul(p, key, UKM, order, ctx); + EC_POINT_mul(EC_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); + EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key), + pnt, X, Y, ctx); + /* + * Serialize elliptic curve point same way as we do it when saving key + */ + store_bignum(Y, databuf, half_len); + store_bignum(X, databuf + half_len, half_len); + /* And reverse byte order of whole buffer */ + for (i = 0; i < buf_len; i++) { + hashbuf[buf_len - 1 - i] = databuf[i]; + } + EVP_MD_CTX_init(&mdctx); + EVP_DigestInit_ex(&mdctx, md, NULL); + EVP_DigestUpdate(&mdctx, hashbuf, buf_len); + EVP_DigestFinal_ex(&mdctx, shared_key, NULL); + EVP_MD_CTX_cleanup(&mdctx); + err: + BN_free(UKM); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(pnt); + if (databuf) + OPENSSL_free(databuf); + if (hashbuf) + OPENSSL_free(hashbuf); + + return 32; +} + +/* + * EVP_PKEY_METHOD callback derive. + * Implements VKO R 34.10-2001/2012 algorithms + */ +int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + /* + * Public key of peer in the ctx field peerkey + * Our private key in the ctx pkey + * ukm is in the algorithm specific context data + */ + EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); + EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + int dgst_nid = NID_undef; + + if (!data || !data->shared_ukm) { + GOSTerr(GOST_F_PKEY_GOST_EC_DERIVE, GOST_R_UKM_NOT_SET); + return 0; + } + + if (key == NULL) { + *keylen = 32; + return 32; + } + + EVP_PKEY_get_default_digest_nid(my_key, &dgst_nid); + + *keylen = + VKO_compute_key(key, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), + (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm, + dgst_nid); + return (*keylen) ? 1 : 0; +} + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptocom variation + */ +/* + * Generates ephemeral key based on pubk algorithm computes shared key using + * VKO and returns filled up GOST_KEY_TRANSPORT structure + */ + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ + +int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, + size_t *out_len, const unsigned char *key, + size_t key_len) +{ + GOST_KEY_TRANSPORT *gkt = NULL; + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); + int pkey_nid = EVP_PKEY_base_id(pubk); + ASN1_OBJECT *crypt_params_obj = (pkey_nid == NID_id_GostR3410_2001) ? + OBJ_nid2obj(NID_id_Gost28147_89_CryptoPro_A_ParamSet) : + OBJ_nid2obj(NID_id_tc26_gost_28147_param_Z); + const struct gost_cipher_info *param = + get_encryption_params(crypt_params_obj); + unsigned char ukm[8], shared_key[32], crypted_key[44]; + int ret = 0; + int key_is_ephemeral = 1; + gost_ctx cctx; + EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); + if (data->shared_ukm) { + memcpy(ukm, data->shared_ukm, 8); + } else if (out) { + + if (RAND_bytes(ukm, 8) <= 0) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, + GOST_R_RANDOM_GENERATOR_FAILURE); + return 0; + } + } + /* Check for private key in the peer_key of context */ + if (sec_key) { + key_is_ephemeral = 0; + if (!gost_get0_priv_key(sec_key)) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } else { + key_is_ephemeral = 1; + if (out) { + sec_key = EVP_PKEY_new(); + EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); + EVP_PKEY_copy_parameters(sec_key, pubk); + if (!gost_ec_keygen(EVP_PKEY_get0(sec_key))) { + goto err; + } + } + } + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) + && param == gost_cipher_list) { + param = gost_cipher_list + 1; + } + if (out) { + int dgst_nid = NID_undef; + EVP_PKEY_get_default_digest_nid(pubk, &dgst_nid); + + if (!VKO_compute_key(shared_key, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)), + EVP_PKEY_get0(sec_key), ukm, dgst_nid)) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + gost_init(&cctx, param->sblock); + keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (!gkt) { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { + goto err; + } + if (!ASN1_OCTET_STRING_set + (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { + goto err; + } + if (key_is_ephemeral) { + if (!X509_PUBKEY_set + (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, + GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); - if (key_is_ephemeral && sec_key) ++ if (key_is_ephemeral) + EVP_PKEY_free(sec_key); + if (!key_is_ephemeral) { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) + <= 0) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) + ret = 1; + GOST_KEY_TRANSPORT_free(gkt); + return ret; + err: - if (key_is_ephemeral && sec_key) ++ if (key_is_ephemeral) + EVP_PKEY_free(sec_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; +} + +/* + * EVP_PKEY_METHOD callback decrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ +int pkey_GOST_ECcp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, + size_t *key_len, const unsigned char *in, + size_t in_len) +{ + const unsigned char *p = in; + EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); + GOST_KEY_TRANSPORT *gkt = NULL; + int ret = 0; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + gost_ctx ctx; + const struct gost_cipher_info *param = NULL; + EVP_PKEY *eph_key = NULL, *peerkey = NULL; + int dgst_nid = NID_undef; + + if (!key) { + *key_len = 32; + return 1; + } + gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); + if (!gkt) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, + GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return -1; + } + + /* If key transport structure contains public key, use it */ + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key) { + if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, + GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } else { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) + <= 0) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(pctx); + if (!peerkey) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, GOST_R_NO_PEER_KEY); + goto err; + } + + param = get_encryption_params(gkt->key_agreement_info->cipher); + if (!param) { + goto err; + } + + gost_init(&ctx, param->sblock); + OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8); + memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); + OPENSSL_assert(gkt->key_info->encrypted_key->length == 32); + memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); + OPENSSL_assert(gkt->key_info->imit->length == 4); + memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); + + EVP_PKEY_get_default_digest_nid(priv, &dgst_nid); + if (!VKO_compute_key(sharedKey, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)), + EVP_PKEY_get0(priv), wrappedKey, dgst_nid)) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) { + GOSTerr(GOST_F_PKEY_GOST_ECCP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + ret = 1; + err: - if (eph_key) - EVP_PKEY_free(eph_key); - if (gkt) - GOST_KEY_TRANSPORT_free(gkt); ++ EVP_PKEY_free(eph_key); ++ GOST_KEY_TRANSPORT_free(gkt); + return ret; +} diff --combined gost_ec_sign.c index 38c50ac,0000000..8821799 mode 100644,000000..100644 --- a/gost_ec_sign.c +++ b/gost_ec_sign.c @@@ -1,511 -1,0 +1,525 @@@ +/********************************************************************** + * gost_ec_sign.c * + * Copyright (c) 2005-2013 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.10-2001 * + * Requires OpenSSL 1.0.0+ for compilation * + **********************************************************************/ +#include "gost_lcl.h" - #include "gost_params.h" +#include +#include +#include +#include +#include "e_gost_err.h" +#ifdef DEBUG_SIGN +extern +void dump_signature(const char *message, const unsigned char *buffer, + size_t len); +void dump_dsa_sig(const char *message, DSA_SIG *sig); +#else + +# define dump_signature(a,b,c) +# define dump_dsa_sig(a,b) +#endif + ++/* Convert little-endian byte array into bignum */ ++BIGNUM *hashsum2bn(const unsigned char *dgst, int len) ++{ ++ unsigned char buf[64]; ++ int i; ++ ++ if (len > sizeof(buf)) ++ return NULL; ++ ++ for (i = 0; i < len; i++) { ++ buf[len - i - 1] = dgst[i]; ++ } ++ return getbnfrombuf(buf, len); ++} ++ +static R3410_ec_params *gost_nid2params(int nid) +{ + R3410_ec_params *params; + + /* Search nid in 2012 paramset */ + params = R3410_2012_512_paramset; + while (params->nid != NID_undef) { + if (params->nid == nid) + return params; + params++; + } + + /* Search nid in 2001 paramset */ + params = R3410_2001_paramset; + while (params->nid != NID_undef) { + if (params->nid == nid) + return params; + params++; + } + + return NULL; +} + +/* + * Fills EC_KEY structure hidden in the app_data field of DSA structure + * with parameter information, extracted from parameter array in + * params.c file. + * + * Also fils DSA->q field with copy of EC_GROUP order field to make + * DSA_size function work + */ +int fill_GOST_EC_params(EC_KEY *eckey, int nid) +{ + R3410_ec_params *params = gost_nid2params(nid); + EC_GROUP *grp = NULL; + EC_POINT *P = NULL; + BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; + BN_CTX *ctx; + int ok = 0; + + if (!eckey || !params) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET); + return 0; + } + + if (!(ctx = BN_CTX_new())) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE); + return 0; + } + + BN_CTX_start(ctx); + p = BN_CTX_get(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + if (!p || !a || !b || !x || !y || !q) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!BN_hex2bn(&p, params->p) + || !BN_hex2bn(&a, params->a) + || !BN_hex2bn(&b, params->b)) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR); + goto end; + } + + grp = EC_GROUP_new_curve_GFp(p, a, b, ctx); + if (!grp) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE); + goto end; + } + + P = EC_POINT_new(grp); + if (!P) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!BN_hex2bn(&x, params->x) + || !BN_hex2bn(&y, params->y) + || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx) + || !BN_hex2bn(&q, params->q)) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR); + goto end; + } + + if (!EC_GROUP_set_generator(grp, P, q, NULL)) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR); + goto end; + } + EC_GROUP_set_curve_name(grp, params->nid); + if (!EC_KEY_set_group(eckey, grp)) { + GOSTerr(GOST_F_FILL_GOST_EC_PARAMS, ERR_R_INTERNAL_ERROR); + goto end; + } + ok = 1; +end: + if (P) + EC_POINT_free(P); + if (grp) + EC_GROUP_free(grp); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} + +/* + * Computes gost_ec signature as DSA_SIG structure + * + */ +DSA_SIG *gost_ec_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) +{ + DSA_SIG *newsig = NULL, *ret = NULL; + BIGNUM *md = NULL; + BIGNUM *order = NULL; + const EC_GROUP *group; + const BIGNUM *priv_key; + BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, + *k = NULL, *e = NULL; + EC_POINT *C = NULL; + BN_CTX *ctx; + + OPENSSL_assert(dgst != NULL && eckey != NULL); + + if (!(ctx = BN_CTX_new())) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + BN_CTX_start(ctx); + OPENSSL_assert(dlen == 32 || dlen == 64); + md = hashsum2bn(dgst, dlen); + newsig = DSA_SIG_new(); + if (!newsig || !md) { + GOSTerr(GOST_F_GOST_EC_SIGN, GOST_R_NO_MEMORY); + goto err; + } + group = EC_KEY_get0_group(eckey); + if (!group) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + order = BN_CTX_get(ctx); + if (!order || !EC_GROUP_get_order(group, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + priv_key = EC_KEY_get0_private_key(eckey); + if (!priv_key) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + e = BN_CTX_get(ctx); + if (!e || !BN_mod(e, md, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "digest as bignum="); + BN_print_fp(stderr, md); + fprintf(stderr, "\ndigest mod q="); + BN_print_fp(stderr, e); + fprintf(stderr, "\n"); +#endif + if (BN_is_zero(e)) { + BN_one(e); + } + k = BN_CTX_get(ctx); + C = EC_POINT_new(group); + if (!k || !C) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + do { + do { + if (!BN_rand_range(k, order)) { + GOSTerr(GOST_F_GOST_EC_SIGN, + GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + goto err; + } + /* + * To avoid timing information leaking the length of k, + * compute C*k using an equivalent scalar of fixed bit-length */ + if (!BN_add(k, k, order) + || (BN_num_bits(k) <= BN_num_bits(order) + && !BN_add(k, k, order))) { + goto err; + } + if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_EC_LIB); + goto err; + } + if (!X) + X = BN_CTX_get(ctx); + if (!r) + r = BN_CTX_get(ctx); + if (!X || !r) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_EC_LIB); + goto err; + } + + if (!BN_nnmod(r, X, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + } + while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (!tmp) + tmp = BN_CTX_get(ctx); + if (!tmp2) + tmp2 = BN_CTX_get(ctx); + if (!s) + s = BN_CTX_get(ctx); + if (!tmp || !tmp2 || !s) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BN_mod_mul(tmp, priv_key, r, order, ctx) + || !BN_mod_mul(tmp2, k, e, order, ctx) + || !BN_mod_add(s, tmp, tmp2, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + } + while (BN_is_zero(s)); + + newsig->s = BN_dup(s); + newsig->r = BN_dup(r); + if (!newsig->s || !newsig->r) { + GOSTerr(GOST_F_GOST_EC_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ret = newsig; + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (C) + EC_POINT_free(C); + if (md) + BN_free(md); + if (!ret && newsig) { + DSA_SIG_free(newsig); + } + return ret; +} + +/* + * Verifies gost ec signature + * + */ +int gost_ec_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, EC_KEY *ec) +{ + BN_CTX *ctx; + const EC_GROUP *group = (ec) ? EC_KEY_get0_group(ec) : NULL; + BIGNUM *order; + BIGNUM *md = NULL, *e = NULL, *R = NULL, *v = NULL, + *z1 = NULL, *z2 = NULL; + BIGNUM *X = NULL, *tmp = NULL; + EC_POINT *C = NULL; + const EC_POINT *pub_key = NULL; + int ok = 0; + + OPENSSL_assert(dgst != NULL && sig != NULL && group != NULL); + + if (!(ctx = BN_CTX_new())) { + GOSTerr(GOST_F_GOST_EC_VERIFY, GOST_R_NO_MEMORY); + return 0; + } + + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + e = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + z2 = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + R = BN_CTX_get(ctx); + v = BN_CTX_get(ctx); + if (!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + pub_key = EC_KEY_get0_public_key(ec); + if (!pub_key || !EC_GROUP_get_order(group, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || + (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; + + } + + OPENSSL_assert(dgst_len == 32 || dgst_len == 64); + md = hashsum2bn(dgst, dgst_len); + if (!md || !BN_mod(e, md, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "digest as bignum: "); + BN_print_fp(stderr, md); + fprintf(stderr, "\ndigest mod q: "); + BN_print_fp(stderr, e); +#endif + if (BN_is_zero(e) && !BN_one(e)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + v = BN_mod_inverse(v, e, order, ctx); + if (!v + || !BN_mod_mul(z1, sig->s, v, order, ctx) + || !BN_sub(tmp, order, sig->r) + || !BN_mod_mul(z2, tmp, v, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "\nInverted digest value: "); + BN_print_fp(stderr, v); + fprintf(stderr, "\nz1: "); + BN_print_fp(stderr, z1); + fprintf(stderr, "\nz2: "); + BN_print_fp(stderr, z2); +#endif + C = EC_POINT_new(group); + if (!C) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (!BN_mod(R, X, order, ctx)) { + GOSTerr(GOST_F_GOST_EC_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "\nX="); + BN_print_fp(stderr, X); + fprintf(stderr, "\nX mod q="); + BN_print_fp(stderr, R); + fprintf(stderr, "\n"); +#endif + if (BN_cmp(R, sig->r) != 0) { + GOSTerr(GOST_F_GOST_EC_VERIFY, GOST_R_SIGNATURE_MISMATCH); + } else { + ok = 1; + } + err: + if (C) + EC_POINT_free(C); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (md) + BN_free(md); + return ok; +} + +/* + * Computes GOST R 34.10-2001 public key + * or GOST R 34.10-2012 public key + * + */ +int gost_ec_compute_public(EC_KEY *ec) +{ + const EC_GROUP *group = (ec) ? EC_KEY_get0_group(ec) : NULL; + EC_POINT *pub_key = NULL; + const BIGNUM *priv_key = NULL; + BN_CTX *ctx = NULL; + int ok = 0; + + if (!group) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITIALIZED); + return 0; + } + + ctx = BN_CTX_new(); + if (!ctx) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + return 0; + } + + BN_CTX_start(ctx); + priv_key = EC_KEY_get0_private_key(ec); + if (!priv_key) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + + pub_key = EC_POINT_new(group); + if (!pub_key) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + if (!EC_KEY_set_public_key(ec, pub_key)) { + GOSTerr(GOST_F_GOST_EC_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + ok = 1; + err: + if (pub_key) + EC_POINT_free(pub_key); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} + +/* + * + * Generates GOST R 34.10-2001 + * or GOST R 34.10-2012 keypair + * + */ +int gost_ec_keygen(EC_KEY *ec) +{ + BIGNUM *order = NULL, *d = NULL; + const EC_GROUP *group = (ec) ? EC_KEY_get0_group(ec) : NULL; + int ok = 0; + + if (!group) { + GOSTerr(GOST_F_GOST_EC_KEYGEN, ERR_R_INTERNAL_ERROR); + return 0; + } + + order = BN_new(); + d = BN_new(); + if (!order || !d) { + GOSTerr(GOST_F_GOST_EC_KEYGEN, ERR_R_MALLOC_FAILURE); + goto end; + } + + if (!EC_GROUP_get_order(group, order, NULL)) { + GOSTerr(GOST_F_GOST_EC_KEYGEN, ERR_R_INTERNAL_ERROR); + goto end; + } + + do { + if (!BN_rand_range(d, order)) { + GOSTerr(GOST_F_GOST_EC_KEYGEN, + GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + goto end; + } + } + while (BN_is_zero(d)); + + if (!EC_KEY_set_private_key(ec, d)) { + GOSTerr(GOST_F_GOST_EC_KEYGEN, ERR_R_INTERNAL_ERROR); + goto end; + } + + ok = 1; +end: + if (d) + BN_free(d); + if (order) + BN_free(order); + + return (ok) ? gost_ec_compute_public(ec) : 0; +} diff --combined gost_eng.c index f86169b,4129260..9df6a74 --- a/gost_eng.c +++ b/gost_eng.c @@@ -19,6 -19,10 +19,6 @@@ static const char *engine_gost_id = "go static const char *engine_gost_name = "Reference implementation of GOST engine"; -static int gost_pkey_meth_nids[] = { - NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0 -}; - /* Symmetric cipher and digest function registrar */ static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, @@@ -33,45 -37,16 +33,42 @@@ static int gost_pkey_meths(ENGINE *e, E static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, const int **nids, int nid); -static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 }; +static int gost_cipher_nids[] = { + NID_id_Gost28147_89, + NID_gost89_cnt, + NID_gost89_cnt_12, + 0 +}; -static int gost_digest_nids[] = - { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 }; +static int gost_digest_nids[] = { + NID_id_GostR3411_94, + NID_id_Gost28147_89_MAC, + NID_id_GostR3411_2012_256, + NID_id_GostR3411_2012_512, + NID_gost_mac_12, + 0 +}; + +static int gost_pkey_meth_nids[] = { - NID_id_GostR3410_94, + NID_id_GostR3410_2001, + NID_id_Gost28147_89_MAC, + NID_id_GostR3410_2012_256, + NID_id_GostR3410_2012_512, + NID_gost_mac_12, + 0 +}; - static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, - *pmeth_GostR3410_2001 = NULL, -static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL; -static EVP_PKEY_METHOD *pmeth_Gost28147_MAC = NULL; ++static EVP_PKEY_METHOD *pmeth_GostR3410_2001 = NULL, + *pmeth_GostR3410_2012_256 = NULL, + *pmeth_GostR3410_2012_512 = NULL, + *pmeth_Gost28147_MAC = NULL, + *pmeth_Gost28147_MAC_12 = NULL; - static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, - *ameth_GostR3410_2001 = NULL, -static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_2001 = NULL; -static EVP_PKEY_ASN1_METHOD *ameth_Gost28147_MAC = NULL; ++static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_2001 = NULL, + *ameth_GostR3410_2012_256 = NULL, + *ameth_GostR3410_2012_512 = NULL, + *ameth_Gost28147_MAC = NULL, + *ameth_Gost28147_MAC_12 = NULL; static int gost_engine_init(ENGINE *e) { @@@ -87,20 -62,10 +84,18 @@@ static int gost_engine_destroy(ENGINE * { gost_param_free(); - pmeth_GostR3410_94 = NULL; pmeth_GostR3410_2001 = NULL; pmeth_Gost28147_MAC = NULL; + pmeth_GostR3410_2012_256 = NULL; + pmeth_GostR3410_2012_512 = NULL; + pmeth_Gost28147_MAC_12 = NULL; + - ameth_GostR3410_94 = NULL; ameth_GostR3410_2001 = NULL; ameth_Gost28147_MAC = NULL; + ameth_GostR3410_2012_256 = NULL; + ameth_GostR3410_2012_512 = NULL; + ameth_Gost28147_MAC_12 = NULL; + return 1; } @@@ -109,11 -74,11 +104,10 @@@ static int bind_gost(ENGINE *e, const c int ret = 0; if (id && strcmp(id, engine_gost_id)) return 0; - - if (ameth_GostR3410_94) { + if (ameth_GostR3410_2001) { printf("GOST engine already loaded\n"); goto end; } - if (!ENGINE_set_id(e, engine_gost_id)) { printf("ENGINE_set_id failed\n"); goto end; @@@ -153,44 -118,17 +147,39 @@@ goto end; } - if (!register_ameth_gost - (NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", - "GOST R 34.10-94")) - goto end; if (!register_ameth_gost (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end; + if (!register_ameth_gost + (NID_id_GostR3410_2012_256, &ameth_GostR3410_2012_256, "GOST2012_256", + "GOST R 34.10-2012 with 256 bit key")) + goto end; + if (!register_ameth_gost + (NID_id_GostR3410_2012_512, &ameth_GostR3410_2012_512, "GOST2012_512", + "GOST R 34.10-2012 with 512 bit key")) + goto end; if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, "GOST-MAC", "GOST 28147-89 MAC")) goto end; + if (!register_ameth_gost(NID_gost_mac_12, &ameth_Gost28147_MAC_12, + "GOST-MAC-12", + "GOST 28147-89 MAC with 2012 params")) + goto end; - if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) - goto end; if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end; - if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) ++ + if (!register_pmeth_gost + (NID_id_GostR3410_2012_256, &pmeth_GostR3410_2012_256, 0)) + goto end; + if (!register_pmeth_gost + (NID_id_GostR3410_2012_512, &pmeth_GostR3410_2012_512, 0)) + goto end; + if (!register_pmeth_gost + (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) + goto end; + if (!register_pmeth_gost(NID_gost_mac_12, &pmeth_Gost28147_MAC_12, 0)) goto end; if (!ENGINE_register_ciphers(e) || !ENGINE_register_digests(e) @@@ -198,12 -136,8 +187,12 @@@ /* These two actually should go in LIST_ADD command */ || !EVP_add_cipher(&cipher_gost) || !EVP_add_cipher(&cipher_gost_cpacnt) + || !EVP_add_cipher(&cipher_gost_cpcnt_12) || !EVP_add_digest(&digest_gost) + || !EVP_add_digest(&digest_gost2012_512) + || !EVP_add_digest(&digest_gost2012_256) || !EVP_add_digest(&imit_gost_cpa) + || !EVP_add_digest(&imit_gost_cp_12) ) { goto end; } @@@ -224,18 -158,15 +213,18 @@@ static int gost_digests(ENGINE *e, cons int ok = 1; if (!digest) { *nids = gost_digest_nids; - return 2; + return 5; } - /* - * printf("Digest no %d requested\n",nid); - */ if (nid == NID_id_GostR3411_94) { *digest = &digest_gost; + } else if (nid == NID_id_GostR3411_2012_256) { + *digest = &digest_gost2012_256; + } else if (nid == NID_id_GostR3411_2012_512) { + *digest = &digest_gost2012_512; } else if (nid == NID_id_Gost28147_89_MAC) { *digest = &imit_gost_cpa; + } else if (nid == NID_gost_mac_12) { + *digest = &imit_gost_cp_12; } else { ok = 0; *digest = NULL; @@@ -249,15 -180,13 +238,15 @@@ static int gost_ciphers(ENGINE *e, cons int ok = 1; if (!cipher) { *nids = gost_cipher_nids; - return 2; /* two ciphers are supported */ + return 3; /* three ciphers are supported */ } if (nid == NID_id_Gost28147_89) { *cipher = &cipher_gost; } else if (nid == NID_gost89_cnt) { *cipher = &cipher_gost_cpacnt; + } else if (nid == NID_gost89_cnt_12) { + *cipher = &cipher_gost_cpcnt_12; } else { ok = 0; *cipher = NULL; @@@ -270,29 -199,16 +259,26 @@@ static int gost_pkey_meths(ENGINE *e, E { if (!pmeth) { *nids = gost_pkey_meth_nids; - return 6; - return 2; ++ return sizeof(gost_pkey_meth_nids)/sizeof(int) - 1; } switch (nid) { - case NID_id_GostR3410_94: - *pmeth = pmeth_GostR3410_94; - return 1; case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; + case NID_id_GostR3410_2012_256: + *pmeth = pmeth_GostR3410_2012_256; + return 1; + case NID_id_GostR3410_2012_512: + *pmeth = pmeth_GostR3410_2012_512; + return 1; case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1; + case NID_gost_mac_12: + *pmeth = pmeth_Gost28147_MAC_12; + return 1; + default:; } @@@ -305,27 -221,15 +291,24 @@@ static int gost_pkey_asn1_meths(ENGINE { if (!ameth) { *nids = gost_pkey_meth_nids; - return 6; - return 2; ++ return sizeof(gost_pkey_meth_nids)/sizeof(int) - 1; } switch (nid) { - case NID_id_GostR3410_94: - *ameth = ameth_GostR3410_94; - return 1; case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; + case NID_id_GostR3410_2012_256: + *ameth = ameth_GostR3410_2012_256; + return 1; + case NID_id_GostR3410_2012_512: + *ameth = ameth_GostR3410_2012_512; + return 1; case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1; + case NID_gost_mac_12: + *ameth = ameth_Gost28147_MAC_12; + return 1; default:; } @@@ -350,7 -254,7 +333,7 @@@ static ENGINE *engine_gost(void void ENGINE_load_gost(void) { ENGINE *toadd; - if (pmeth_GostR3410_94) + if (pmeth_GostR3410_2001) return; toadd = engine_gost(); if (!toadd) diff --combined gost_lcl.h index 61c2aa6,27fe0e7..4e1c4ea --- a/gost_lcl.h +++ b/gost_lcl.h @@@ -20,11 -20,21 +20,25 @@@ # include "gosthash.h" /* Control commands */ # define GOST_PARAM_CRYPT_PARAMS 0 -# define GOST_PARAM_MAX 0 +# define GOST_PARAM_PBE_PARAMS 1 +# define GOST_PARAM_MAX 1 # define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) +# define GOST_CTRL_PBE_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_PBE_PARAMS) -typedef struct R3410_2001 { ++typedef struct R3410_ec { + int nid; + char *a; + char *b; + char *p; + char *q; + char *x; + char *y; -} R3410_2001_params; ++} R3410_ec_params; + -extern R3410_2001_params R3410_2001_paramset[]; ++extern R3410_ec_params R3410_2001_paramset[], ++ *R3410_2012_256_paramset, ++ R3410_2012_512_paramset[]; + extern const ENGINE_CMD_DEFN gost_cmds[]; int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); const char *get_gost_engine_param(int param); @@@ -119,14 -129,6 +133,14 @@@ typedef struct } GOST_CIPHER_PARAMS; DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) + +typedef struct { + ASN1_OCTET_STRING *masked_priv_key; + ASN1_OCTET_STRING *public_key; +} MASKED_GOST_KEY; + +DECLARE_ASN1_FUNCTIONS(MASKED_GOST_KEY) + /*============== Message digest and cipher related structures ==========*/ /* * Structure used as EVP_MD_CTX-md_data. It allows to avoid storing @@@ -142,12 -144,8 +156,12 @@@ struct ossl_gost_digest_ctx }; /* EVP_MD structure for GOST R 34.11 */ extern EVP_MD digest_gost; +/* EVP MD structure for GOST R 34.11-2012 algorithms */ +extern EVP_MD digest_gost2012_256; +extern EVP_MD digest_gost2012_512; /* EVP_MD structure for GOST 28147 in MAC mode */ extern EVP_MD imit_gost_cpa; +extern EVP_MD imit_gost_cp_12; /* Cipher context used for EVP_CIPHER operation */ struct ossl_gost_cipher_ctx { int paramNID; @@@ -178,51 -176,38 +192,37 @@@ const struct gost_cipher_info *get_encr /* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ extern EVP_CIPHER cipher_gost; extern EVP_CIPHER cipher_gost_cpacnt; +extern EVP_CIPHER cipher_gost_cpcnt_12; # define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) # define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) /* EVP_PKEY_METHOD key encryption callbacks */ - /* From gost94_keyx.c */ - int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, -/* From gost2001_keyx.c */ -int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, -- size_t *outlen, const unsigned char *key, -- size_t key_len); -- - int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, -int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, -- size_t *outlen, const unsigned char *in, -- size_t in_len); +/* From gost_ec_keyx.c */ +int pkey_GOST_ECcp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *key, + size_t key_len); + +int pkey_GOST_ECcp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t in_len); /* derive functions */ -/* From gost2001_keyx.c */ -int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen); -/* Internal functions for signature algorithms */ -int fill_GOST2001_params(EC_KEY *eckey, int nid); +/* From gost_ec_keyx.c */ +int pkey_gost_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen); - /* From gost94_keyx.c */ - int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); - /* Internal functions for signature algorithms */ - int fill_GOST94_params(DSA *dsa, int nid); +int fill_GOST_EC_params(EC_KEY *eckey, int nid); int gost_sign_keygen(DSA *dsa); -int gost2001_keygen(EC_KEY *ec); +int gost_ec_keygen(EC_KEY *ec); --DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); -DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey); +DSA_SIG *gost_ec_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey); int gost_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); -int gost2001_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, EC_KEY *ec); -int gost2001_compute_public(EC_KEY *ec); +int gost_ec_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, EC_KEY *ec); +int gost_ec_compute_public(EC_KEY *ec); - int gost94_compute_public(DSA *dsa); /*============== miscellaneous functions============================= */ /* from gost_sign.c */ /* Convert GOST R 34.11 hash sum to bignum according to standard */ -BIGNUM *hashsum2bn(const unsigned char *dgst); +BIGNUM *hashsum2bn(const unsigned char *dgst, int len); /* * Store bignum in byte array of given length, prepending by zeros if * nesseccary @@@ -232,13 -217,11 +232,9 @@@ int store_bignum(BIGNUM *bn, unsigned c BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len); /* Pack GOST R 34.10 signature according to CryptoPro rules */ int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen); --/* Unpack GOST R 34.10 signature according to CryptoPro rules */ --DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen); /* from ameth.c */ - /* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001 keys*/ + /* Get private key as BIGNUM from both 34.10-2001 keys*/ /* Returns pointer into EVP_PKEY structure */ BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey); - /* Find NID by GOST 94 parameters */ - int gost94_nid_by_params(DSA *p); #endif diff --combined gost_md2012.c index d909b4f,0000000..092de26 mode 100644,000000..100644 --- a/gost_md2012.c +++ b/gost_md2012.c @@@ -1,97 -1,0 +1,97 @@@ +/********************************************************************** + * gost_md2012.c * + * Copyright (c) 2013 Cryptocom LTD. * + * This file is distributed under the same license as OpenSSL * + * * + * GOST R 34.11-2012 interface to OpenSSL engine. * + * * + * Author: Alexey Degtyarev * + * * + **********************************************************************/ + +#include +#include "gosthash2012.h" + +static int gost_digest_init512(EVP_MD_CTX *ctx); +static int gost_digest_init256(EVP_MD_CTX *ctx); +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count); +static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); +static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); +static int gost_digest_cleanup(EVP_MD_CTX *ctx); + +EVP_MD digest_gost2012_512 = { + NID_id_GostR3411_2012_512, + NID_undef, + 64, /* digest size */ + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, + gost_digest_init512, + gost_digest_update, + gost_digest_final, + gost_digest_copy, + gost_digest_cleanup, + NULL, + NULL, + {NID_undef, NID_undef, 0, 0, 0}, + 64, /* block size */ + sizeof(gost2012_hash_ctx), + NULL +}; + +EVP_MD digest_gost2012_256 = { + NID_id_GostR3411_2012_256, + NID_undef, + 32, /* digest size */ + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, + gost_digest_init256, + gost_digest_update, + gost_digest_final, + gost_digest_copy, + gost_digest_cleanup, + NULL, + NULL, + {NID_undef, NID_undef, 0, 0, 0}, + 64, /* block size */ + sizeof(gost2012_hash_ctx), + NULL +}; + +static int gost_digest_init512(EVP_MD_CTX *ctx) +{ + init_gost2012_hash_ctx((gost2012_hash_ctx *) ctx->md_data, 512); + return 1; +} + +static int gost_digest_init256(EVP_MD_CTX *ctx) +{ + init_gost2012_hash_ctx((gost2012_hash_ctx *) ctx->md_data, 256); + return 1; +} + +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + gost2012_hash_block((gost2012_hash_ctx *) ctx->md_data, data, count); + return 1; +} + +static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + gost2012_finish_hash((gost2012_hash_ctx *) ctx->md_data, md); + return 1; +} + +static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + if (to->md_data && from->md_data) - memcpy(to->md_data, from->md_data, sizeof(from->md_data)); ++ memcpy(to->md_data, from->md_data, sizeof(*(from->md_data))); + + return 1; +} + +static int gost_digest_cleanup(EVP_MD_CTX *ctx) +{ + if (ctx->md_data) + memset(ctx->md_data, 0x00, sizeof(gost2012_hash_ctx)); + + return 1; +} diff --combined gost_params.c index b344a82,2371c9a..3e70990 --- a/gost_params.c +++ b/gost_params.c @@@ -1,144 -1,17 +1,17 @@@ /********************************************************************** * params.c * - * Copyright (c) 2005-2006 Cryptocom LTD * + * Copyright (c) 2005-2013 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357 * - * OpenSSL 0.9.9 libraries required to compile and use * + * OpenSSL 1.0.0+ libraries required to compile and use * * this code * **********************************************************************/ + #include "gost_lcl.h" #include - #include "gost_params.h" /* Parameters of GOST 34.10 */ - R3410_params R3410_paramset[] = { - /* Paramset A */ - {NID_id_GostR3410_94_CryptoPro_A_ParamSet, - "100997906755055304772081815535925224869" - "8410825720534578748235158755771479905292727772441528526992987964833" - "5669968284202797289605274717317548059048560713474685214192868091256" - "1502802222185647539190902656116367847270145019066794290930185446216" - "3997308722217328898303231940973554032134009725883228768509467406639" - "62", - "127021248288932417465907042777176443525" - "7876535089165358128175072657050312609850984974231883334834011809259" - "9999512098893413065920561499672425412104927434935707492031276956145" - "1689224110579311248812610229678534638401693520013288995000362260684" - "2227508135323070045173416336850045410625869714168836867788425378203" - "83", - "683631961449557007844441656118272528951" - "02170888761442055095051287550314083023"} - , - {NID_id_GostR3410_94_CryptoPro_B_ParamSet, - "429418261486158041438734477379555023926" - "7234596860714306679811299408947123142002706038521669956384871995765" - "7284814898909770759462613437669456364882730370838934791080835932647" - "9767786019153434744009610342313166725786869204821949328786333602033" - "8479709268434224762105576023501613261478065276102850944540333865234" - "1", - "139454871199115825601409655107690713107" - "0417070599280317977580014543757653577229840941243685222882398330391" - "1468164807668823692122073732267216074074777170091113455043205380464" - "7694904686120113087816240740184800477047157336662926249423571248823" - "9685422217536601433914856808405203368594584948031873412885804895251" - "63", - "79885141663410976897627118935756323747307951916507639758300472692338873533959"} - , - {NID_id_GostR3410_94_CryptoPro_C_ParamSet, - "816552717970881016017893191415300348226" - "2544051353358162468249467681876621283478212884286545844013955142622" - "2087723485023722868022275009502224827866201744494021697716482008353" - "6398202298024892620480898699335508064332313529725332208819456895108" - "5155178100221003459370588291073071186553005962149936840737128710832" - "3", - "110624679233511963040518952417017040248" - "5862954819831383774196396298584395948970608956170224210628525560327" - "8638246716655439297654402921844747893079518669992827880792192992701" - "1428546551433875806377110443534293554066712653034996277099320715774" - "3542287621283671843703709141350171945045805050291770503634517804938" - "01", - "113468861199819350564868233378875198043" - "267947776488510997961231672532899549103"} - , - {NID_id_GostR3410_94_CryptoPro_D_ParamSet, - "756976611021707301782128757801610628085" - "5283803109571158829574281419208532589041660017017859858216341400371" - "4687551412794400562878935266630754392677014598582103365983119173924" - "4732511225464712252386803315902707727668715343476086350472025298282" - "7271461690125050616858238384366331089777463541013033926723743254833" - "7", - "905457649621929965904290958774625315611" - "3056083907389766971404812524422262512556054474620855996091570786713" - "5849550236741915584185990627801066465809510095784713989819413820871" - "5964648914493053407920737078890520482730623038837767710173664838239" - "8574828787891286471201460474326612697849693665518073864436497893214" - "9", - "108988435796353506912374591498972192620" - "190487557619582334771735390599299211593"} - , - - {NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, - "1335318132727206734338595199483190012179423759678474868994823595993" - "6964252873471246159040332773182141032801252925387191478859899310331" - "0567744136196364803064721377826656898686468463277710150809401182608" - "7702016153249904683329312949209127762411378780302243557466062839716" - "59376426832674269780880061631528163475887", - "14201174159756348119636828602231808974327613839524373876287257344192" - "74593935127189736311660784676003608489466235676257952827747192122419" - "29071046134208380636394084512691828894000571524625445295769349356752" - "72895683154177544176313938445719175509684710784659566254794231229333" - "8483924514339614727760681880609734239", - "91771529896554605945588149018382750217296858393520724172743325725474" - "374979801"} - , - {NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, - "8890864727828423151699995801875757891031463338652579140051973659" - "3048131440685857067369829407947744496306656291505503608252399443" - "7900272386749145996230867832228661977543992816745254823298629859" - "8753575466286051738837854736167685769017780335804511440773337196" - "2538423532919394477873664752824509986617878992443177", - "1028946126624994859676552074360530315217970499989304888248413244" - "8474923022758470167998871003604670704877377286176171227694098633" - "1539089568784129110109512690503345393869871295783467257264868341" - "7200196629860561193666752429682367397084815179752036423595736533" - "68957392061769855284593965042530895046088067160269433", - "9109671391802626916582318050603555673628769498182593088388796888" - "5281641595199"} - , - {NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, - "4430618464297584182473135030809859326863990650118941756995270074" - "8609973181426950235239623239110557450826919295792878938752101867" - "7047181623251027516953100431855964837602657827828194249605561893" - "6965865325513137194483136247773653468410118796740709840825496997" - "9375560722345106704721086025979309968763193072908334", - "1246996366993477513607147265794064436203408861395055989217248455" - "7299870737698999651480662364723992859320868822848751165438350943" - "3276647222625940615560580450040947211826027729977563540237169063" - "0448079715771649447778447000597419032457722226253269698374446528" - "35352729304393746106576383349151001715930924115499549", - "6787876137336591234380295020065682527118129468050147943114675429" - "4748422492761"} - , - - {NID_undef, NULL, NULL, NULL} - }; - -R3410_2001_params R3410_2001_paramset[] = { +R3410_ec_params R3410_2001_paramset[] = { - /* default_cc_sign01_param 1.2.643.2.9.1.8.1 */ - {NID_id_GostR3410_2001_ParamSet_cc, - /* A */ - "C0000000000000000000000000000000000000000000000000000000000003c4", - /* B */ - "2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c", - /* P */ - "C0000000000000000000000000000000000000000000000000000000000003C7", - /* Q */ - "5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85", - /* X */ - "2", - /* Y */ - "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"} - , /* 1.2.643.2.2.35.0 */ {NID_id_GostR3410_2001_TestParamSet, "7", @@@ -203,51 -76,5 +76,51 @@@ "0", "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"} , - {0, NULL, NULL, NULL, NULL, NULL, NULL} + {NID_undef, NULL, NULL, NULL, NULL, NULL, NULL} +}; + +/* Parameters of GOST 34.10-2012 */ + +R3410_ec_params *R3410_2012_256_paramset = R3410_2001_paramset; + +R3410_ec_params R3410_2012_512_paramset[] = { + {NID_id_tc26_gost_3410_2012_512_paramSetA, + /* a */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC4", + /* b */ + "E8C2505DEDFC86DDC1BD0B2B6667F1DA34B82574761CB0E879BD081CFD0B6265" + "EE3CB090F30D27614CB4574010DA90DD862EF9D4EBEE4761503190785A71C760", + /* p */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDC7", + /* q */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "27E69532F48D89116FF22B8D4E0560609B4B38ABFAD2B85DCACDB1411F10B275", + /* x */ + "3", + /* y */ + "7503CFE87A836AE3A61B8816E25450E6CE5E1C93ACF1ABC1778064FDCBEFA921DF16" + "26BE4FD036E93D75E6A50E3A41E98028FE5FC235F5B889A589CB5215F2A4"} + , + {NID_id_tc26_gost_3410_2012_512_paramSetB, + /* a */ + "8000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000006C", + /* b */ + "687D1B459DC841457E3E06CF6F5E2517B97C7D614AF138BCBF85DC806C4B289F" + "3E965D2DB1416D217F8B276FAD1AB69C50F78BEE1FA3106EFB8CCBC7C5140116", + /* p */ + "8000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000006F", + /* q */ + "8000000000000000000000000000000000000000000000000000000000000001" + "49A1EC142565A545ACFDB77BD9D40CFA8B996712101BEA0EC6346C54374F25BD", + /* x */ + "2", + /* y */ + "1A8F7EDA389B094C2C071E3647A8940F3C123B697578C213BE6DD9E6C8EC7335" + "DCB228FD1EDF4A39152CBCAAF8C0398828041055F94CEEEC7E21340780FE41BD"} + , + {NID_undef, NULL, NULL, NULL, NULL, NULL, NULL} }; diff --combined gost_pmeth.c index e87c519,0574d6e..a825217 --- a/gost_pmeth.c +++ b/gost_pmeth.c @@@ -1,52 -1,41 +1,50 @@@ /********************************************************************** * gost_pmeth.c * - * Copyright (c) 2005-2006 Cryptocom LTD * + * Copyright (c) 2005-2013 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * * Implementation of RFC 4357 (GOST R 34.10) Publick key method * * for OpenSSL * - * Requires OpenSSL 0.9.9 for compilation * + * Requires OpenSSL 1.0.0+ for compilation * **********************************************************************/ #include #include #include + #include #include /* For string_to_hex */ #include #include #include - #include "gost_params.h" #include "gost_lcl.h" #include "e_gost_err.h" -/* -----init, cleanup, copy - uniform for all algs ---------------*/ + +/* -----init, cleanup, copy - uniform for all algs --------------*/ /* Allocates new gost_pmeth_data structure and assigns it as data */ static int pkey_gost_init(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); + + data = OPENSSL_malloc(sizeof(*data)); if (!data) return 0; - memset(data, 0, sizeof(struct gost_pmeth_data)); + memset(data, 0, sizeof(*data)); if (pkey && EVP_PKEY_get0(pkey)) { switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey)); - break; case NID_id_GostR3410_2001: - data->sign_param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)pkey))); - break; + case NID_id_GostR3410_2012_256: + case NID_id_GostR3410_2012_512: + { + const EC_GROUP *group = + EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)); + if (group != NULL) { + data->sign_param_nid = EC_GROUP_get_curve_name(group); + break; + } + /* else */ + } default: + OPENSSL_free(data); return 0; } } @@@ -63,9 -52,6 +61,9 @@@ static int pkey_gost_copy(EVP_PKEY_CTX } src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); + if (!src_data || !dst_data) + return 0; + *dst_data = *src_data; if (src_data->shared_ukm) { dst_data->shared_ukm = NULL; @@@ -77,10 -63,8 +75,9 @@@ static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - + if (!data) + return; - if (data->shared_ukm) - OPENSSL_free(data->shared_ukm); + OPENSSL_free(data->shared_ukm); OPENSSL_free(data); } @@@ -89,43 -73,15 +86,43 @@@ static int pkey_gost_ctrl(EVP_PKEY_CTX { struct gost_pmeth_data *pctx = (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); + if (pctx == NULL) + return 0; + switch (type) { case EVP_PKEY_CTRL_MD: { - if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { - GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); - return 0; + EVP_PKEY *key = EVP_PKEY_CTX_get0_pkey(ctx); + int pkey_nid = (key == NULL) ? NID_undef : EVP_PKEY_base_id(key); + + OPENSSL_assert(p2 != NULL); + + switch (EVP_MD_type((const EVP_MD *)p2)) { + case NID_id_GostR3411_94: + if (pkey_nid == NID_id_GostR3410_2001 + || pkey_nid == NID_id_GostR3410_94) { + pctx->md = (EVP_MD *)p2; + return 1; + } + break; + + case NID_id_GostR3411_2012_256: + if (pkey_nid == NID_id_GostR3410_2012_256) { + pctx->md = (EVP_MD *)p2; + return 1; + } + break; + + case NID_id_GostR3411_2012_512: + if (pkey_nid == NID_id_GostR3410_2012_512) { + pctx->md = (EVP_MD *)p2; + return 1; + } + break; } - pctx->md = (EVP_MD *)p2; - return 1; + + GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; } case EVP_PKEY_CTRL_GET_MD: @@@ -147,10 -103,11 +144,10 @@@ pctx->sign_param_nid = (int)p1; return 1; case EVP_PKEY_CTRL_SET_IV: + OPENSSL_assert(p2 != NULL); pctx->shared_ukm = OPENSSL_malloc((int)p1); - if (pctx->shared_ukm == NULL) { - GOSTerr(GOST_F_PKEY_GOST_CTRL, ERR_R_MALLOC_FAILURE); + if (!pctx->shared_ukm) return 0; - } memcpy(pctx->shared_ukm, p2, (int)p1); return 1; case EVP_PKEY_CTRL_PEER_KEY: @@@ -160,80 -117,17 +157,19 @@@ return pctx->peer_key_used; if (p1 == 3) /* TLS: peer key used! */ return (pctx->peer_key_used = 1); - return -2; + break; } + + GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_CTRL_CALL_FAILED); return -2; } - static int pkey_gost94_ctrl_str(EVP_PKEY_CTX *ctx, -static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, -- const char *type, const char *value) - { - int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { - if (!value) { - return 0; - } - if (strlen(value) == 1) { - switch (toupper((unsigned char)value[0])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet; - break; - case 'D': - param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet; - break; - default: - return 0; - } - } else if ((strlen(value) == 2) - && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper((unsigned char)value[1])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet; - break; - default: - return 0; - } - } else { - R3410_params *p = R3410_paramset; - param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { - return 0; - } - for (; p->nid != NID_undef; p++) { - if (p->nid == param_nid) - break; - } - if (p->nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST94_CTRL_STR, GOST_R_INVALID_PARAMSET); - return 0; - } - } - - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, NULL); - } - return -2; - } - +static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx, + const char *type, const char *value) { int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { + + if (strcmp(type, param_ctrl_string) == 0) { if (!value) { return 0; } @@@ -267,7 -161,7 +203,7 @@@ return 0; } } else { - R3410_2001_params *p = R3410_2001_paramset; + R3410_ec_params *p = R3410_2001_paramset; param_nid = OBJ_txt2nid(value); if (param_nid == NID_undef) { return 0; @@@ -277,8 -171,7 +213,8 @@@ break; } if (p->nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, GOST_R_INVALID_PARAMSET); + GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_256, + GOST_R_INVALID_PARAMSET); return 0; } } @@@ -289,49 -182,6 +225,49 @@@ return -2; } +static int pkey_gost_ec_ctrl_str_512(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + int param_nid = NID_undef; + + if (strcmp(type, param_ctrl_string)) + return -2; + + if (!value) + return 0; + + if (strlen(value) == 1) { + switch (toupper((unsigned char)value[0])) { + case 'A': + param_nid = NID_id_tc26_gost_3410_2012_512_paramSetA; + break; + + case 'B': + param_nid = NID_id_tc26_gost_3410_2012_512_paramSetB; + break; + + default: + return 0; + } + } else { + R3410_ec_params *p = R3410_2012_512_paramset; + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) + return 0; + + while (p->nid != NID_undef && p->nid != param_nid) + p++; + + if (p->nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST_EC_CTRL_STR_512, + GOST_R_INVALID_PARAMSET); + return 0; + } + } + + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, param_nid, NULL); +} + /* --------------------- key generation --------------------------------*/ static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) @@@ -339,200 -189,95 +275,165 @@@ return 1; } - static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) - { - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - DSA *dsa = NULL; - if (!data || data->sign_param_nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET); - return 0; - } - dsa = DSA_new(); - if (!fill_GOST94_params(dsa, data->sign_param_nid) - || !EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) { - DSA_free(dsa); - return 0; - } - return 1; - } - -static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_KEY *ec = NULL; - if (data->sign_param_nid == NID_undef) { + if (!data || data->sign_param_nid == NID_undef) { GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; } - if (!ec) - ec = EC_KEY_new(); - if (!fill_GOST2001_params(ec, data->sign_param_nid)) { + + ec = EC_KEY_new(); + if (!fill_GOST_EC_params(ec, data->sign_param_nid) + || !EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) { EC_KEY_free(ec); return 0; } - EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec); return 1; } +static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + EC_KEY *ec; + int result = 0; + + if (!data || data->sign_param_nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST12_PARAMGEN, GOST_R_NO_PARAMETERS_SET); + return 0; + } + + ec = EC_KEY_new(); + if (!fill_GOST_EC_params(ec, data->sign_param_nid)) { + EC_KEY_free(ec); + return 0; + } + + switch (data->sign_param_nid) { + case NID_id_tc26_gost_3410_2012_512_paramSetA: + case NID_id_tc26_gost_3410_2012_512_paramSetB: + result = + (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0; + break; + + case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: + case NID_id_GostR3410_2001_CryptoPro_B_ParamSet: + case NID_id_GostR3410_2001_CryptoPro_C_ParamSet: + case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: + case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: + case NID_id_GostR3410_2001_TestParamSet: + result = + (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0; + break; + default: + result = 0; + break; + } + + if (result == 0) + EC_KEY_free(ec); + + return result; +} + +/* ----------- keygen callbacks --------------------------------------*/ - /* Generates Gost_R3410_94_cp key */ - static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) - { - DSA *dsa; - if (!pkey_gost94_paramgen(ctx, pkey)) - return 0; - dsa = EVP_PKEY_get0(pkey); - gost_sign_keygen(dsa); - return 1; - } - /* Generates GOST_R3410 2001 key and assigns it using specified type */ -static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_gost2001cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { EC_KEY *ec; - if (!pkey_gost01_paramgen(ctx, pkey)) + if (!pkey_gost2001_paramgen(ctx, pkey)) return 0; ec = EVP_PKEY_get0(pkey); - gost2001_keygen(ec); + gost_ec_keygen(ec); + return 1; +} + +/* Generates GOST_R3410 2012 key and assigns it using specified type */ +static int pkey_gost2012cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + if (!pkey_gost2012_paramgen(ctx, pkey)) + return 0; + + gost_ec_keygen(EVP_PKEY_get0(pkey)); return 1; } /* ----------- sign callbacks --------------------------------------*/ - - static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbs_len) + /* + * Packs signature according to Cryptopro rules + * and frees up DSA_SIG structure + */ + int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) { - DSA_SIG *unpacked_sig = NULL; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!siglen) - return 0; - if (!sig) { - *siglen = 64; /* better to check size of pkey->pkey.dsa-q */ - return 1; - } - unpacked_sig = gost_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { - return 0; - } - return pack_sign_cp(unpacked_sig, 32, sig, siglen); + *siglen = 2 * order; + memset(sig, 0, *siglen); + store_bignum(s->s, sig, order); + store_bignum(s->r, sig + order, order); + DSA_SIG_free(s); + return 1; } - -static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbs_len) +static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbs_len) { DSA_SIG *unpacked_sig = NULL; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + int order = 0; + if (!siglen) return 0; + if (!pkey) + return 0; + + switch (EVP_PKEY_base_id(pkey)) { + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2012_256: + order = 64; + break; + case NID_id_GostR3410_2012_512: + order = 128; + break; + default: + return 0; + } + if (!sig) { - *siglen = 64; /* better to check size of curve order */ + *siglen = order; return 1; } - unpacked_sig = gost2001_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); + unpacked_sig = gost_ec_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); if (!unpacked_sig) { return 0; } - return pack_sign_cp(unpacked_sig, 32, sig, siglen); + return pack_sign_cp(unpacked_sig, order / 2, sig, siglen); } /* ------------------- verify callbacks ---------------------------*/ - - static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) + /* Unpack signature according to cryptopro rules */ + DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen) { - int ok = 0; - EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL; - if (!s) - return 0; - if (pub_key) - ok = gost_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); - DSA_SIG_free(s); - return ok; + DSA_SIG *s; + + s = DSA_SIG_new(); + if (s == NULL) { + GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE); + return NULL; + } + s->s = BN_bin2bn(sig, siglen / 2, NULL); + s->r = BN_bin2bn(sig + siglen / 2, siglen / 2, NULL); + return s; } - -static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) +static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbs_len) { int ok = 0; EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s = unpack_cp_signature(sig, siglen); + DSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL; if (!s) return 0; #ifdef DEBUG_SIGN @@@ -543,7 -288,7 +444,7 @@@ fprintf(stderr, "\n"); #endif if (pub_key) - ok = gost2001_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); + ok = gost_ec_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); DSA_SIG_free(s); return ok; } @@@ -564,11 -309,11 +465,11 @@@ static int pkey_gost_derive_init(EVP_PK /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) { - struct gost_mac_pmeth_data *data; - data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); + struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data)); + if (!data) return 0; - memset(data, 0, sizeof(struct gost_mac_pmeth_data)); + memset(data, 0, sizeof(*data)); EVP_PKEY_CTX_set_data(ctx, data); return 1; } @@@ -576,8 -321,7 +477,8 @@@ static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - OPENSSL_free(data); + if (data) + OPENSSL_free(data); } static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) @@@ -588,9 -332,6 +489,9 @@@ } src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); + if (!src_data || !dst_data) + return 0; + *dst_data = *src_data; return 1; } @@@ -603,8 -344,7 +504,8 @@@ static int pkey_gost_mac_ctrl(EVP_PKEY_ switch (type) { case EVP_PKEY_CTRL_MD: { - if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) { + int nid = EVP_MD_type((const EVP_MD *)p2); + if (nid != NID_id_Gost28147_89_MAC && nid != NID_gost_mac_12) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); return 0; @@@ -612,7 -352,6 +513,6 @@@ data->md = (EVP_MD *)p2; return 1; } - break; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = data->md; @@@ -660,7 -399,7 +560,7 @@@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { - if (!strcmp(type, key_ctrl_string)) { + if (strcmp(type, key_ctrl_string) == 0) { if (strlen(value) != 32) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_KEY_LENGTH); @@@ -669,8 -408,8 +569,8 @@@ return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, (char *)value); } - if (!strcmp(type, hexkey_ctrl_string)) { - long keylen = 0; + if (strcmp(type, hexkey_ctrl_string) == 0) { + long keylen; int ret; unsigned char *keybuf = string_to_hex(value, &keylen); if (!keybuf || keylen != 32) { @@@ -687,33 -426,22 +587,33 @@@ return -2; } -static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey, int mac_nid) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); unsigned char *keydata; - if (!data->key_set) { + if (!data || !data->key_set) { GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); return 0; } keydata = OPENSSL_malloc(32); - if (!keydata) + if (keydata == NULL) return 0; memcpy(keydata, data->key, 32); - EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); + EVP_PKEY_assign(pkey, mac_nid, keydata); return 1; } +static int pkey_gost_mac_keygen_12(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + return pkey_gost_mac_keygen_base(ctx, pkey, NID_gost_mac_12); +} + +static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC); +} + static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { return 1; @@@ -722,14 -450,9 +622,14 @@@ static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) { - unsigned int tmpsiglen = *siglen; /* for platforms where - * sizeof(int)!=sizeof(size_t) */ + unsigned int tmpsiglen; int ret; + + if (!siglen) + return 0; + tmpsiglen = *siglen; /* for platforms where sizeof(int) != + * sizeof(size_t) */ + if (!sig) { *siglen = 4; return 1; @@@ -747,72 -470,21 +647,58 @@@ int register_pmeth_gost(int id, EVP_PKE return 0; switch (id) { - case NID_id_GostR3410_94: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost94_ctrl_str); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost94cp_keygen); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify); - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, - pkey_GOST94cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); - EVP_PKEY_meth_set_derive(*pmeth, - pkey_gost_derive_init, pkey_gost94_derive); - EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, - pkey_gost94_paramgen); - break; case NID_id_GostR3410_2001: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl01_str); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify); + EVP_PKEY_meth_set_ctrl(*pmeth, + pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2001cp_keygen); EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, - pkey_GOST01cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); + pkey_GOST_ECcp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST_ECcp_decrypt); EVP_PKEY_meth_set_derive(*pmeth, - pkey_gost_derive_init, pkey_gost2001_derive); + pkey_gost_derive_init, pkey_gost_ec_derive); EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, - pkey_gost01_paramgen); + pkey_gost2001_paramgen); + break; + case NID_id_GostR3410_2012_256: + EVP_PKEY_meth_set_ctrl(*pmeth, + pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify); + + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen); + + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, + pkey_GOST_ECcp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST_ECcp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost_ec_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, + pkey_gost_paramgen_init, + pkey_gost2012_paramgen); + break; + case NID_id_GostR3410_2012_512: + EVP_PKEY_meth_set_ctrl(*pmeth, + pkey_gost_ctrl, pkey_gost_ec_ctrl_str_512); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost_ec_cp_verify); + + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost2012cp_keygen); + + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, + pkey_GOST_ECcp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST_ECcp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost_ec_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, + pkey_gost_paramgen_init, + pkey_gost2012_paramgen); break; case NID_id_Gost28147_89_MAC: EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, @@@ -824,16 -496,6 +710,16 @@@ EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); return 1; + case NID_gost_mac_12: + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, + pkey_gost_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init, + pkey_gost_mac_signctx); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen_12); + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init); + EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); + EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); + return 1; default: /* Unsupported method */ return 0; } diff --combined gosthash.c index ee4a57d,b3d80d4..036a2b3 --- a/gosthash.c +++ b/gosthash.c @@@ -154,7 -154,7 +154,7 @@@ static int hash_step(gost_ctx * c, byt int init_gost_hash_ctx(gost_hash_ctx * ctx, const gost_subst_block * subst_block) { - memset(ctx, 0, sizeof(gost_hash_ctx)); + memset(ctx, 0, sizeof(*ctx)); ctx->cipher_ctx = (gost_ctx *) MYALLOC(sizeof(gost_ctx)); if (!ctx->cipher_ctx) { return 0; @@@ -255,8 -255,6 +255,8 @@@ int finish_hash(gost_hash_ctx * ctx, by fin_len += ctx->left; } memset(buf, 0, 32); + if (fin_len == 0) + hash_step(ctx->cipher_ctx, H, buf); bptr = buf; fin_len <<= 3; /* Hash length in BITS!! */ while (fin_len > 0) { diff --combined gosthash2012.c index 6a89237,0000000..f9b8f23 mode 100644,000000..100644 --- a/gosthash2012.c +++ b/gosthash2012.c @@@ -1,232 -1,0 +1,230 @@@ +/* + * GOST R 34.11-2012 core functions. + * + * Copyright (c) 2013 Cryptocom LTD. + * This file is distributed under the same license as OpenSSL. + * + * Author: Alexey Degtyarev + * + */ + +#include "gosthash2012.h" + +#if defined(_WIN32) || defined(_WINDOWS) +# define INLINE __inline +#else +# define INLINE inline +#endif + +#define BSWAP64(x) \ + (((x & 0xFF00000000000000ULL) >> 56) | \ + ((x & 0x00FF000000000000ULL) >> 40) | \ + ((x & 0x0000FF0000000000ULL) >> 24) | \ + ((x & 0x000000FF00000000ULL) >> 8) | \ + ((x & 0x00000000FF000000ULL) << 8) | \ + ((x & 0x0000000000FF0000ULL) << 24) | \ + ((x & 0x000000000000FF00ULL) << 40) | \ + ((x & 0x00000000000000FFULL) << 56)) + +/* + * Initialize gost2012 hash context structure + */ +void init_gost2012_hash_ctx(gost2012_hash_ctx * CTX, + const unsigned int digest_size) +{ - unsigned int i; - + memset(CTX, 0, sizeof(gost2012_hash_ctx)); + + CTX->digest_size = digest_size; + if (digest_size == 256) + memset(&CTX->h, 0x01, sizeof(uint512_u)); + else + memset(&CTX->h, 0x00, sizeof(uint512_u)); +} + +static INLINE void pad(gost2012_hash_ctx * CTX) +{ + unsigned char buf[64]; + + if (CTX->bufsize > 63) + return; + + memset(&buf, 0x00, sizeof buf); + memcpy(&buf, CTX->buffer, CTX->bufsize); + + buf[CTX->bufsize] = 0x01; + memcpy(CTX->buffer, &buf, sizeof buf); +} + +static INLINE void add512(const union uint512_u *x, + const union uint512_u *y, union uint512_u *r) +{ +#ifndef __GOST3411_BIG_ENDIAN__ + unsigned int CF, OF; + unsigned int i; + + CF = 0; + for (i = 0; i < 8; i++) { + r->QWORD[i] = x->QWORD[i] + y->QWORD[i]; + if (r->QWORD[i] < y->QWORD[i] || r->QWORD[i] < x->QWORD[i]) + OF = 1; + else + OF = 0; + + r->QWORD[i] += CF; + CF = OF; + } +#else + const unsigned char *xp, *yp; + unsigned char *rp; + unsigned int i; + int buf; + + xp = (const unsigned char *)&x[0]; + yp = (const unsigned char *)&y[0]; + rp = (unsigned char *)&r[0]; + + buf = 0; + for (i = 0; i < 64; i++) { + buf = xp[i] + yp[i] + (buf >> 8); + rp[i] = (unsigned char)buf & 0xFF; + } +#endif +} + +static void g(union uint512_u *h, const union uint512_u *N, + const unsigned char *m) +{ +#ifdef __GOST3411_HAS_SSE2__ + __m128i xmm0, xmm2, xmm4, xmm6; /* XMMR0-quadruple */ + __m128i xmm1, xmm3, xmm5, xmm7; /* XMMR1-quadruple */ + unsigned int i; + + LOAD(N, xmm0, xmm2, xmm4, xmm6); + XLPS128M(h, xmm0, xmm2, xmm4, xmm6); + + LOAD(m, xmm1, xmm3, xmm5, xmm7); + XLPS128R(xmm0, xmm2, xmm4, xmm6, xmm1, xmm3, xmm5, xmm7); + + for (i = 0; i < 11; i++) + ROUND128(i, xmm0, xmm2, xmm4, xmm6, xmm1, xmm3, xmm5, xmm7); + + XLPS128M((&C[11]), xmm0, xmm2, xmm4, xmm6); + X128R(xmm0, xmm2, xmm4, xmm6, xmm1, xmm3, xmm5, xmm7); + + X128M(h, xmm0, xmm2, xmm4, xmm6); + X128M(m, xmm0, xmm2, xmm4, xmm6); + + UNLOAD(h, xmm0, xmm2, xmm4, xmm6); + + /* Restore the Floating-point status on the CPU */ + _mm_empty(); +#else + union uint512_u Ki, data; + unsigned int i; + + XLPS(h, N, (&data)); + + /* Starting E() */ + Ki = data; + XLPS((&Ki), ((const union uint512_u *)&m[0]), (&data)); + + for (i = 0; i < 11; i++) + ROUND(i, (&Ki), (&data)); + + XLPS((&Ki), (&C[11]), (&Ki)); + X((&Ki), (&data), (&data)); + /* E() done */ + + X((&data), h, (&data)); + X((&data), ((const union uint512_u *)&m[0]), h); +#endif +} + +static INLINE void stage2(gost2012_hash_ctx * CTX, const unsigned char *data) +{ + g(&(CTX->h), &(CTX->N), data); + + add512(&(CTX->N), &buffer512, &(CTX->N)); + add512(&(CTX->Sigma), (const union uint512_u *)data, &(CTX->Sigma)); +} + +static INLINE void stage3(gost2012_hash_ctx * CTX) +{ + ALIGN(16) union uint512_u buf; + + memset(&buf, 0x00, sizeof buf); + memcpy(&buf, &(CTX->buffer), CTX->bufsize); + memcpy(&(CTX->buffer), &buf, sizeof(uint512_u)); + + memset(&buf, 0x00, sizeof buf); +#ifndef __GOST3411_BIG_ENDIAN__ + buf.QWORD[0] = CTX->bufsize << 3; +#else + buf.QWORD[0] = BSWAP64(CTX->bufsize << 3); +#endif + + pad(CTX); + + g(&(CTX->h), &(CTX->N), (const unsigned char *)&(CTX->buffer)); + + add512(&(CTX->N), &buf, &(CTX->N)); + add512(&(CTX->Sigma), (const union uint512_u *)&CTX->buffer[0], + &(CTX->Sigma)); + + g(&(CTX->h), &buffer0, (const unsigned char *)&(CTX->N)); + + g(&(CTX->h), &buffer0, (const unsigned char *)&(CTX->Sigma)); + memcpy(&(CTX->hash), &(CTX->h), sizeof(uint512_u)); +} + +/* + * Hash block of arbitrary length + * + */ +void gost2012_hash_block(gost2012_hash_ctx * CTX, + const unsigned char *data, size_t len) +{ + size_t chunksize; + + while (len > 63 && CTX->bufsize == 0) { + stage2(CTX, data); + + data += 64; + len -= 64; + } + + while (len) { + chunksize = 64 - CTX->bufsize; + if (chunksize > len) + chunksize = len; + + memcpy(&CTX->buffer[CTX->bufsize], data, chunksize); + + CTX->bufsize += chunksize; + len -= chunksize; + data += chunksize; + + if (CTX->bufsize == 64) { + stage2(CTX, CTX->buffer); + + CTX->bufsize = 0; + } + } +} + +/* + * Compute hash value from current state of ctx + * state of hash ctx becomes invalid and cannot be used for further + * hashing. + */ +void gost2012_finish_hash(gost2012_hash_ctx * CTX, unsigned char *digest) +{ + stage3(CTX); + + CTX->bufsize = 0; + + if (CTX->digest_size == 256) + memcpy(digest, &(CTX->hash.QWORD[4]), 32); + else + memcpy(digest, &(CTX->hash.QWORD[0]), 64); +}