diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-09-21 13:04:43 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-09-21 13:04:43 +0000 |
commit | 926c41bd293461df485e1ccde391ef471abf86c1 (patch) | |
tree | 38fb7da2421faf174a9cb9cdd055c8dabfa2739d /engines | |
parent | 1182301ca725de1b01371d0fb9b27ae2414c21c2 (diff) | |
download | openssl-926c41bd293461df485e1ccde391ef471abf86c1.tar.gz |
Updated version of gost engine.
Diffstat (limited to 'engines')
31 files changed, 2680 insertions, 2273 deletions
diff --git a/engines/ccgost/Makefile b/engines/ccgost/Makefile index b4caacdb7e..0c3750bb8c 100644 --- a/engines/ccgost/Makefile +++ b/engines/ccgost/Makefile @@ -1,122 +1,269 @@ -# OPENSSL_DIR is a root directory of openssl sources -THISDIR?=$(shell perl -MCwd -e 'print getcwd') -OPENSSL_DIR?=$(THISDIR)/../openssl -ENGINE_ID?=gost -TESTSUITE_DIR?=$(THISDIR)/test-suite -FOR?=$(HOST) -CC=gcc -CFLAGS=-fPIC -g -Wall -I$(OPENSSL_DIR)/include -LDFLAGS=-g -L $(OPENSSL_DIR) -static-libgcc -ifeq "$(FOR)" "s64" -CFLAGS+=-m64 -LDFLAGS+=-m64 -endif -OS:=$(shell uname -s) -ifeq "$(OS)" "FreeBSD" -LIBDIR:=$(shell LD_LIBRARY_PATH=$(OPENSSL_DIR) $(OPENSSL_DIR)/apps/openssl version -d|sed -e 's/^[^"]*"//' -e 's/".*$$//')/lib -LDFLAGS+=-rpath $(LIBDIR) -endif - - -ifeq "$(FOR)" "w32" -ENGINE_LIB?=$(ENGINE_ID)$(DLLSUFFIX) -DLLSUFFIX=.dll -EXESUFFIX=.exe -CFLAGS+=-mno-cygwin -LDFLAGS+=-mno-cygwin -ifeq "$(OS)" "Linux" -CC=i586-mingw32msvc-gcc -endif -LIBS=-lcrypto.dll -else -ENGINE_LIB?=lib$(ENGINE_ID)$(DLLSUFFIX) -LIBS=-lcrypto -DLLSUFFIX=.so -endif -export DLLSUFFIX -export EXESUFFIX -ifneq "$(FOR)" "" -export FOR -endif -CFLAGS+=$(DEBUG_FLAGS) -export ENGINE_LIB -ENG_SOURCES=md_gost.c gost_crypt.c gost_asn1.c ameth.c pmeth.c\ - gost_crypt.c gost_sign.c gost2001.c md_gost.c gost_crypt.c\ - engine.c gost94_keyx.c keywrap.c gost2001_keyx.c -all: $(ENGINE_LIB) openssl.cnf -buildtests: -$(ENGINE_LIB): e_gost_err.o engine.o ameth.o pmeth.o params.o md_gost.o gosthash.o gost89.o gost_sign.o gost_crypt.o keywrap.o gost2001.o gost94_keyx.o gost2001_keyx.o gost_asn1.o - $(CC) $(LDFLAGS) -shared -o $@ $+ $(LIBS) $(LDFLAGS) -openssl.cnf: openssl.cnf.1 openssl.cnf.2 - cat $+ > $@ -openssl.cnf.1: - echo "openssl_conf = openssl_def" > $@ -openssl.cnf.2: - echo "[openssl_def]" > $@ - echo "engines = engine_section" >> $@ - echo "[engine_section]" >> $@ - echo "$(ENGINE_ID) = $(ENGINE_ID)_section" >> $@ - echo "[$(ENGINE_ID)_section]" >> $@ - echo "dynamic_path = $(THISDIR)/$(ENGINE_LIB)" >> $@ - echo "engine_id = $(ENGINE_ID)" >> $@ - echo "default_algorithms = ALL" >> $@ -gosthash1.o: gosthash.c - $(CC) -c $(CFLAGS) -o $@ -DOPENSSL_BUILD $+ -gostsum: gostsum.o gosthash.o gost89.o -inttests: gosttest$(EXESUFFIX) etalon wraptest$(EXESUFFIX) etalon.wrap ectest$(EXESUFFIX) etalon.ec - ./gosttest${EXESUFFIX} > gost_test - diff -uw gost_test etalon - ./wraptest$(EXESUFFIX) > wrap_test - diff -uw wrap_test etalon.wrap - ./ectest$(EXESUFFIX) > ec_test 2>&1 - diff -uw ec_test etalon.ec -ectest$(EXESUFFIX): ectest.o gost2001_dbg.o gost_sign_dbg.o params.o e_gost_err.o - $(CC) -o $@ $(LDFLAGS) $+ -lcrypto -%_dbg.o: %.c - $(CC) -c $(CFLAGS) -DDEBUG_SIGN -DDEBUG_KEYS -o $@ $+ -gosttest$(EXESUFFIX): gosttest.o gosthash.o gost89.o - $(CC) $(LDFLAGS) -o $@ $+ -wraptest$(EXESUFFIX): wraptest.c keywrap.c gost89.c - $(CC) -DDEBUG_DH $(LDFLAGS) -o $@ $+ -sign_ex: LOADLIBES=-lcrypto -sign_ex: sign_ex.o -clean: - rm -f core gosttest gostsum *.o gost_test openssl.cnf* $(ENGINE_LIB) - if [ -f t/Makefile ]; then $(MAKE) -C t clean; fi - if [ -f $(TESTSUITE_DIR)/Makefile ]; then $(MAKE) -C $(TESTSUITE_DIR) clean; fi -e_gost_err.c e_gost_err.h: $(ENG_SOURCES) gost.ec e_gost_err.proto - perl $(OPENSSL_DIR)/util/mkerr.pl -conf gost.ec -nostatic -debug -write $(ENG_SOURCES) +DIR=ccgost +TOP=../.. +CC=cc +INCLUDES= -I../../include +CFLAG=-g +MAKEFILE= Makefile +AR= ar r +CFLAGS= $(INCLUDES) $(CFLAG) +LIB=$(TOP)/libcrypto.a -tests: openssl.cnf.2 - OPENSSL_DIR=$(OPENSSL_DIR) $(MAKE) -C $(TESTSUITE_DIR) CONFADD=$(THISDIR)/openssl.cnf.2 +LIBSRC= gost2001.c gost2001_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 -# depedencies -# -# -gost_sign.o: gost_sign.c sign.h paramset.h tools.h e_gost_err.h +LIBOBJ= e_gost_err.o gost2001_keyx.o gost2001.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 -pmeth.o: pmeth.c meth.h pmeth.h sign.h paramset.h e_gost_err.h +SRC=$(LIBSRC) -ameth.o: ameth.c tools.h meth.h pmeth.h gost_asn1.h crypt.h e_gost_err.h paramset.h +LIBNAME=gost -keywrap.o: keywrap.c gost89.h keywrap.h +top: + (cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all) -gost2001.o: gost2001.c tools.h sign.h paramset.h e_gost_err.h +all: lib -engine.o: engine.c md.h crypt.h meth.h e_gost_err.h +tags: + ctags $(SRC) -gost89.o: gost89.c gost89.h +errors: + $(PERL) ../../util/mkerr.pl -conf gost.ec -nostatic -debug -write $(SRC) + +lib: $(LIBOBJ) + if [ -n "$(SHARED_LIBS)" ]; then \ + $(MAKE) -f $(TOP)/Makefile.shared -e \ + LIBNAME=$(LIBNAME) \ + LIBEXTRAS='$(LIBOBJ)' \ + LIBDEPS='-L$(TOP) -lcrypto' \ + link_o.$(SHLIB_TARGET); \ + else \ + $(AR) $(LIB) $(LIBOBJ); \ + fi + +install: + [ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + if [ -n "$(SHARED_LIBS)" ]; then \ + set -e; \ + echo installing $(LIBNAME); \ + if [ "$(PLATFORM)" != "Cygwin" ]; then \ + case "$(CFLAGS)" in \ + *DSO_BEOS*) sfx="so";; \ + *DSO_DLFCN*) sfx="so";; \ + *DSO_DL*) sfx="sl";; \ + *) sfx="bad";; \ + esac; \ + cp lib$(LIBNAME).$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$(LIBNAME).$$sfx.new; \ + else \ + sfx="so"; \ + cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$(LIBNAME).$$sfx.new; \ + fi; \ + chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$(LIBNAME).$$sfx.new; \ + mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$(LIBNAME).$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/lib/engines/lib$(LIBNAME).$$sfx; \ + fi + +links: -gost_asn1.o: gost_asn1.c gost_asn1.h +tests: -gost_crypt.o: gost_crypt.c crypt.h gost89.h e_gost_err.h gost_asn1.h +depend: + @if [ -z "$(THIS)" ]; then \ + $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \ + else \ + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \ + fi -gosthash.o: gosthash.c gost89.h gosthash.h +files: -md_gost.o: md_gost.c md.h gosthash.h e_gost_err.h -params.o: params.c paramset.h -gost94_keyx.o: gost94_keyx.c gost_asn1.h gost89.h gosthash.h crypt.h pmeth.h keywrap.h e_gost_err.h gostkeyx.h +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff -gost2001_keyx.o: gost2001_keyx.c gost89.h gost_asn1.h e_gost_err.h keywrap.h crypt.h sign.h gostkeyx.h pmeth.h gosthash.h tools.h +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +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 gost_params.h +gost2001.o: 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: 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/crypto.h +gost_ameth.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_ameth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_ameth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_ameth.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +gost_ameth.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +gost_ameth.o: ../../include/openssl/opensslconf.h +gost_ameth.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +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/x509_vfy.h e_gost_err.h gost89.h +gost_ameth.o: gost_ameth.c gost_lcl.h gost_params.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 +gost_asn1.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_asn1.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_asn1.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +gost_asn1.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +gost_asn1.o: ../../include/openssl/opensslconf.h +gost_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +gost_asn1.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +gost_asn1.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +gost_asn1.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +gost_asn1.o: ../../include/openssl/x509_vfy.h gost89.h gost_asn1.c gost_lcl.h +gost_asn1.o: gosthash.h +gost_crypt.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +gost_crypt.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +gost_crypt.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +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/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 +gost_crypt.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +gost_crypt.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +gost_crypt.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +gost_crypt.o: e_gost_err.h gost89.h gost_crypt.c gost_lcl.h gosthash.h +gost_ctl.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +gost_ctl.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +gost_ctl.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +gost_ctl.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_ctl.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_ctl.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_ctl.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +gost_ctl.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +gost_ctl.o: ../../include/openssl/opensslconf.h +gost_ctl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +gost_ctl.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +gost_ctl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +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_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 +gost_eng.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_eng.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +gost_eng.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +gost_eng.o: ../../include/openssl/opensslconf.h +gost_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +gost_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +gost_eng.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +gost_eng.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +gost_eng.o: ../../include/openssl/x509_vfy.h e_gost_err.h gost89.h gost_eng.c +gost_eng.o: gost_lcl.h gosthash.h +gost_keywrap.o: gost89.h gost_keywrap.c gost_keywrap.h +gost_md.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +gost_md.o: ../../include/openssl/bio.h ../../include/openssl/bn.h +gost_md.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +gost_md.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_md.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_md.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +gost_md.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h +gost_md.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +gost_md.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +gost_md.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +gost_md.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +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_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_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/crypto.h +gost_pmeth.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h +gost_pmeth.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +gost_pmeth.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.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 e_gost_err.h gost89.h gost_lcl.h +gost_pmeth.o: gost_params.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/evp.h ../../include/openssl/lhash.h +gost_sign.o: ../../include/openssl/obj_mac.h ../../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 +gosthash.o: gost89.h gosthash.c gosthash.h diff --git a/engines/ccgost/crypt.h b/engines/ccgost/crypt.h deleted file mode 100644 index bdd3dc08a8..0000000000 --- a/engines/ccgost/crypt.h +++ /dev/null @@ -1,62 +0,0 @@ -/********************************************************************** - * gost_crypt.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declarations for GOST 28147-89 encryption algorithm * - * OpenSSL 0.9.9 libraries required * - **********************************************************************/ -#ifndef GOST_CRYPT_H -#define GOST_CRYPT_H -#include <unistd.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include "gost89.h" -#ifdef __cplusplus - extern "C" { -#endif -/* Cipher context used for EVP_CIPHER operation */ -struct ossl_gost_cipher_ctx { - int paramNID; - off_t count; - int key_meshing; - gost_ctx cctx; -}; -/* Structure to map parameter NID to S-block */ -struct gost_cipher_info { - int nid; - gost_subst_block *sblock; - int key_meshing; -}; -#ifdef USE_SSL -/* Context for MAC */ -struct ossl_gost_imit_ctx { - gost_ctx cctx; - unsigned char buffer[8]; - unsigned char partial_block[8]; - off_t count; - int key_meshing; - int bytes_left; - int key_set; -}; -#endif -/* Table which maps parameter NID to S-blocks */ -extern struct gost_cipher_info gost_cipher_list[]; -/* Find encryption params from ASN1_OBJECT */ -const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); -/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ -extern EVP_CIPHER cipher_gost; -#ifdef USE_SSL -#define EVP_MD_FLAG_NEEDS_KEY 0x20 -#define EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH (EVP_MD_CTRL_ALG_CTRL+1) -#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+2) -/* Ciphers and MACs specific for GOST TLS draft */ -extern EVP_CIPHER cipher_gost_vizircfb; -extern EVP_CIPHER cipher_gost_cpacnt; -extern EVP_MD imit_gost_vizir; -extern EVP_MD imit_gost_cpa; -#endif -#ifdef __cplusplus - }; -#endif -#endif diff --git a/engines/ccgost/e_gost_err.c b/engines/ccgost/e_gost_err.c index 5ba09e885a..3dad4f4fc3 100644 --- a/engines/ccgost/e_gost_err.c +++ b/engines/ccgost/e_gost_err.c @@ -70,95 +70,95 @@ static ERR_STRING_DATA GOST_str_functs[]= { -{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, -{ERR_FUNC(GOST_F_DECRYPT_CRYPTOCOM_KEY), "decrypt_cryptocom_key"}, -{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_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_GET_ENCRYPTION_PARAMS), "get_encryption_params"}, -{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_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_COPY_PARAMETERS), "GOST94_COPY_PARAMETERS"}, -{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "gost_cipher_ctl"}, -{ERR_FUNC(GOST_F_GOST_COMPUTE_PUBLIC), "GOST_COMPUTE_PUBLIC"}, -{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, -{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, -{ERR_FUNC(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001), "MAKE_RFC4490_KEYTRANSPORT_2001"}, -{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, -{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, -{ERR_FUNC(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT"}, -{ERR_FUNC(GOST_F_PKCS7_GOST94_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94_KEY_TRANSPORT_DECRYPT"}, -{ERR_FUNC(GOST_F_PKEY_GOST01CC_DECRYPT), "pkey_GOST01cc_decrypt"}, -{ERR_FUNC(GOST_F_PKEY_GOST01CC_ENCRYPT), "pkey_GOST01cc_encrypt"}, -{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "pkey_GOST01cp_encrypt"}, -{ERR_FUNC(GOST_F_PKEY_GOST01_KEYGEN), "PKEY_GOST01_KEYGEN"}, -{ERR_FUNC(GOST_F_PKEY_GOST94CC_DECRYPT), "pkey_GOST94cc_decrypt"}, -{ERR_FUNC(GOST_F_PKEY_GOST94CC_ENCRYPT), "pkey_GOST94cc_encrypt"}, -{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_KEYGEN), "PKEY_GOST94_KEYGEN"}, -{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, -{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, -{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, -{ERR_FUNC(GOST_F_PRIV_DECODE_GOST_94), "PRIV_DECODE_GOST_94"}, -{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_GOST01), "PUB_ENCODE_GOST01"}, -{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, -{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, -{0,NULL} + {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, + {ERR_FUNC(GOST_F_DECRYPT_CRYPTOCOM_KEY), "decrypt_cryptocom_key"}, + {ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_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_GET_ENCRYPTION_PARAMS), "get_encryption_params"}, + {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_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_COPY_PARAMETERS), "GOST94_COPY_PARAMETERS"}, + {ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "gost_cipher_ctl"}, + {ERR_FUNC(GOST_F_GOST_COMPUTE_PUBLIC), "GOST_COMPUTE_PUBLIC"}, + {ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, + {ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, + {ERR_FUNC(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001), "MAKE_RFC4490_KEYTRANSPORT_2001"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, + {ERR_FUNC(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT"}, + {ERR_FUNC(GOST_F_PKCS7_GOST94_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94_KEY_TRANSPORT_DECRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CC_DECRYPT), "pkey_GOST01cc_decrypt"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CC_ENCRYPT), "pkey_GOST01cc_encrypt"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "pkey_GOST01cp_encrypt"}, + {ERR_FUNC(GOST_F_PKEY_GOST01_KEYGEN), "PKEY_GOST01_KEYGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST94CC_DECRYPT), "pkey_GOST94cc_decrypt"}, + {ERR_FUNC(GOST_F_PKEY_GOST94CC_ENCRYPT), "pkey_GOST94cc_encrypt"}, + {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_KEYGEN), "PKEY_GOST94_KEYGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, + {ERR_FUNC(GOST_F_PRIV_DECODE_GOST_94), "PRIV_DECODE_GOST_94"}, + {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_GOST01), "PUB_ENCODE_GOST01"}, + {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, + {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, + {0,NULL} }; static ERR_STRING_DATA GOST_str_reasons[]= { -{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, -{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, -{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, -{ERR_REASON(GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT),"ctx not initialized for encrypt"}, -{ERR_REASON(GOST_R_ERROR_COMPUTING_MAC) ,"error computing mac"}, -{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_ERROR_STORING_ENCRYPTED_KEY),"error storing encrypted key"}, -{ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"}, -{ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"}, -{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, -{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_ENCRYPTED_KEY_SIZE),"invalid encrypted key size"}, -{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_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_MALLOC_FAILURE) ,"malloc failure"}, -{ERR_REASON(GOST_R_NOT_ENOUGH_SPACE_FOR_KEY),"not enough space for key"}, -{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"}, -{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, -{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, -{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"}, -{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"}, -{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, -{ERR_REASON(GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH),"session key mac does not match"}, -{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, -{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, -{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"}, -{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"}, -{0,NULL} + {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, + {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, + {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, + {ERR_REASON(GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT),"ctx not initialized for encrypt"}, + {ERR_REASON(GOST_R_ERROR_COMPUTING_MAC) ,"error computing mac"}, + {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_ERROR_STORING_ENCRYPTED_KEY),"error storing encrypted key"}, + {ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"}, + {ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"}, + {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, + {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_ENCRYPTED_KEY_SIZE),"invalid encrypted key size"}, + {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_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_MALLOC_FAILURE) ,"malloc failure"}, + {ERR_REASON(GOST_R_NOT_ENOUGH_SPACE_FOR_KEY),"not enough space for key"}, + {ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"}, + {ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, + {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, + {ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"}, + {ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"}, + {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, + {ERR_REASON(GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH),"session key mac does not match"}, + {ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, + {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, + {ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"}, + {ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"}, + {0,NULL} }; #endif #ifdef GOST_LIB_NAME static ERR_STRING_DATA GOST_lib_name[]= - { -{0 ,GOST_LIB_NAME}, -{0,NULL} + { + {0 ,GOST_LIB_NAME}, + {0,NULL} }; #endif diff --git a/engines/ccgost/gost2001.c b/engines/ccgost/gost2001.c index c53bd6c7c5..e0d685f754 100644 --- a/engines/ccgost/gost2001.c +++ b/engines/ccgost/gost2001.c @@ -6,9 +6,8 @@ * Implementation of GOST R 34.10-2001 * * Requires OpenSSL 0.9.9 for compilation * **********************************************************************/ -#include "tools.h" -#include "sign.h" -#include "paramset.h" +#include "gost_lcl.h" +#include "gost_params.h" #include <string.h> #include <openssl/rand.h> #include <openssl/ecdsa.h> @@ -32,9 +31,10 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig); * Also fils DSA->q field with copy of EC_GROUP order field to make * DSA_size function work */ -int fill_GOST2001_params(EC_KEY *eckey, int nid) { +int fill_GOST2001_params(EC_KEY *eckey, int nid) + { R3410_2001_params *params = R3410_2001_paramset; - EC_GROUP *grp; + EC_GROUP *grp=NULL; BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL; EC_POINT *P=NULL; BN_CTX *ctx=BN_CTX_new(); @@ -48,10 +48,11 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid) { y=BN_CTX_get(ctx); q=BN_CTX_get(ctx); while (params->nid!=NID_undef && params->nid != nid) params++; - if (params->nid == NID_undef) { + if (params->nid == NID_undef) + { GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET); goto err; - } + } BN_hex2bn(&p,params->p); BN_hex2bn(&a,params->a); BN_hex2bn(&b,params->b); @@ -66,7 +67,7 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid) { BN_hex2bn(&q,params->q); #ifdef DEBUG_KEYS fprintf(stderr,"Set params index %d oid %s\nq=", - (params-R3410_2001_paramset),OBJ_nid2sn(params->nid)); + (params-R3410_2001_paramset),OBJ_nid2sn(params->nid)); BN_print_fp(stderr,q); fprintf(stderr,"\n"); #endif @@ -76,14 +77,13 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid) { EC_KEY_set_group(eckey,grp); ok=1; -err: + err: EC_POINT_free(P); EC_GROUP_free(grp); BN_CTX_end(ctx); BN_CTX_free(ctx); return ok; - -} + } /* @@ -91,88 +91,96 @@ err: * * */ -DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) { - DSA_SIG *newsig = NULL; - BIGNUM *md = hashsum2bn(dgst); - 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 = BN_CTX_new(); - BN_CTX_start(ctx); - OPENSSL_assert(dlen==32); - newsig=DSA_SIG_new(); - if (!newsig) +DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) + { + DSA_SIG *newsig = NULL; + BIGNUM *md = hashsum2bn(dgst); + 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 = BN_CTX_new(); + BN_CTX_start(ctx); + OPENSSL_assert(dlen==32); + newsig=DSA_SIG_new(); + if (!newsig) { - GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY); - goto err; + GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY); + goto err; } - group = EC_KEY_get0_group(eckey); - order=BN_CTX_get(ctx); - EC_GROUP_get_order(group,order,ctx); - priv_key = EC_KEY_get0_private_key(eckey); - e = BN_CTX_get(ctx); - BN_mod(e,md,order,ctx); + group = EC_KEY_get0_group(eckey); + order=BN_CTX_get(ctx); + EC_GROUP_get_order(group,order,ctx); + priv_key = EC_KEY_get0_private_key(eckey); + e = BN_CTX_get(ctx); + BN_mod(e,md,order,ctx); #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"); + 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)) + if (BN_is_zero(e)) { - BN_one(e); + BN_one(e); } - k =BN_CTX_get(ctx); - C=EC_POINT_new(group); - do { - do { - if (!BN_rand_range(k,order)) + k =BN_CTX_get(ctx); + C=EC_POINT_new(group); + do + { + do + { + if (!BN_rand_range(k,order)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); - DSA_SIG_free(newsig); - goto err; + GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + DSA_SIG_free(newsig); + goto err; } - if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); - DSA_SIG_free(newsig); - goto err; + if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); + DSA_SIG_free(newsig); + goto err; } - if (!X) X=BN_CTX_get(ctx); - if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); - DSA_SIG_free(newsig); - goto err; + if (!X) X=BN_CTX_get(ctx); + if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) + { + GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB); + DSA_SIG_free(newsig); + goto err; } - if (!r) r=BN_CTX_get(ctx); - BN_nnmod(r,X,order,ctx); - } while (BN_is_zero(r)); - /* s = (r*priv_key+k*e) mod order */ - if (!tmp) tmp = BN_CTX_get(ctx); - BN_mod_mul(tmp,priv_key,r,order,ctx); - if (!tmp2) tmp2 = BN_CTX_get(ctx); - BN_mod_mul(tmp2,k,e,order,ctx); - if (!s) s=BN_CTX_get(ctx); - BN_mod_add(s,tmp,tmp2,order,ctx); - } while (BN_is_zero(s)); + if (!r) r=BN_CTX_get(ctx); + BN_nnmod(r,X,order,ctx); + } + while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (!tmp) tmp = BN_CTX_get(ctx); + BN_mod_mul(tmp,priv_key,r,order,ctx); + if (!tmp2) tmp2 = BN_CTX_get(ctx); + BN_mod_mul(tmp2,k,e,order,ctx); + if (!s) s=BN_CTX_get(ctx); + BN_mod_add(s,tmp,tmp2,order,ctx); + } + while (BN_is_zero(s)); - newsig->s=BN_dup(s); - newsig->r=BN_dup(r); -err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - EC_POINT_free(C); - BN_free(md); - return newsig; -} + newsig->s=BN_dup(s); + newsig->r=BN_dup(r); + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(C); + BN_free(md); + return newsig; + } /* * Verifies gost 2001 signature * */ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, - DSA_SIG *sig, EC_KEY *ec) { + DSA_SIG *sig, EC_KEY *ec) + { BN_CTX *ctx=BN_CTX_new(); const EC_GROUP *group = EC_KEY_get0_group(ec); BIGNUM *order; @@ -196,11 +204,11 @@ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, pub_key = EC_KEY_get0_public_key(ec); 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_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); - goto err; + { + GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; - } + } md = hashsum2bn(dgst); BN_mod(e,md,order,ctx); @@ -225,15 +233,15 @@ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, #endif C = EC_POINT_new(group); if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx)) - { + { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; - } + } if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) - { + { GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB); goto err; - } + } BN_mod(R,X,order,ctx); #ifdef DEBUG_SIGN fprintf(stderr,"\nX="); @@ -242,83 +250,91 @@ int gost2001_do_verify(const unsigned char *dgst,int dgst_len, BN_print_fp(stderr,R); fprintf(stderr,"\n"); #endif - if (BN_cmp(R,sig->r)!=0) { + if (BN_cmp(R,sig->r)!=0) + { GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); - } else { + } + else + { ok = 1; - } -err: + } + err: EC_POINT_free(C); BN_CTX_end(ctx); BN_CTX_free(ctx); BN_free(md); return ok; -} + } /* * Computes GOST R 34.10-2001 public key * * */ int gost2001_compute_public(EC_KEY *ec) -{ + { const EC_GROUP *group = EC_KEY_get0_group(ec); EC_POINT *pub_key=NULL; const BIGNUM *priv_key=NULL; BN_CTX *ctx=NULL; int ok=0; - if (!group) { + if (!group) + { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED); return 0; - } + } ctx=BN_CTX_new(); BN_CTX_start(ctx); if (!(priv_key=EC_KEY_get0_private_key(ec))) - { + { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); goto err; - } + } pub_key = EC_POINT_new(group); if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx)) - { + { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); goto err; - } - if (!EC_KEY_set_public_key(ec,pub_key)) { + } + if (!EC_KEY_set_public_key(ec,pub_key)) + { GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB); goto err; - } + } ok = 256; -err: + err: BN_CTX_end(ctx); EC_POINT_free(pub_key); BN_CTX_free(ctx); return ok; -} + } /* * * Generates GOST R 34.10-2001 keypair * * */ -int gost2001_keygen(EC_KEY *ec) { +int gost2001_keygen(EC_KEY *ec) + { BIGNUM *order = BN_new(),*d=BN_new(); const EC_GROUP *group = EC_KEY_get0_group(ec); EC_GROUP_get_order(group,order,NULL); - do { - if (!BN_rand_range(d,order)) + do { + if (!BN_rand_range(d,order)) + { GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); BN_free(d); BN_free(order); return 0; - } - } while (BN_is_zero(d)); + } + } + while (BN_is_zero(d)); EC_KEY_set_private_key(ec,d); BN_free(d); BN_free(order); return gost2001_compute_public(ec); -} + } diff --git a/engines/ccgost/gost2001_keyx.c b/engines/ccgost/gost2001_keyx.c index 120ec69d3c..7b81c23f92 100644 --- a/engines/ccgost/gost2001_keyx.c +++ b/engines/ccgost/gost2001_keyx.c @@ -13,49 +13,48 @@ #include <openssl/objects.h> #include "gost89.h" #include "gosthash.h" -#include "gost_asn1.h" #include "e_gost_err.h" -#include "keywrap.h" -#include "crypt.h" -#include "sign.h" -#include "pmeth.h" -#include "tools.h" -#include "gostkeyx.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" /* Transform ECDH shared key into little endian as required by Cryptocom * key exchange */ -static void *make_key_le(const void *in, size_t inlen, void *out, size_t *outlen) { +static void *make_key_le(const void *in, size_t inlen, void *out, size_t *outlen) + { const char* inbuf= in; char* outbuf= out; int i; - if (*outlen < inlen) { - return NULL; - } - for (i=0;i<inlen;i++) { + if (*outlen < inlen) + { + return NULL; + } + for (i=0;i<inlen;i++) + { outbuf[inlen-1-i]=inbuf[i]; - } + } *outlen = inlen; return out; -} + } /* Create gost 2001 ephemeral key with same parameters as peer key */ -static EC_KEY *make_ec_ephemeral_key(EC_KEY *peer_key,BIGNUM *seckey) { +static EC_KEY *make_ec_ephemeral_key(EC_KEY *peer_key,BIGNUM *seckey) + { EC_KEY *out = EC_KEY_new(); EC_KEY_copy(out,peer_key); EC_KEY_set_private_key(out,seckey); gost2001_compute_public(out); return out; -} + } /* Packs GOST elliptic curve key into EVP_PKEY setting same parameters * as in passed pubkey */ static EVP_PKEY *ec_ephemeral_key_to_EVP(EVP_PKEY *pubk,int type,EC_KEY *ephemeral) -{ + { EVP_PKEY *newkey; newkey = EVP_PKEY_new(); EVP_PKEY_assign(newkey,type,ephemeral); return newkey; -} + } /* * EVP_PKEY_METHOD callback encrypt @@ -64,7 +63,7 @@ static EVP_PKEY *ec_ephemeral_key_to_EVP(EVP_PKEY *pubk,int type,EC_KEY *ephemer int pkey_GOST01cc_encrypt (EVP_PKEY_CTX *pctx,unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len) -{ + { EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); GOST_KEY_TRANSPORT *gkt = NULL; @@ -73,66 +72,68 @@ int pkey_GOST01cc_encrypt (EVP_PKEY_CTX *pctx,unsigned char *out, EC_KEY *ephemeral=NULL; const EC_POINT *pub_key_point=NULL; unsigned char shared_key[32],encrypted_key[32],hmac[4], - iv[8]={0,0,0,0,0,0,0,0}; + iv[8]={0,0,0,0,0,0,0,0}; ephemeral = make_ec_ephemeral_key(EVP_PKEY_get0(pubk), gost_get_priv_key(data->eph_seckey)); if (!ephemeral) goto err; /* compute shared key */ pub_key_point=EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)); if (!ECDH_compute_key(shared_key,32,pub_key_point,ephemeral,make_key_le)) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; - } + } /* encrypt session key */ gost_init(&ctx, &GostR3411_94_CryptoProParamSet); gost_key(&ctx,shared_key); encrypt_cryptocom_key(key,key_len,encrypted_key,&ctx); /* compute hmac of session key */ if (!gost_mac(&ctx,32,key,32,hmac)) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_ERROR_COMPUTING_MAC); return -1; - } + } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_NO_MEMORY); return -1; - } + } /* Store IV which is always zero in our case */ if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,iv,8)) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_ERROR_STORING_IV); goto err; - } + } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,hmac,4)) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_ERROR_STORING_MAC); goto err; - } + } if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,encrypted_key,32)) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_ERROR_STORING_ENCRYPTED_KEY); goto err; - } + } - if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) { + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) + { GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; - } + } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc); if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret = 1; ; -err: + err: if (gkt) GOST_KEY_TRANSPORT_free(gkt); return ret; -} + } /* * EVP_PKEY_METHOD callback decrypt * Implementation of GOST2001 key transport, cryptocom variation */ -int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, const unsigned char *in, size_t in_len) { +int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, const unsigned char *in, size_t in_len) + { /* Form DH params from compute shared key */ EVP_PKEY *priv=EVP_PKEY_CTX_get0_pkey(pctx); GOST_KEY_TRANSPORT *gkt = NULL; @@ -145,17 +146,19 @@ int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l const EC_POINT *pub_key_point; EVP_PKEY *eph_key; - if (!key) { + if (!key) + { *key_len = 32; return 1; - } + } /* Parse passed octet string and find out public key, iv and HMAC*/ gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, - in_len); - if (!gkt) { + in_len); + if (!gkt) + { GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); return 0; - } + } eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); /* Initialization vector is really ignored here */ OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8); @@ -168,37 +171,40 @@ int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l i=ECDH_compute_key(shared_key,32,pub_key_point,EVP_PKEY_get0(priv),make_key_le); EVP_PKEY_free(eph_key); if (!i) - { + { GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_COMPUTING_SHARED_KEY); GOST_KEY_TRANSPORT_free(gkt); return 0; - } + } /* Decrypt session key */ gost_init(&ctx, &GostR3411_94_CryptoProParamSet); gost_key(&ctx,shared_key); if (!decrypt_cryptocom_key(key,*key_len,gkt->key_info->encrypted_key->data, gkt->key_info->encrypted_key->length, &ctx)) - { + { GOST_KEY_TRANSPORT_free(gkt); return 0; - } + } GOST_KEY_TRANSPORT_free(gkt); /* check HMAC of session key*/ - if (!gost_mac(&ctx,32,key,32,hmac_comp)) { + if (!gost_mac(&ctx,32,key,32,hmac_comp)) + { GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_COMPUTING_MAC); return 0; - } - /* HMAC of session key is not correct */ - if (memcmp(hmac,hmac_comp,4)!=0) { + } + /* HMAC of session key is not correct */ + if (memcmp(hmac,hmac_comp,4)!=0) + { GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH); return 0; - } + } return 1; -} + } /* Implementation of CryptoPro VKO 34.10-2001 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) { +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) + { unsigned char ukm_be[8],databuf[64],hashbuf[64]; BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL; const BIGNUM* key=EC_KEY_get0_private_key(priv_key); @@ -207,9 +213,10 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons gost_hash_ctx hash_ctx; BN_CTX *ctx = BN_CTX_new(); - for (i=0;i<8;i++) { + for (i=0;i<8;i++) + { ukm_be[7-i]=ukm[i]; - } + } BN_CTX_start(ctx); UKM=getbnfrombuf(ukm_be,8); p=BN_CTX_get(ctx); @@ -220,15 +227,16 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons 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); + pnt,X,Y,ctx); /*Serialize elliptic curve point same way as we do it when saving * key */ store_bignum(Y,databuf,32); store_bignum(X,databuf+32,32); /* And reverse byte order of whole buffer */ - for (i=0;i<64;i++) { + for (i=0;i<64;i++) + { hashbuf[63-i]=databuf[i]; - } + } init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet); start_hash(&hash_ctx); hash_block(&hash_ctx,hashbuf,64); @@ -239,7 +247,7 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons BN_CTX_free(ctx); EC_POINT_free(pnt); return 32; -} + } /* Generates ephemeral key based on pubk algorithm * computes shared key using VKO and returns filled up @@ -247,9 +255,9 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons */ /* Public, because it would be needed in SSL implementation */ GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_key, - const unsigned char *key,size_t keylen, unsigned char *ukm, - size_t ukm_len) -{ + const unsigned char *key,size_t keylen, unsigned char *ukm, + size_t ukm_len) + { const struct gost_cipher_info *param=get_encryption_params(NULL); EC_KEY *ephemeral = NULL; @@ -260,43 +268,49 @@ GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_ke EVP_PKEY *newkey=NULL; /* Do not use vizir cipher parameters with cryptopro */ - if (!getenv("CRYPT_PARAMS") && param == gost_cipher_list) { + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list) + { param= gost_cipher_list+1; - } + } ephemeral = make_ec_ephemeral_key(EVP_PKEY_get0(pubk),eph_key); VKO_compute_key(shared_key,32,pub_key_point,ephemeral,ukm); gost_init(&ctx,param->sblock); keyWrapCryptoPro(&ctx,shared_key,ukm,key,crypted_key); gkt = GOST_KEY_TRANSPORT_new(); - if (!gkt) { + if (!gkt) + { goto memerr; - } + } if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, - ukm,8)) { + ukm,8)) + { goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) { + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) + { goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) { + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) + { goto memerr; - } + } newkey = ec_ephemeral_key_to_EVP(pubk,NID_id_GostR3410_2001,ephemeral); - if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,newkey)) { + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,newkey)) + { GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001,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); EVP_PKEY_free(newkey); return gkt; -memerr: - GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001, - GOST_R_MALLOC_FAILURE); -err: - GOST_KEY_TRANSPORT_free(gkt); - return NULL; -} + memerr: + GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001, + GOST_R_MALLOC_FAILURE); + err: + GOST_KEY_TRANSPORT_free(gkt); + return NULL; + } /* * EVP_PKEY_METHOD callback encrypt @@ -304,32 +318,34 @@ err: */ int pkey_GOST01cp_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); unsigned char ukm[8]; int ret=0; - if (RAND_bytes(ukm,8)<=0) { + if (RAND_bytes(ukm,8)<=0) + { GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_RANDOM_GENERATOR_FAILURE); return 0; - } + } - if (!(gkt=make_rfc4490_keytransport_2001(pubk,gost_get_priv_key(data->eph_seckey),key, key_len,ukm,8))) { + if (!(gkt=make_rfc4490_keytransport_2001(pubk,gost_get_priv_key(data->eph_seckey),key, key_len,ukm,8))) + { goto err; - } + } if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret =1; GOST_KEY_TRANSPORT_free(gkt); return ret; -err: - GOST_KEY_TRANSPORT_free(gkt); - return -1; -} + err: + GOST_KEY_TRANSPORT_free(gkt); + return -1; + } /* Public, because it would be needed in SSL implementation */ int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,GOST_KEY_TRANSPORT *gkt, - unsigned char *key_buf,int key_buf_len) -{ + unsigned char *key_buf,int key_buf_len) + { unsigned char wrappedKey[44]; unsigned char sharedKey[32]; gost_ctx ctx; @@ -346,40 +362,44 @@ int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,GOST_KEY_TRANSPORT *gkt, OPENSSL_assert(gkt->key_info->imit->length==4); memcpy(wrappedKey+40,gkt->key_info->imit->data,4); VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(eph_key)), - EVP_PKEY_get0(priv),wrappedKey); - if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key_buf)) { + EVP_PKEY_get0(priv),wrappedKey); + if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key_buf)) + { GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT, - GOST_R_ERROR_COMPUTING_SHARED_KEY); + GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; - } + } EVP_PKEY_free(eph_key); return 32; -err: + err: EVP_PKEY_free(eph_key); return -1; -} + } /* * EVP_PKEY_METHOD callback decrypt * Implementation of GOST2001 key transport, cryptopo variation */ -int pkey_GOST01cp_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len) { +int pkey_GOST01cp_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; - if (!key) { + if (!key) + { *key_len = 32; return 1; - } + } gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, - in_len); - if (!gkt) { + in_len); + if (!gkt) + { GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); return -1; - } + } ret = decrypt_rfc4490_shared_key_2001(priv,gkt,key,*key_len); GOST_KEY_TRANSPORT_free(gkt); return ret; -} + } diff --git a/engines/ccgost/gost89.c b/engines/ccgost/gost89.c index 03675724cc..7439c3e34a 100644 --- a/engines/ccgost/gost89.c +++ b/engines/ccgost/gost89.c @@ -20,30 +20,30 @@ /* Substitution blocks from test examples for GOST R 34.11-94*/ gost_subst_block GostR3411_94_TestParamSet = { - {0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC}, - {0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC}, - {0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE}, - {0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2}, - {0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3}, - {0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB}, - {0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9}, - {0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3} -}; + {0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC}, + {0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC}, + {0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE}, + {0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2}, + {0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3}, + {0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB}, + {0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9}, + {0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3} + }; /* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ gost_subst_block GostR3411_94_CryptoProParamSet= { - {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, - {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, - {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, - {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, - {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, - {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, - {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, - {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} -} ; + {0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC}, + {0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB}, + {0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3}, + {0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5}, + {0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3}, + {0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD}, + {0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8}, + {0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF} + } ; /* Test paramset from GOST 28147 */ gost_subst_block Gost28147_TestParamSet = -{ + { {0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8}, {0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD}, {0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4}, @@ -52,7 +52,7 @@ gost_subst_block Gost28147_TestParamSet = {0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB}, {0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5}, {0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6} -}; + }; @@ -67,10 +67,10 @@ gost_subst_block Gost28147_CryptoProParamSetA= { {0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9}, {0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1}, {0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5} -}; + }; /* 1.2.643.2.2.31.2 */ gost_subst_block Gost28147_CryptoProParamSetB= -{ + { {0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC}, {0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE}, {0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5}, @@ -79,10 +79,10 @@ gost_subst_block Gost28147_CryptoProParamSetB= {0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4}, {0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE}, {0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF} -}; + }; /* 1.2.643.2.2.31.3 */ gost_subst_block Gost28147_CryptoProParamSetC= -{ + { {0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8}, {0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7}, {0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD}, @@ -91,11 +91,11 @@ gost_subst_block Gost28147_CryptoProParamSetC= {0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB}, {0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3}, {0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3} -}; + }; /* 1.2.643.2.2.31.4 */ gost_subst_block Gost28147_CryptoProParamSetD= -{ + { {0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE}, {0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7}, {0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6}, @@ -104,7 +104,7 @@ gost_subst_block Gost28147_CryptoProParamSetD= {0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2}, {0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1}, {0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3} -}; + }; const byte CryptoProKeyMeshingKey[]={ @@ -112,62 +112,64 @@ const byte CryptoProKeyMeshingKey[]={ 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B -}; + }; /* Initialization of gost_ctx subst blocks*/ -void kboxinit(gost_ctx *c, const gost_subst_block *b) { +void kboxinit(gost_ctx *c, const gost_subst_block *b) + { int i; - for (i = 0; i < 256; i++) { + for (i = 0; i < 256; i++) + { c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24; c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16; c->k43[i] = (b->k4[i>>4] <<4 | b->k3 [i &15])<<8; c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15]; + } } -} /* Part of GOST 28147 algorithm moved into separate function */ -static word32 -f(gost_ctx *c,word32 x) -{ x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| - c->k43[x>> 8 & 255] | c->k21[x & 255]; - /* Rotate left 11 bits */ - return x<<11 | x>>(32-11); -} +static word32 f(gost_ctx *c,word32 x) + { + x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]| + c->k43[x>> 8 & 255] | c->k21[x & 255]; + /* Rotate left 11 bits */ + return x<<11 | x>>(32-11); + } /* Low-level encryption routine - encrypts one 64 bit block*/ void gostcrypt(gost_ctx *c, const byte *in, byte *out) -{ - register word32 n1, n2; /* As named in the GOST */ - n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); - n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); - /* Instead of swapping halves, swap names each round */ + { + register word32 n1, n2; /* As named in the GOST */ + n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); + n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); + /* Instead of swapping halves, swap names each round */ - n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); - n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); - n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); - n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); - n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); - n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); - n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); - n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); - n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); - n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); - n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); - n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); - n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); - n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); - n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); - n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); + n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]); + n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]); + n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]); + n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); - out[0] = (n2&0xff); out[1] = (n2>>8)&0xff; out[2]=(n2>>16)&0xff; out[3]=n2>>24; - out[4] = (n1&0xff); out[5] = (n1>>8)&0xff; out[6]=(n1>>16)&0xff; out[7]=n1>>24; -} + out[0] = (n2&0xff); out[1] = (n2>>8)&0xff; out[2]=(n2>>16)&0xff; out[3]=n2>>24; + out[4] = (n1&0xff); out[5] = (n1>>8)&0xff; out[6]=(n1>>16)&0xff; out[7]=n1>>24; + } /* Low-level decryption routine. Decrypts one 64-bit block */ void gostdecrypt(gost_ctx *c, const byte *in,byte *out) -{ + { register word32 n1, n2; /* As named in the GOST */ n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24); n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24); @@ -193,102 +195,113 @@ void gostdecrypt(gost_ctx *c, const byte *in,byte *out) n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]); out[0] = (n2&0xff); out[1] = (n2>>8)&0xff; out[2]=(n2>>16)&0xff; out[3]=n2>>24; out[4] = (n1&0xff); out[5] = (n1>>8)&0xff; out[6]=(n1>>16)&0xff; out[7]=n1>>24; -} + } /* Encrypts several blocks in ECB mode */ void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks) -{ + { int i; - for(i=0;i<blocks;i++){ + for(i=0;i<blocks;i++) + { gostcrypt(c,clear,cipher); clear+=8; cipher+=8; + } } -} /* Decrypts several blocks in ECB mode */ void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks) -{ + { int i; - for(i=0;i<blocks;i++) { + for(i=0;i<blocks;i++) + { gostdecrypt(c,cipher,clear); clear+=8; cipher+=8; + } } -} - /* Encrypts several full blocks in CFB mode using 8byte IV */ -void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks) { +void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks) + { byte cur_iv[8]; byte gamma[8]; int i,j; const byte *in; byte *out; memcpy(cur_iv,iv,8); - for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8) { + for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8) + { gostcrypt(ctx,cur_iv,gamma); - for (j=0;j<8;j++) { + for (j=0;j<8;j++) + { cur_iv[j]=out[j]=in[j]^gamma[j]; - } + } + } } - -} /* Decrypts several full blocks in CFB mode using 8byte IV */ -void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear, int blocks) { +void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear, int blocks) + { byte cur_iv[8]; byte gamma[8]; int i,j; const byte *in; byte *out; memcpy(cur_iv,iv,8); - for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8) { + for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8) + { gostcrypt(ctx,cur_iv,gamma); - for (j=0;j<8;j++) { + for (j=0;j<8;j++) + { out[j]=(cur_iv[j]=in[j])^gamma[j]; - } + } + } } -} /* Encrypts one block using specified key */ void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock) -{ + { gost_key(c,key); gostcrypt(c,inblock,outblock); + } -} /* Set 256 bit key into context */ void gost_key(gost_ctx *c, const byte *k) -{ + { int i,j; - for(i=0,j=0;i<8;i++,j+=4) { + for(i=0,j=0;i<8;i++,j+=4) + { c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24); - } -} + } + } + /* Retrieve 256-bit key from context */ void gost_get_key(gost_ctx *c, byte *k) -{ + { int i,j; - for(i=0,j=0;i<8;i++,j+=4) { + for(i=0,j=0;i<8;i++,j+=4) + { k[j]=c->k[i]& 0xFF; k[j+1]=(c->k[i]>>8 )&0xFF; k[j+2]=(c->k[i]>>16) &0xFF; k[j+3]=(c->k[i]>>24) &0xFF; - } + } + } -} /* Initalize context. Provides default value for subst_block */ void gost_init(gost_ctx *c, const gost_subst_block *b) -{ - if(!b) { + { + if(!b) + { b=&GostR3411_94_TestParamSet; - } + } kboxinit(c,b); -} + } + /* Cleans up key from context */ void gost_destroy(gost_ctx *c) -{ + { int i; for(i=0;i<8;i++) c->k[i]=0; -} + } /* Compute GOST 28147 mac block * @@ -297,80 +310,86 @@ void gost_destroy(gost_ctx *c) * buffer - 8-byte mac state buffer * block 8-byte block to process. * */ -void mac_block(gost_ctx *c,byte *buffer,const byte *block) { - - register word32 n1, n2; /* As named in the GOST */ - int i; - for (i=0; i<8; i++) { - buffer[i]^=block[i]; - } - n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); - n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); - /* Instead of swapping halves, swap names each round */ +void mac_block(gost_ctx *c,byte *buffer,const byte *block) + { + register word32 n1, n2; /* As named in the GOST */ + int i; + for (i=0; i<8; i++) + { + buffer[i]^=block[i]; + } + n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24); + n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24); + /* Instead of swapping halves, swap names each round */ - n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); - n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); - n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); - n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); - n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); - n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); - n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); - n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); + n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]); + n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]); + n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]); + n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]); buffer[0] = (n1&0xff); buffer[1] = (n1>>8)&0xff; buffer[2]=(n1>>16)&0xff; buffer[3]=n1>>24; buffer[4] = (n2&0xff); buffer[5] = (n2>>8)&0xff; buffer[6]=(n2>>16)&0xff; buffer[7]=n2>>24; -} + } /* Get mac with specified number of bits from MAC state buffer */ -void get_mac(byte *buffer,int nbits,byte *out) { +void get_mac(byte *buffer,int nbits,byte *out) + { int nbytes= nbits >> 3; int rembits = nbits & 7; int mask =rembits?((1<rembits)-1):0; int i; for (i=0;i<nbytes;i++) out[i]=buffer[i]; if (rembits) out[i]=buffer[i]&mask; -} + } /* Compute mac of specified length (in bits) from data. * Context should be initialized with key and subst blocks */ int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data, - unsigned int data_len,unsigned char *mac) -{ + unsigned int data_len,unsigned char *mac) + { byte buffer[8]={0,0,0,0,0,0,0,0}; byte buf2[8]; int i; for (i=0;i+8<=data_len;i+=8) mac_block(ctx,buffer,data+i); - if (i<data_len) { + if (i<data_len) + { memset(buf2,0,8); memcpy(buf2,data+i,data_len-i); mac_block(ctx,buffer,buf2); - } + } get_mac(buffer,mac_len,mac); return 1; -} + } + /* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */ int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data, - unsigned int data_len,unsigned char *mac) -{ + unsigned int data_len,unsigned char *mac) + { byte buffer[8]; byte buf2[8]; int i; memcpy (buffer,iv,8); for (i=0;i+8<=data_len;i+=8) mac_block(ctx,buffer,data+i); - if (i<data_len) { + if (i<data_len) + { memset(buf2,0,8); memcpy(buf2,data+i,data_len-i); mac_block(ctx,buffer,buf2); - } + } get_mac(buffer,mac_len,mac); return 1; -} + } /* Implements key meshing algorithm by modifing ctx and IV in place */ -void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv) { +void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv) + { unsigned char newkey[32],newiv[8]; /* Set static keymeshing key */ /* "Decrypt" key with keymeshing key */ @@ -380,4 +399,4 @@ void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv) { /* Encrypt iv with new key */ gostcrypt(ctx,iv,newiv); memcpy(iv,newiv,8); -} + } diff --git a/engines/ccgost/gost94_keyx.c b/engines/ccgost/gost94_keyx.c index 4cf8a0ba80..599185f66d 100644 --- a/engines/ccgost/gost94_keyx.c +++ b/engines/ccgost/gost94_keyx.c @@ -14,62 +14,59 @@ #include <openssl/evp.h> #include <openssl/objects.h> -#include "gostkeyx.h" -#include "gost_asn1.h" #include "gost89.h" #include "gosthash.h" -#include "crypt.h" #include "e_gost_err.h" -#include "pmeth.h" -#include "keywrap.h" -#include "tools.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" /* Common functions for both 94 and 2001 key exchange schemes */ int decrypt_cryptocom_key(unsigned char *sess_key,int max_key_len, - const unsigned char *crypted_key,int crypted_key_len, gost_ctx *ctx) -{ + const unsigned char *crypted_key,int crypted_key_len, gost_ctx *ctx) + { int i; int j; int blocks = crypted_key_len >>3; unsigned char gamma[8]; - if (max_key_len <crypted_key_len) { + if (max_key_len <crypted_key_len) + { GOSTerr(GOST_F_DECRYPT_CRYPTOCOM_KEY,GOST_R_NOT_ENOUGH_SPACE_FOR_KEY); return 0; - } + } if ((crypted_key_len & 7) !=0) - { + { GOSTerr(GOST_F_DECRYPT_CRYPTOCOM_KEY,GOST_R_INVALID_ENCRYPTED_KEY_SIZE); return 0; - } + } for (i=blocks-1;i>0;i--) - { + { gostcrypt(ctx,crypted_key+(i-1)*8,gamma); for(j=0;j<8;j++) - { + { sess_key[i*8+j]=gamma[j]^crypted_key[i*8+j]; - } - } + } + } gostcrypt(ctx,sess_key+crypted_key_len-8,gamma); for(j=0;j<8;j++) - { + { sess_key[j]=gamma[j]^crypted_key[j]; - } + } return 1; -} + } int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len, - unsigned char *crypted_key, gost_ctx *ctx) -{ + unsigned char *crypted_key, gost_ctx *ctx) + { int i; int j; unsigned char gamma[8]; memcpy(gamma,sess_key+key_len-8,8); for (i=0;i<key_len;i+=8) - { + { gostcrypt(ctx,gamma,gamma); for (j=0;j<8;j++) gamma[j]=crypted_key[i+j]=sess_key[i+j]^gamma[j]; - } + } return 1; -} + } /* Implementation of the Diffi-Hellman key agreement scheme based on * GOST-94 keys */ @@ -78,23 +75,24 @@ int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len, * algorigthm */ static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) -{ + { unsigned char be_key[128]; int i,key_size; key_size=DH_compute_key(be_key,pub_key,dh); if (!key_size) return 0; memset(pair_key,0,128); - for (i=0;i<key_size;i++) { + for (i=0;i<key_size;i++) + { pair_key[i]=be_key[key_size-1-i]; - } + } return key_size; -} + } /* * Computes 256 bit key exchange key for CryptoCom variation of GOST 94 * algorithm */ static int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key) -{ + { unsigned char dh_key [128]; int i; /* Compute key */ @@ -105,34 +103,39 @@ static int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key) * 2^509<p<2^512, so DH_size can be exactly 128 or exactly 64 only */ - if (DH_size(dh)==128) - for (i=0;i<64;i++) { + if (DH_size(dh)==128) + { + for (i=0;i<64;i++) + { dh_key[i]^=dh_key[64+i]; - } - for (i=0;i<32;i++) { + } + } + for (i=0;i<32;i++) + { shared_key[i]=dh_key[i]^dh_key[32+i]; - } + } return 1; -} + } static DH *make_ephemeral_key(EVP_PKEY *pubk,BIGNUM *ephemeral_key) -{ + { DH *dh = DH_new(); dh->g = BN_dup(pubk->pkey.dsa->g); dh->p = BN_dup(pubk->pkey.dsa->p); dh->priv_key = BN_dup(ephemeral_key); /* Generate ephemeral key pair */ - if (!DH_generate_key(dh)) { + if (!DH_generate_key(dh)) + { DH_free(dh); return NULL; - } + } return dh; -} + } /* * Computes 256 bit Key exchange key as specified in RFC 4357 */ static int make_cp_exchange_key(DH *dh,EVP_PKEY *pubk, unsigned char *shared_key) -{ + { unsigned char dh_key [128]; gost_hash_ctx hash_ctx; memset(dh_key,0,128); @@ -143,13 +146,14 @@ static int make_cp_exchange_key(DH *dh,EVP_PKEY *pubk, unsigned char *shared_key finish_hash(&hash_ctx,shared_key); done_gost_hash_ctx(&hash_ctx); return 1; -} + } + /* EVP_PKEY_METHOD callback encrypt for * GOST R 34.10-94 cryptopro modification */ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ) -{ + { GOST_KEY_TRANSPORT *gkt=NULL; DH *dh = NULL; unsigned char shared_key[32], ukm[8],crypted_key[44]; @@ -159,64 +163,72 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, int size=-1; gost_ctx cctx; - - if (!(data->eph_seckey)) { + if (!(data->eph_seckey)) + { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT); + GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT); return -1; - } + } dh = make_ephemeral_key(pubk,gost_get_priv_key(data->eph_seckey)); gost_init(&cctx,param->sblock); make_cp_exchange_key(dh,pubk,shared_key); - if (RAND_bytes(ukm,8)<=0) { + if (RAND_bytes(ukm,8)<=0) + { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_RANDOM_GENERATOR_FAILURE); + GOST_R_RANDOM_GENERATOR_FAILURE); return -1; - } + } keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key); gkt = GOST_KEY_TRANSPORT_new(); - if (!gkt) { + if (!gkt) + { goto memerr; - } + } if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, - ukm,8)) { + ukm,8)) + { goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) { + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4)) + { goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) { + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32)) + { goto memerr; - } - if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) { + } + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) + { GOSTerr(GOST_F_PKEY_GOST94CP_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); *outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out); - if (!size) { + if (!size) + { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO); size=-1; - } + } GOST_KEY_TRANSPORT_free(gkt); DH_free(dh); return 1; -memerr: - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_MALLOC_FAILURE); -err: - GOST_KEY_TRANSPORT_free(gkt); - DH_free(dh); - return -1; -} + memerr: + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_MALLOC_FAILURE); + err: + GOST_KEY_TRANSPORT_free(gkt); + DH_free(dh); + return -1; + } + /* EVP_PKEY_METHOD callback encrypt for * GOST R 34.10-94 cryptocom modification */ int pkey_GOST94cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * key,size_t key_len) -{ + { EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx); struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); /* create DH structure filling parameters from passed pub_key */ @@ -225,68 +237,70 @@ int pkey_GOST94cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen gost_ctx cctx; EVP_PKEY *newkey=NULL; unsigned char shared_key[32],encrypted_key[32],hmac[4], - iv[8]={0,0,0,0,0,0,0,0}; + iv[8]={0,0,0,0,0,0,0,0}; - if (! data->eph_seckey) { + if (! data->eph_seckey) + { GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT); + GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT); return -1; - } + } dh = make_ephemeral_key(pubk,gost_get_priv_key(data->eph_seckey)); if (!dh) goto err; /* compute shared key */ if (!make_gost_shared_key(dh,pubk,shared_key)) - { + { GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; - } + } /* encrypt session key */ gost_init(&cctx, &GostR3411_94_CryptoProParamSet); gost_key(&cctx,shared_key); encrypt_cryptocom_key(key,key_len,encrypted_key,&cctx); /* compute hmac of session key */ if (!gost_mac(&cctx,32,key,32,hmac)) - { + { DH_free(dh); GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_COMPUTING_MAC); return -1; - } + } gkt = GOST_KEY_TRANSPORT_new(); if (!gkt) - { + { DH_free(dh); GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_NO_MEMORY); return -1; - } + } /* Store IV which is always zero in our case */ if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,iv,8)) - { + { GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_STORING_IV); goto err; - } + } if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,hmac,4)) - { + { GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_STORING_MAC); goto err; - } + } if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,encrypted_key,32)) - { + { GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_STORING_ENCRYPTED_KEY); goto err; - } - if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) { + } + if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,data->eph_seckey)) + { GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY); goto err; - } + } ASN1_OBJECT_free(gkt->key_agreement_info->cipher); gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc); *outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out); -err: + err: if (gkt) GOST_KEY_TRANSPORT_free(gkt); if (dh) DH_free(dh); if (newkey) EVP_PKEY_free(newkey); return 1; -} + } /* EVP_PLEY_METHOD callback decrypt for * GOST R 34.10-94 cryptopro modification @@ -302,21 +316,23 @@ int pkey_GOST94cp_decrypt (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_le EVP_PKEY *eph_key=NULL; EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx); - if (!key) { + if (!key) + { *key_len = 32; return 1; - } + } dh->g = BN_dup(priv->pkey.dsa->g); dh->p = BN_dup(priv->pkey.dsa->p); dh->priv_key = BN_dup(priv->pkey.dsa->priv_key); gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, - in_len); - if (!gkt) { + in_len); + if (!gkt) + { GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); DH_free(dh); return 0; - } + } eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); param = get_encryption_params(gkt->key_agreement_info->cipher); gost_init(&cctx,param->sblock); @@ -327,11 +343,12 @@ int pkey_GOST94cp_decrypt (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_le OPENSSL_assert(gkt->key_info->imit->length==4); memcpy(wrappedKey+40,gkt->key_info->imit->data,4); make_cp_exchange_key(dh,eph_key,sharedKey); - if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key)) { + if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key)) + { GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, - GOST_R_ERROR_COMPUTING_SHARED_KEY); + GOST_R_ERROR_COMPUTING_SHARED_KEY); goto err; - } + } EVP_PKEY_free(eph_key); GOST_KEY_TRANSPORT_free(gkt); @@ -342,14 +359,14 @@ err: GOST_KEY_TRANSPORT_free(gkt); DH_free(dh); return -1; - -} + } + /* EVP_PKEY_METHOD callback decrypt for * GOST R 34.10-94 cryptocom modification */ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_len, const unsigned char *in, size_t in_len) -{ + { /* Form DH params from compute shared key */ GOST_KEY_TRANSPORT *gkt = NULL; const unsigned char *p=in; @@ -362,22 +379,24 @@ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l EVP_PKEY *eph_key; EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); - if (!key) { + if (!key) + { *key_len = 32; return 1; - } + } /* Construct DH structure from the our GOST private key */ dh->g = BN_dup(priv->pkey.dsa->g); dh->p = BN_dup(priv->pkey.dsa->p); dh->priv_key = BN_dup(priv->pkey.dsa->priv_key); /* Parse passed octet string and find out public key, iv and HMAC*/ gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p, - in_len); - if (!gkt) { + in_len); + if (!gkt) + { GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); DH_free(dh); return 0; - } + } eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); /* Initialization vector is really ignored here */ OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8); @@ -390,31 +409,33 @@ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l EVP_PKEY_free(eph_key); DH_free(dh); if (!i) - { + { GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_COMPUTING_SHARED_KEY); GOST_KEY_TRANSPORT_free(gkt); return 0; - } + } /* Decrypt session key */ gost_init(&ctx, &GostR3411_94_CryptoProParamSet); gost_key(&ctx,shared_key); if (!decrypt_cryptocom_key(key,*key_len,gkt->key_info->encrypted_key->data, gkt->key_info->encrypted_key->length, &ctx)) - { + { GOST_KEY_TRANSPORT_free(gkt); return 0; - } + } GOST_KEY_TRANSPORT_free(gkt); /* check HMAC of session key*/ - if (!gost_mac(&ctx,32,key,32,hmac_comp)) { + if (!gost_mac(&ctx,32,key,32,hmac_comp)) + { GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_COMPUTING_MAC); return 0; - } - /* HMAC of session key is not correct */ - if (memcmp(hmac,hmac_comp,4)!=0) { + } + /* HMAC of session key is not correct */ + if (memcmp(hmac,hmac_comp,4)!=0) + { GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH); return 0; - } + } return 1; -} + } diff --git a/engines/ccgost/ameth.c b/engines/ccgost/gost_ameth.c index c64cd2d298..4885ca4787 100644 --- a/engines/ccgost/ameth.c +++ b/engines/ccgost/gost_ameth.c @@ -1,5 +1,5 @@ /********************************************************************** - * ameth.c * + * gost_ameth.c * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * @@ -10,91 +10,91 @@ #include <openssl/engine.h> #include <openssl/evp.h> #include <string.h> -#include "meth.h" -#include "pmeth.h" -#include "paramset.h" -#include "gost_asn1.h" -#include "crypt.h" -#include "sign.h" -#include "tools.h" +#include "gost_params.h" +#include "gost_lcl.h" #include "e_gost_err.h" int gost94_nid_by_params(DSA *p) -{ + { R3410_params *gost_params; BIGNUM *q=BN_new(); - for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) { + for (gost_params = R3410_paramset;gost_params->q!=NULL; gost_params++) + { BN_dec2bn(&q,gost_params->q); if (!BN_cmp(q,p->q)) - { + { BN_free(q); return gost_params->nid; - } - } + } + } BN_free(q); return NID_undef; -} + } 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; int cipher_param_nid = NID_undef; - if (!params || !gkp) { + 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_2001_cc: - pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc; - cipher_param_nid = NID_id_Gost28147_89_cc; - break; - case NID_id_GostR3410_94_cc: - pkey_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - cipher_param_nid = NID_id_Gost28147_89_cc; - break; - case NID_id_GostR3410_2001: - pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key))); - cipher_param_nid = get_encryption_params(NULL)->nid; - break; - case NID_id_GostR3410_94: - pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); - if (pkey_param_nid == NID_undef) { - GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, - GOST_R_INVALID_GOST94_PARMSET); - ASN1_STRING_free(params); - params=NULL; - goto err; } - cipher_param_nid = get_encryption_params(NULL)->nid; - break; - } + switch (EVP_PKEY_base_id(key)) + { + case NID_id_GostR3410_2001_cc: + pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc; + cipher_param_nid = NID_id_Gost28147_89_cc; + break; + case NID_id_GostR3410_94_cc: + pkey_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; + cipher_param_nid = NID_id_Gost28147_89_cc; + break; + case NID_id_GostR3410_2001: + pkey_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)key))); + cipher_param_nid = get_encryption_params(NULL)->nid; + break; + case NID_id_GostR3410_94: + pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); + if (pkey_param_nid == NID_undef) + { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, + GOST_R_INVALID_GOST94_PARMSET); + ASN1_STRING_free(params); + params=NULL; + goto err; + } + cipher_param_nid = get_encryption_params(NULL)->nid; + break; + } 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; -err: + err: GOST_KEY_PARAMS_free(gkp); return params; -} + } + /* Parses GOST algorithm parameters from X509_ALGOR and * modifies pkey setting NID and parameters */ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) -{ + { ASN1_OBJECT *palg_obj =NULL; int ptype = V_ASN1_UNDEF; int pkey_nid = NID_undef,param_nid = NID_undef; @@ -103,161 +103,184 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) GOST_KEY_PARAMS *gkp = NULL; X509_ALGOR_get0(&palg_obj, &ptype, (void **) (&pval), palg); - if (ptype != V_ASN1_SEQUENCE) { + if (ptype != V_ASN1_SEQUENCE) + { GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, GOST_R_BAD_KEY_PARAMETERS_FORMAT); return 0; - } + } p=pval->data; pkey_nid = OBJ_obj2nid(palg_obj); gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length); - if (!gkp) { + if (!gkp) + { GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, - GOST_R_BAD_PKEY_PARAMETERS_FORMAT); - } + GOST_R_BAD_PKEY_PARAMETERS_FORMAT); + } param_nid = OBJ_obj2nid(gkp->key_params); GOST_KEY_PARAMS_free(gkp); EVP_PKEY_set_type(pkey,pkey_nid); - switch (pkey_nid) { - case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: - { DSA *dsa= EVP_PKEY_get0(pkey); - if (!dsa) { - dsa = DSA_new(); - if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0; + switch (pkey_nid) + { + case NID_id_GostR3410_94: + case NID_id_GostR3410_94_cc: + { + DSA *dsa= EVP_PKEY_get0(pkey); + if (!dsa) + { + dsa = DSA_new(); + if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0; } - if (!fill_GOST94_params(dsa,param_nid)) return 0; - break; + if (!fill_GOST94_params(dsa,param_nid)) return 0; + break; } - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: - { EC_KEY *ec = EVP_PKEY_get0(pkey); - if (!ec) { - ec = EC_KEY_new(); - if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0; + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001_cc: + { + 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; - - } - - } + if (!fill_GOST2001_params(ec,param_nid)) return 0; + } + } return 1; -} + } static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv) -{ - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: - { DSA *dsa = EVP_PKEY_get0(pkey); - if (!dsa) { - dsa = DSA_new(); - EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa); + { + switch (EVP_PKEY_base_id(pkey)) + { + case NID_id_GostR3410_94: + case NID_id_GostR3410_94_cc: + { + 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; + dsa->priv_key = BN_dup(priv); + if (!EVP_PKEY_missing_parameters(pkey)) + gost94_compute_public(dsa); + break; } - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: - { EC_KEY *ec = EVP_PKEY_get0(pkey); - if (!ec) { - ec = EC_KEY_new(); - EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec); + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001_cc: + { + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (!ec) + { + ec = EC_KEY_new(); + EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec); } - if (!EC_KEY_set_private_key(ec,priv)) return 0; - if (!EVP_PKEY_missing_parameters(pkey)) - gost2001_compute_public(ec); - break; + if (!EC_KEY_set_private_key(ec,priv)) return 0; + if (!EVP_PKEY_missing_parameters(pkey)) + gost2001_compute_public(ec); + break; + } } - - } return 1; -} + } BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) -{ - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: - { DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); - if (!dsa) { - return NULL; + { + switch (EVP_PKEY_base_id(pkey)) + { + case NID_id_GostR3410_94: + case NID_id_GostR3410_94_cc: + { + DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); + if (!dsa) + { + return NULL; } - if (!dsa->priv_key) return NULL; - return BN_dup(dsa->priv_key); - break; + if (!dsa->priv_key) return NULL; + return BN_dup(dsa->priv_key); + break; } - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: - { EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); - const BIGNUM* priv; - if (!ec) { - return NULL; + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001_cc: + { + EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); + const BIGNUM* priv; + if (!ec) + { + return NULL; } - if (!(priv=EC_KEY_get0_private_key(ec))) return NULL; - return BN_dup(priv); - break; + if (!(priv=EC_KEY_get0_private_key(ec))) return NULL; + return BN_dup(priv); + break; + } } - - } return NULL; -} + } + static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, - long arg1, void *arg2) -{ - switch (op) + long arg1, void *arg2) { + switch (op) + { case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { + 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); + NULL, &alg1, &alg2); X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), - V_ASN1_NULL, 0); - if (nid == NID_undef) { + V_ASN1_NULL, 0); + if (nid == NID_undef) + { return (-1); - } + } X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); - } + } return 1; case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: if (arg1 == 0) { X509_ALGOR *alg; ASN1_STRING * params = encode_gost_algor_params(pkey); - if (!params) { + if (!params) + { return -1; - } + } PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg); X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), - V_ASN1_SEQUENCE, params); + V_ASN1_SEQUENCE, params); } return 1; case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_id_GostR3411_94; - return 2; - } + *(int *)arg2 = NID_id_GostR3411_94; + return 2; + } return -2; -} + } /*----------------------- free functions * ------------------------------*/ -static void pkey_free_gost94(EVP_PKEY *key) { - if (key->pkey.dsa) { +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) { - if (key->pkey.ec) { - EC_KEY_free(key->pkey.ec); + } } -} + +static void pkey_free_gost01(EVP_PKEY *key) + { + if (key->pkey.ec) + { + EC_KEY_free(key->pkey.ec); + } + } + /* ------------------ private key functions -----------------------------*/ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) -{ + { const unsigned char *pkey_buf = NULL,*p=NULL; int priv_len = 0; BIGNUM *pk_num=NULL; @@ -269,25 +292,48 @@ static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) return 0; p = pkey_buf; - if (!decode_gost_algor_params(pk,palg)) { + if (!decode_gost_algor_params(pk,palg)) + { return 0; - } - priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len); - if (!priv_key) { - } - - if (!(pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))) { - GOSTerr(GOST_F_PRIV_DECODE_GOST_94, - EVP_R_DECODE_ERROR); - } + } + 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) + { + GOSTerr(GOST_F_PRIV_DECODE_GOST_94, + EVP_R_DECODE_ERROR); + return 0; + } + for (i=0;i<32;i++) + { + rev_buf[31-i]=s->data[i]; + } + ASN1_STRING_free(s); + pk_num = getbnfrombuf(rev_buf,32); + } + else + { + priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len); + if (!priv_key || !(pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))) + { + GOSTerr(GOST_F_PRIV_DECODE_GOST_94, + EVP_R_DECODE_ERROR); + return 0; + } + } ret= gost_set_priv_key(pk,pk_num); BN_free(pk_num); return ret; -} + } + /* ----------------------------------------------------------------------*/ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) -{ + { ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); ASN1_STRING *params = encode_gost_algor_params(pk); unsigned char *priv_buf = NULL; @@ -295,9 +341,10 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) BIGNUM *key; ASN1_INTEGER *asn1key=NULL; - if (!params) { + if (!params) + { return 0; - } + } key = gost_get_priv_key(pk); asn1key = BN_to_ASN1_INTEGER(key,NULL); BN_free(key); @@ -305,11 +352,11 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) ASN1_INTEGER_free(asn1key); return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params, priv_buf,priv_len); -} + } static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ + ASN1_PCTX *pctx) + { BIGNUM *key; if (!BIO_indent(out,indent,128)) return 0; key = gost_get_priv_key(pkey); @@ -317,96 +364,106 @@ static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent, BN_print(out,key); BN_free(key); return 1; -} + } + /* ---------------------------------------------------------------------*/ 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) -{ + { const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); if (!ec) return 1; if (!EC_KEY_get0_group(ec)) return 1; 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); + GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; - } + } if (!dfrom) - { + { GOSTerr(GOST_F_PARAM_COPY_GOST94, - GOST_R_KEY_PARAMETERS_MISSING); + 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) + COPYBIGNUM(dto,dfrom,q) + COPYBIGNUM(dto,dfrom,g) - if (dto->priv_key) - gost94_compute_public(dto); + 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_gost01(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)) { + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) + { GOSTerr(GOST_F_PARAM_COPY_GOST01, - GOST_R_INCOMPATIBLE_ALGORITHMS); + GOST_R_INCOMPATIBLE_ALGORITHMS); return 0; - } - if (!efrom) { + } + if (!efrom) + { GOSTerr(GOST_F_PARAM_COPY_GOST94, - GOST_R_KEY_PARAMETERS_MISSING); + GOST_R_KEY_PARAMETERS_MISSING); return 0; - } - if (!eto) { + } + if (!eto) + { eto = EC_KEY_new(); EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto); - } + } EC_KEY_set_group(eto,EC_GROUP_dup(EC_KEY_get0_group(efrom))); - if (EC_KEY_get0_private_key(eto)) { + if (EC_KEY_get0_private_key(eto)) + { gost2001_compute_public(eto); - } + } return 1; - - + } -} -static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) { +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 (!BN_cmp(da->q,db->q)) return 1; return 0; -} -static int param_cmp_gost01(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)))) { - return 1; } + +static int param_cmp_gost01(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)))) + { + 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; @@ -416,43 +473,45 @@ static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) ASN1_OCTET_STRING *octet= NULL; if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, - &palg, pub)) return 0; + &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); 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; + 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) { + 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); BN_bn2bin(dsa->pub_key,databuf); @@ -460,17 +519,18 @@ static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk) 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) -{ + { X509_ALGOR *palg = NULL; const unsigned char *pubkey_buf = NULL; unsigned char *databuf; @@ -482,51 +542,55 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub) const EC_GROUP *group; if (!X509_PUBKEY_get0_param(&palgobj,&pubkey_buf,&pub_len, - &palg, pub)) return 0; + &palg, pub)) return 0; EVP_PKEY_assign(pk,OBJ_obj2nid(palgobj),NULL); if (!decode_gost_algor_params(pk,palg)) return 0; 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_GOST94,ERR_R_MALLOC_FAILURE); return 0; - } + } databuf = OPENSSL_malloc(octet->length); for (i=0,j=octet->length-1;i<octet->length;i++,j--) - { + { databuf[j]=octet->data[i]; - } - if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) { + } + if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) + { X= getbnfrombuf(databuf,octet->length/2); Y= getbnfrombuf(databuf+(octet->length/2),octet->length/2); - } else { + } + else + { Y= getbnfrombuf(databuf,octet->length/2); X= getbnfrombuf(databuf+(octet->length/2),octet->length/2); - } + } OPENSSL_free(databuf); pub_key = EC_POINT_new(group); if (!EC_POINT_set_affine_coordinates_GFp(group - ,pub_key,X,Y,NULL)) - { + ,pub_key,X,Y,NULL)) + { GOSTerr(GOST_F_PUB_DECODE_GOST01, - ERR_R_EC_LIB); + ERR_R_EC_LIB); return 0; - } + } 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); + ERR_R_EC_LIB); return 0; - } + } /*EC_POINT_free(pub_key);*/ return 1; -} + } + static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) -{ + { ASN1_OBJECT *algobj = NULL; ASN1_OCTET_STRING *octet = NULL; void *pval = NULL; @@ -535,22 +599,24 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) const EC_POINT *pub_key; BIGNUM *X,*Y,*order; const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); - int ptype; + int ptype = V_ASN1_UNDEF; algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); - if (pk->save_parameters) { + if (pk->save_parameters) + { ASN1_STRING *params = encode_gost_algor_params(pk); pval = params; ptype = V_ASN1_SEQUENCE; - } + } order = BN_new(); EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL); pub_key=EC_KEY_get0_public_key(ec); - if (!pub_key) { + if (!pub_key) + { GOSTerr(GOST_F_PUB_ENCODE_GOST01, - GOST_R_PUBLIC_KEY_UNDEFINED); + GOST_R_PUBLIC_KEY_UNDEFINED); return 0; - } + } X=BN_new(); Y=BN_new(); EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), @@ -559,39 +625,46 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk) BN_free(order); databuf = OPENSSL_malloc(data_len); memset(databuf,0,data_len); - if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) { + if (EVP_PKEY_base_id(pk) == NID_id_GostR3410_2001_cc) + { store_bignum(X,databuf,data_len/2); store_bignum(Y,databuf+data_len/2,data_len/2); - } else { + } + else + { 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(); ASN1_STRING_set(octet,NULL,data_len); sptr=ASN1_STRING_data(octet); - for (i=0,j=data_len-1;i<data_len;i++,j--) { + 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_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 && da->pub_key && db->pub_key - && !BN_cmp(da->pub_key,db->pub_key)) { - return 1; - } + && !BN_cmp(da->pub_key,db->pub_key)) + { + return 1; + } return 0; -} + } + static int pub_cmp_gost01(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; @@ -602,36 +675,43 @@ static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b) if (!ka || !kb) return 0; ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ; return ret; -} + } + static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) -{ + { const BIGNUM *key; if (!BIO_indent(out,indent,128)) return 0; key = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; if (!key) return 0; BN_print(out,key); return 1; -} + } + static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) -{ + { return 0; -} + } + static int pkey_size_gost(const EVP_PKEY *pk) -{ + { return 64; -} + } + static int pkey_bits_gost(const EVP_PKEY *pk) -{ + { return 256; -} + } + /* ----------------------------------------------------------------------*/ -int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) { +int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) + { *ameth = EVP_PKEY_asn1_new(nid, - ASN1_PKEY_SIGPARAM_NULL, pemstr, info); + ASN1_PKEY_SIGPARAM_NULL, pemstr, info); if (!*ameth) return 0; - switch (nid) { + switch (nid) + { case NID_id_GostR3410_94_cc: case NID_id_GostR3410_94: EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94); @@ -666,6 +746,6 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); break; - } + } return 1; -} + } diff --git a/engines/ccgost/gost_asn1.c b/engines/ccgost/gost_asn1.c index e7303b7f92..d9a274d20d 100644 --- a/engines/ccgost/gost_asn1.c +++ b/engines/ccgost/gost_asn1.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <openssl/asn1t.h> #include <openssl/x509.h> -#include "gost_asn1.h" +#include "gost_lcl.h" ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = { ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO), diff --git a/engines/ccgost/gost_asn1.h b/engines/ccgost/gost_asn1.h deleted file mode 100644 index 81075e47d3..0000000000 --- a/engines/ccgost/gost_asn1.h +++ /dev/null @@ -1,57 +0,0 @@ -/********************************************************************** - * gost_keytrans.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * ASN1 structure declaration for GOST key transport * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#ifndef GOST_KEY_TRANS_H -#define GOST_KEY_TRANS_H -#include <openssl/asn1t.h> -#include <openssl/x509.h> - - -typedef struct { - ASN1_OCTET_STRING *encrypted_key; - ASN1_OCTET_STRING *imit; -} GOST_KEY_INFO; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) - -typedef struct { - ASN1_OBJECT *cipher; - X509_PUBKEY *ephem_key; - ASN1_OCTET_STRING *eph_iv; -} GOST_KEY_AGREEMENT_INFO; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) - -typedef struct { - GOST_KEY_INFO *key_info; - GOST_KEY_AGREEMENT_INFO *key_agreement_info; -} GOST_KEY_TRANSPORT; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) - -typedef struct { //FIXME incomplete - GOST_KEY_TRANSPORT *gkt; -} GOST_CLIENT_KEY_EXCHANGE_PARAMS; - -DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) -typedef struct { - ASN1_OBJECT *key_params; - ASN1_OBJECT *hash_params; - ASN1_OBJECT *cipher_params; -} GOST_KEY_PARAMS; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) - -typedef struct { - ASN1_OCTET_STRING *iv; - ASN1_OBJECT *enc_param_set; -} GOST_CIPHER_PARAMS; - -DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) - -#endif diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c index 9b3803d8fd..5ea02d1063 100644 --- a/engines/ccgost/gost_crypt.c +++ b/engines/ccgost/gost_crypt.c @@ -1,32 +1,31 @@ /********************************************************************** -* gost_crypt.c * -* Copyright (c) 2005-2006 Cryptocom LTD * -* This file is distributed under the same license as OpenSSL * -* * -* OpenSSL interface to GOST 28147-89 cipher functions * -* Requires OpenSSL 0.9.9 for compilation * -**********************************************************************/ + * gost_crypt.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * OpenSSL interface to GOST 28147-89 cipher functions * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ #include <string.h> -#include "crypt.h" #include "gost89.h" #include <openssl/rand.h> #include "e_gost_err.h" -#include "gost_asn1.h" +#include "gost_lcl.h" static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); + const unsigned char *iv, int enc); #ifdef USE_SSL /* Specialized init functions which set specific parameters */ static int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); + 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); + const unsigned char *iv, int enc); #endif /* Handles block of data in CFB mode */ static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, unsigned int inl); /* Handles block of data in CNT mode */ static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl); + const unsigned char *in, unsigned int inl); /* Cleanup function */ static int gost_cipher_cleanup(EVP_CIPHER_CTX *); /* set/get cipher parameters */ @@ -37,57 +36,57 @@ static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr); EVP_CIPHER cipher_gost = { - NID_id_Gost28147_89, - 1,/*block_size*/ - 32,/*key_size*/ - 8,/*iv_len - ñèíõðîïîñûëêà*/ - EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | - EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init, - gost_cipher_do_cfb, - gost_cipher_cleanup, - sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */ - gost89_set_asn1_parameters, - gost89_get_asn1_parameters, - gost_cipher_ctl, - NULL, + NID_id_Gost28147_89, + 1,/*block_size*/ + 32,/*key_size*/ + 8,/*iv_len - ñèíõðîïîñûëêà*/ + EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init, + gost_cipher_do_cfb, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx),/* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, }; #ifdef USE_SSL static EVP_CIPHER cipher_gost_vizircfb = { - NID_undef, - 1,/*block_size*/ - 32,/*key_size*/ - 8,/*iv_len - ñèíõðîïîñûëêà*/ - EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | - EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init_vizir, - gost_cipher_do_cfb, - gost_cipher_cleanup, - sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ - gost89_set_asn1_parameters, - gost89_get_asn1_parameters, - gost_cipher_ctl, - NULL, + NID_undef, + 1,/*block_size*/ + 32,/*key_size*/ + 8,/*iv_len - ñèíõðîïîñûëêà*/ + EVP_CIPH_CFB_MODE| EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV| EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init_vizir, + gost_cipher_do_cfb, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, }; static EVP_CIPHER cipher_gost_cpacnt = { - NID_undef, - 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_cpa, - 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, + NID_undef, + 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_cpa, + 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 */ @@ -143,130 +142,154 @@ EVP_MD imit_gost_cpa = #endif /* -* Correspondence between gost parameter OIDs and substitution blocks -* NID field is filed by register_gost_NID function in engine.c -* upon engine initialization -*/ + * Correspondence between gost parameter OIDs and substitution blocks + * NID field is filed by register_gost_NID function in engine.c + * upon engine initialization + */ -struct gost_cipher_info gost_cipher_list[]={ +struct gost_cipher_info gost_cipher_list[]= + { /* NID */ /* Subst block */ /* Key meshing*/ /*{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,1}, -{NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1}, -{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1}, -{NID_undef,NULL,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,1}, + {NID_id_Gost28147_89_CryptoPro_C_ParamSet,&Gost28147_CryptoProParamSetC,1}, + {NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1}, + {NID_undef,NULL,0} + }; /* get encryption parameters from crypto network settings -FIXME For now we use environment var CRYPT_PARAMS as place to -store these settings. Actually, it is better to use engine control command, read from configuration file to set them */ -const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) { -int nid; -struct gost_cipher_info *param; -if (!obj) { - const char * params = getenv("CRYPT_PARAMS"); - if (!params || !strlen(params)) - return &gost_cipher_list[0]; - - nid = OBJ_txt2nid(params); - if (nid == NID_undef) { - GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, + FIXME For now we use environment var CRYPT_PARAMS as place to + store these settings. Actually, it is better to use engine control command, read from configuration file to set them */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) + { + int nid; + struct gost_cipher_info *param; + if (!obj) + { + const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS); + if (!params || !strlen(params)) + return &gost_cipher_list[0]; + + nid = OBJ_txt2nid(params); + if (nid == NID_undef) + { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, GOST_R_INVALID_CIPHER_PARAM_OID); + return NULL; + } + } + else + { + nid= OBJ_obj2nid(obj); + } + for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; + param++); + if (!param->sblock) + { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS); return NULL; - } -} else { - nid= OBJ_obj2nid(obj); -} -for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid; - param++); -if (!param->sblock) { - GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS); - return NULL; - -} -return param; - -} + } + return param; + } + /* Sets cipher param from paramset NID. */ -int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid) { -const struct gost_cipher_info *param; -param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid))); -if (!param) return 0; +int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int nid) + { + const struct gost_cipher_info *param; + param=get_encryption_params((nid==NID_undef?NULL:OBJ_nid2obj(nid))); + if (!param) return 0; -c->paramNID = param->nid; -c->key_meshing=param->key_meshing; -c->count=0; -gost_init(&(c->cctx), param->sblock); -return 1; -} + c->paramNID = param->nid; + c->key_meshing=param->key_meshing; + c->count=0; + gost_init(&(c->cctx), param->sblock); + return 1; + } + /* Initializes EVP_CIPHER_CTX by paramset NID */ static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc, int paramNID,int mode) { -struct ossl_gost_cipher_ctx *c=ctx->cipher_data; -if (!gost_cipher_set_param(c,paramNID)) return 0; -if (key) gost_key(&(c->cctx),key); -if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); -memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); -return 1; -} + const unsigned char *iv, int enc, int paramNID,int mode) + { + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + if (ctx->app_data == NULL) + { + if (!gost_cipher_set_param(c,paramNID)) return 0; + ctx->app_data = ctx->cipher_data; + } + if (key) gost_key(&(c->cctx),key); + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; + } /* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */ int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) { -struct ossl_gost_cipher_ctx *c=ctx->cipher_data; -gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); -c->key_meshing=1; -c->count=0; -gost_key(&(c->cctx),key); -if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); -memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); -return 1; -} + const unsigned char *iv, int enc) + { + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); + c->key_meshing=1; + c->count=0; + gost_key(&(c->cctx),key); + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; + } + /* Initializes EVP_CIPHER_CTX with fixed vizir paramset */ int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) { -struct ossl_gost_cipher_ctx *c=ctx->cipher_data; -gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); -c->key_meshing=0; -c->count=0; -gost_key(&(c->cctx),key); - -if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); -memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); -return 1; -} + const unsigned char *iv, int enc) + { + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); + c->key_meshing=0; + c->count=0; + gost_key(&(c->cctx),key); + + if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; + } /* 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) { -return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE); -} + const unsigned char *iv, int enc) + { + return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE); + } /* Wrapper around gostcrypt function from gost89.c which perform -* key meshing when nesseccary -*/ -static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) { + * key meshing when nesseccary + */ +static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) + { struct ossl_gost_cipher_ctx *c = ctx; - if (c->count&&c->key_meshing && c->count%1024==0) { + if (c->count&&c->key_meshing && c->count%1024==0) + { cryptopro_key_meshing(&(c->cctx),iv); - } + } gostcrypt(&(c->cctx),iv,buf); c->count+=8; -} - -static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) { -struct ossl_gost_cipher_ctx *c = ctx; -word32 g,go; -unsigned char buf1[8]; -if (c->count && c->key_meshing && c->count %1024 ==0) { - cryptopro_key_meshing(&(c->cctx),iv); -} -if (c->count==0) { -gostcrypt(&(c->cctx),iv,buf1); -} else { - memcpy(buf1,iv,8); -} + } + +static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) + { + struct ossl_gost_cipher_ctx *c = ctx; + word32 g,go; + unsigned char buf1[8]; + if (c->count && c->key_meshing && c->count %1024 ==0) + { + cryptopro_key_meshing(&(c->cctx),iv); + } + if (c->count==0) + { + gostcrypt(&(c->cctx),iv,buf1); + } + else + { + memcpy(buf1,iv,8); + } g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24); g += 0x01010101; buf1[0]=g&0xff; buf1[1]=(g>>8)&0xff; buf1[2]=(g>>16)&0xff; buf1[3]=(g>>24)&0xff; @@ -278,302 +301,354 @@ gostcrypt(&(c->cctx),iv,buf1); buf1[4]=g&0xff; buf1[5]=(g>>8)&0xff; buf1[6]=(g>>16)&0xff; buf1[7]=(g>>24)&0xff; memcpy(iv,buf1,8); gostcrypt(&(c->cctx),buf1,buf); -c->count +=8; -} + c->count +=8; + } /* GOST encryption in CFB mode */ int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) { -const unsigned char *in_ptr=in; -unsigned char *out_ptr=out; -int i=0; -int j; -/* process partial block if any */ -if (ctx->num) -{ - for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) + const unsigned char *in, unsigned int inl) { - if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr; - *out_ptr=ctx->buf[j]^(*in_ptr); - if (ctx->encrypt) ctx->buf[j+8]=*out_ptr; - } - if (j==8) { - memcpy(ctx->iv,ctx->buf+8,8); - ctx->num=0; - } else { - ctx->num=j; - return 1; - } -} - -for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) { - /*block cipher current iv */ - gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf); - /*xor next block of input text with it and output it*/ - /*output this block */ - if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8); - for (j=0;j<8;j++) { + const unsigned char *in_ptr=in; + unsigned char *out_ptr=out; + int i=0; + int j=0; +/* process partial block if any */ + if (ctx->num) + { + for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) + { + if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr; + *out_ptr=ctx->buf[j]^(*in_ptr); + if (ctx->encrypt) ctx->buf[j+8]=*out_ptr; + } + if (j==8) + { + memcpy(ctx->iv,ctx->buf+8,8); + ctx->num=0; + } + else + { + ctx->num=j; + return 1; + } + } + + for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) + { + /*block cipher current iv */ + gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf); + /*xor next block of input text with it and output it*/ + /*output this block */ + if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8); + for (j=0;j<8;j++) + { out_ptr[j]=ctx->buf[j]^in_ptr[j]; - } - /* Encrypt */ - /* Next iv is next block of cipher text*/ - if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8); -} + } + /* Encrypt */ + /* Next iv is next block of cipher text*/ + if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8); + } /* Process rest of buffer */ -if (i<inl) { - gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf); - if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j); - for (j=0;i<inl;j++,i++) { + if (i<inl) + { + gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf); + if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j); + for (j=0;i<inl;j++,i++) + { out_ptr[j]=ctx->buf[j]^in_ptr[j]; - } - ctx->num = j; - if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j); -} else { - ctx->num = 0; -} -return 1; -} + } + ctx->num = j; + if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j); + } + else + { + ctx->num = 0; + } + return 1; + } + int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) { -const unsigned char *in_ptr=in; -unsigned char *out_ptr=out; -int i=0; -int j; -/* process partial block if any */ -if (ctx->num) -{ - for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) + const unsigned char *in, unsigned int inl) { - *out_ptr=ctx->buf[j]^(*in_ptr); - } - if (j==8) { - ctx->num=0; - } else { - ctx->num=j; - return 1; - } -} - -for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) { - /*block cipher current iv */ - /* Encrypt */ - gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf); - /*xor next block of input text with it and output it*/ - /*output this block */ - for (j=0;j<8;j++) { + const unsigned char *in_ptr=in; + unsigned char *out_ptr=out; + int i=0; + int j; +/* process partial block if any */ + if (ctx->num) + { + for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++) + { + *out_ptr=ctx->buf[j]^(*in_ptr); + } + if (j==8) + { + ctx->num=0; + } + else + { + ctx->num=j; + return 1; + } + } + + for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) + { + /*block cipher current iv */ + /* Encrypt */ + gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf); + /*xor next block of input text with it and output it*/ + /*output this block */ + for (j=0;j<8;j++) + { out_ptr[j]=ctx->buf[j]^in_ptr[j]; - } -} + } + } /* Process rest of buffer */ -if (i<inl) { - gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf); - for (j=0;i<inl;j++,i++) { + if (i<inl) + { + gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf); + for (j=0;i<inl;j++,i++) + { out_ptr[j]=ctx->buf[j]^in_ptr[j]; - } - ctx->num = j; -} else { - ctx->num = 0; -} -return 1; -} + } + ctx->num = j; + } + else + { + ctx->num = 0; + } + return 1; + } + /* Cleaning up of EVP_CIPHER_CTX */ int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) -{ -gost_destroy((gost_ctx *)ctx->cipher_data); -return 1; + { + gost_destroy((gost_ctx *)ctx->cipher_data); + ctx->app_data = NULL; + return 1; + } -} /* Control function for gost cipher */ int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr) -{ -switch (type) -{ - case EVP_CTRL_RAND_KEY: - { - if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0) - { - GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR); - return -1; - } - break; + { + switch (type) + { + case EVP_CTRL_RAND_KEY: + { + if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0) + { + GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_RANDOM_GENERATOR_ERROR); + return -1; } - default: - GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND); + break; + } + default: + GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND); return -1; -} -return 1; -} + } + return 1; + } /* Set cipher parameters from ASN1 structure */ int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params) -{ -int len=0; -unsigned char *buf=NULL; -unsigned char *p=NULL; -struct ossl_gost_cipher_ctx *c = ctx->cipher_data; -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); - 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); - 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); -if (!buf) { + { + int len=0; + unsigned char *buf=NULL; + unsigned char *p=NULL; + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + 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); + 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); + 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); + if (!buf) + { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + i2d_GOST_CIPHER_PARAMS(gcp, &p); GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; -} -i2d_GOST_CIPHER_PARAMS(gcp, &p); -GOST_CIPHER_PARAMS_free(gcp); -os = ASN1_OCTET_STRING_new(); + os = ASN1_OCTET_STRING_new(); -if(!os || !ASN1_OCTET_STRING_set(os, buf, len)) { + if(!os || !ASN1_OCTET_STRING_set(os, buf, len)) + { + OPENSSL_free(buf); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } OPENSSL_free(buf); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; -} -OPENSSL_free(buf); - -ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); -return 1; -} + + ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); + return 1; + } + /* Store parameters into ASN1 structure */ int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params) -{ -int ret = -1; -int len; -GOST_CIPHER_PARAMS *gcp = NULL; -unsigned char *p = params->value.sequence->data; -struct ossl_gost_cipher_ctx *c=ctx->cipher_data; -if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) { - return ret; -} - -gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, + { + int ret = -1; + int len; + GOST_CIPHER_PARAMS *gcp = NULL; + unsigned char *p = params->value.sequence->data; + struct ossl_gost_cipher_ctx *c=ctx->cipher_data; + if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) + { + return ret; + } + + gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, params->value.sequence->length); -len = gcp->iv->length; -if (len != ctx->cipher->iv_len) { - GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, + len = gcp->iv->length; + if (len != ctx->cipher->iv_len) + { + GOST_CIPHER_PARAMS_free(gcp); + 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))) { - GOST_CIPHER_PARAMS_free(gcp); - return -1; -} -memcpy(ctx->oiv, gcp->iv->data, len); + return -1; + } + if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set))) + { + GOST_CIPHER_PARAMS_free(gcp); + return -1; + } + memcpy(ctx->oiv, gcp->iv->data, len); -GOST_CIPHER_PARAMS_free(gcp); + GOST_CIPHER_PARAMS_free(gcp); -return 1; - -} + return 1; + } #ifdef USE_SSL -int gost_imit_init_vizir(EVP_MD_CTX *ctx) { -struct ossl_gost_imit_ctx *c = ctx->md_data; -memset(c,0,sizeof(struct ossl_gost_imit_ctx)); -gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); -return 1; -} -int gost_imit_init_cpa(EVP_MD_CTX *ctx) { -struct ossl_gost_imit_ctx *c = ctx->md_data; -memset(c,0,sizeof(struct ossl_gost_imit_ctx)); -c->key_meshing=1; -gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); -return 1; -} +int gost_imit_init_vizir(EVP_MD_CTX *ctx) + { + struct ossl_gost_imit_ctx *c = ctx->md_data; + memset(c,0,sizeof(struct ossl_gost_imit_ctx)); + gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); + return 1; + } + +int gost_imit_init_cpa(EVP_MD_CTX *ctx) + { + struct ossl_gost_imit_ctx *c = ctx->md_data; + memset(c,0,sizeof(struct ossl_gost_imit_ctx)); + c->key_meshing=1; + gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); + return 1; + } static void mac_block_mesh(struct ossl_gost_imit_ctx *c,unsigned char *data) -{ + { char buffer[8]; /* We are using local buffer for iv because CryptoPro doesn't * interpret internal state of MAC algorithm as iv during keymeshing * (but does initialize internal state from iv in key transport */ - if (c->key_meshing&& c->count && c->count %1024 ==0) { + if (c->key_meshing&& c->count && c->count %1024 ==0) + { cryptopro_key_meshing(&(c->cctx),buffer); - } + } mac_block(&(c->cctx),c->buffer,data); c->count +=8; -} + } -int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) { +int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) + { struct ossl_gost_imit_ctx *c = ctx->md_data; const unsigned char *p = data; size_t bytes = count,i; if (!(c->key_set)) return 0; - if (c->bytes_left) { - for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++) { + if (c->bytes_left) + { + for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++) + { c->partial_block[i]=*p; - } - if (i==8) { + } + if (i==8) + { mac_block_mesh(c,c->partial_block); - } else { + } + else + { c->bytes_left = i; return 1; - } - } - while (bytes>8) { + } + } + while (bytes>8) + { mac_block_mesh(c,p); p+=8; bytes-=8; - } - if (bytes>0) { + } + if (bytes>0) + { memcpy(c->partial_block,p,bytes); c->bytes_left=bytes; - } + } return 1; -} + } -int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md) { +int gost_imit_final(EVP_MD_CTX *ctx,unsigned char *md) + { struct ossl_gost_imit_ctx *c = ctx->md_data; - if (c->bytes_left) { + if (c->bytes_left) + { int i; - for (i=c->bytes_left;i<8;i++) { + for (i=c->bytes_left;i<8;i++) + { c->partial_block[i]=0; - } + } mac_block_mesh(c,c->partial_block); - } + } get_mac(c->buffer,32,md); return 1; -} -int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) { - switch (type) { - case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH: - *((unsigned int*)(ptr)) = 32; - return 1; - case EVP_MD_CTRL_SET_KEY: - { - gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ; - ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1; + } + +int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) + { + switch (type) + { + case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH: + *((unsigned int*)(ptr)) = 32; + return 1; + case EVP_MD_CTRL_SET_KEY: + { + gost_key(&(((struct ossl_gost_imit_ctx*)(ctx->md_data))->cctx),ptr) ; + ((struct ossl_gost_imit_ctx*)(ctx->md_data))->key_set = 1; } - default: - return 0; - } -} -int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) { + default: + return 0; + } + } + +int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) + { memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx)); return 1; -} + } + /* Clean up imit ctx */ -int gost_imit_cleanup(EVP_MD_CTX *ctx) { +int gost_imit_cleanup(EVP_MD_CTX *ctx) + { memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx)); return 1; - -} + } + #endif diff --git a/engines/ccgost/gost_ctl.c b/engines/ccgost/gost_ctl.c new file mode 100644 index 0000000000..e31e1f9776 --- /dev/null +++ b/engines/ccgost/gost_ctl.c @@ -0,0 +1,74 @@ +/********************************************************************** + * gost_ctl.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of control commands for GOST engine * + * OpenSSL 0.9.9 libraries required * + **********************************************************************/ +#include <stdlib.h> +#include <string.h> +#include <openssl/engine.h> +#include "gost_lcl.h" + +static char *gost_params[GOST_PARAM_MAX+1]={NULL}; +static const char *gost_envnames[]={"CRYPT_PARAMS"}; +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 + }, +{0,NULL,NULL,0} + }; + + +int gost_control_func(ENGINE *e,int cmd,long i, void *p, void (*f)(void)) + { + int param = cmd-ENGINE_CMD_BASE; + int ret=0; + if (param <0 || param >GOST_PARAM_MAX) return -1; + ret=gost_set_default_param(param,p); + return ret; + } + +const char *get_gost_engine_param(int param) + { + char *tmp; + if (param <0 || param >GOST_PARAM_MAX) return NULL; + if (gost_params[param]!=NULL) + { + return gost_params[param]; + } + tmp = getenv(gost_envnames[param]); + if (tmp) + { + gost_params[param] = strdup(tmp); + return gost_params[param]; + } + return NULL; + } + +int gost_set_default_param(int param, const char *value) + { + const char *tmp; + if (param <0 || param >GOST_PARAM_MAX) return 0; + tmp = getenv(gost_envnames[param]); + /* if there is value in the environment, use it, else -passed string * */ + if (!tmp) tmp=value; + if (gost_params[param]) free(gost_params[param]); + gost_params[param] = strdup(tmp); + + return 1; + } diff --git a/engines/ccgost/engine.c b/engines/ccgost/gost_eng.c index 757793b396..feb2a1f615 100644 --- a/engines/ccgost/engine.c +++ b/engines/ccgost/gost_eng.c @@ -1,5 +1,5 @@ /********************************************************************** - * engine.c * + * gost_eng.c * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * @@ -12,26 +12,23 @@ #include <openssl/engine.h> #include <openssl/obj_mac.h> #include "e_gost_err.h" -#include "md.h" -#include "crypt.h" -#include "meth.h" - +#include "gost_lcl.h" static const char *engine_gost_id = "gost"; static const char *engine_gost_name = "Reference implementation of GOST engine"; /* Symmetric cipher and digest function registrar */ static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); + const int **nids, int nid); static int gost_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int ind); + const int **nids, int ind); static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid); + const int **nids, int nid); static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, - const int **nids, int nid); + const int **nids, int nid); static int gost_cipher_nids[] = {NID_id_Gost28147_89, 0}; @@ -41,7 +38,7 @@ static int gost_digest_nids[] = static int gost_pkey_meth_nids[] = {NID_id_GostR3410_94_cc, NID_id_GostR3410_94, NID_id_GostR3410_2001_cc, - NID_id_GostR3410_2001, 0}; + NID_id_GostR3410_2001, 0}; static EVP_PKEY_METHOD *pmeth_GostR3410_94_cc = NULL, *pmeth_GostR3410_94 = NULL, *pmeth_GostR3410_2001_cc = NULL, *pmeth_GostR3410_2001 = NULL; @@ -50,50 +47,73 @@ static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94_cc = NULL, *ameth_GostR3410_94 = *ameth_GostR3410_2001_cc = NULL, *ameth_GostR3410_2001 = NULL; -static int gost_engine_init(ENGINE *e) { +static int gost_engine_init(ENGINE *e) + { return 1; -} -static int gost_engine_finish(ENGINE *e) { + } + +static int gost_engine_finish(ENGINE *e) + { return 1; -} + } -static int gost_engine_destroy(ENGINE *e) { +static int gost_engine_destroy(ENGINE *e) + { return 1; -} + } -static int bind_gost (ENGINE *e,const char *id) { +static int bind_gost (ENGINE *e,const char *id) + { int ret = 0; if (id && strcmp(id, engine_gost_id)) return 0; - if (!ENGINE_set_id(e, engine_gost_id)) { + if (!ENGINE_set_id(e, engine_gost_id)) + { printf("ENGINE_set_id failed\n"); goto end; - } - if (!ENGINE_set_name(e, engine_gost_name)) { + } + if (!ENGINE_set_name(e, engine_gost_name)) + { printf("ENGINE_set_name failed\n"); goto end; - } - if (!ENGINE_set_digests(e, gost_digests)) { + } + if (!ENGINE_set_digests(e, gost_digests)) + { printf("ENGINE_set_digests failed\n"); goto end; - } - if (! ENGINE_set_ciphers(e, gost_ciphers)) { + } + if (! ENGINE_set_ciphers(e, gost_ciphers)) + { printf("ENGINE_set_ciphers failed\n"); goto end; - } - if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) { + } + if (! ENGINE_set_pkey_meths(e, gost_pkey_meths)) + { printf("ENGINE_set_pkey_meths failed\n"); goto end; - } - if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) { + } + if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) + { printf("ENGINE_set_pkey_asn1_meths failed\n"); goto end; - } + } + /* Control function and commands */ + if (!ENGINE_set_cmd_defns(e,gost_cmds)) + { + fprintf(stderr,"ENGINE_set_cmd_defns failed\n"); + goto end; + } + if (!ENGINE_set_ctrl_function(e,gost_control_func)) + { + fprintf(stderr,"ENGINE_set_ctrl_func failed\n"); + goto end; + } if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy) || ! ENGINE_set_init_function(e,gost_engine_init) - || ! ENGINE_set_finish_function(e,gost_engine_finish)) goto end; - - + || ! ENGINE_set_finish_function(e,gost_engine_finish)) + { + goto end; + } if (!register_ameth_gost(NID_id_GostR3410_94_cc, &ameth_GostR3410_94_cc, "GOST94CC", "GOST R 34.10-94, Cryptocom LTD implementation")) goto end; if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end; @@ -110,13 +130,16 @@ static int bind_gost (ENGINE *e,const char *id) { /* These two actually should go in LIST_ADD command */ || ! EVP_add_cipher(&cipher_gost) || ! EVP_add_digest(&digest_gost) - ) goto end; + ) + { + goto end; + } ERR_load_GOST_strings(); ret = 1; -end: + end: return ret; -} + } #ifdef _WIN32 extern __declspec( dllexport ) @@ -131,100 +154,116 @@ extern __declspec( dllexport ) IMPLEMENT_DYNAMIC_CHECK_FN(); //#else -static ENGINE *engine_gost(void) - { - ENGINE *ret = ENGINE_new(); - if(!ret) - return NULL; - if(!bind_gost(ret, engine_gost_id)) - { - ENGINE_free(ret); - return NULL; - } - return ret; - } - -void ENGINE_load_gost(void) - { - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_gost(); - if(!toadd) return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); - } //#endif /* OPENSSL_NO_DYNAMIC_ENGINE */ static int gost_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ + const int **nids, int nid) + { int ok =1 ; - if (!digest) { + if (!digest) + { *nids = gost_digest_nids; return 1; - } - //printf("Digest no %d requested\n",nid); - if(nid == NID_id_GostR3411_94) { - *digest = &digest_gost; - } else { - ok =0; - *digest = NULL; + } + //printf("Digest no %d requested\n",nid); + if(nid == NID_id_GostR3411_94) + { + *digest = &digest_gost; + } + else + { + ok =0; + *digest = NULL; } return ok; -} + } static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher, - const int **nids, int nid) { + const int **nids, int nid) + { int ok = 1; - if (!cipher) { + if (!cipher) + { *nids = gost_cipher_nids; return 1; /* Only one cipher supported */ - } + } - if(nid == NID_id_Gost28147_89) { - *cipher = &cipher_gost; - } else { + if(nid == NID_id_Gost28147_89) + { + *cipher = &cipher_gost; + } + else + { ok = 0; *cipher = NULL; - } + } return ok; -} + } static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid) -{ - if (!pmeth) { + const int **nids, int nid) + { + if (!pmeth) + { *nids = gost_pkey_meth_nids; return 4; - } + } - switch (nid) { - case NID_id_GostR3410_94_cc: *pmeth = pmeth_GostR3410_94_cc; return 1; - case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; - case NID_id_GostR3410_2001_cc: *pmeth = pmeth_GostR3410_2001_cc; return 1; - case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; - default:; - } + switch (nid) + { + case NID_id_GostR3410_94_cc: *pmeth = pmeth_GostR3410_94_cc; return 1; + case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; + case NID_id_GostR3410_2001_cc: *pmeth = pmeth_GostR3410_2001_cc; return 1; + case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; + default:; + } *pmeth = NULL; return 0; -} + } static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, - const int **nids, int nid) -{ - if (!ameth) { + const int **nids, int nid) + { + if (!ameth) + { *nids = gost_pkey_meth_nids; return 4; - } - switch (nid) { - case NID_id_GostR3410_94_cc: *ameth = ameth_GostR3410_94_cc; return 1; - case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; - case NID_id_GostR3410_2001_cc: *ameth = ameth_GostR3410_2001_cc; return 1; - case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; - default:; - } + } + switch (nid) + { + case NID_id_GostR3410_94_cc: *ameth = ameth_GostR3410_94_cc; return 1; + case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; + case NID_id_GostR3410_2001_cc: *ameth = ameth_GostR3410_2001_cc; return 1; + case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; + default:; + } *ameth = NULL; return 0; -} + } + +#ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_gost(void) + { + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_gost(ret,engine_gost_id)) + { + ENGINE_free(ret); + return NULL; + } + return ret; + } + +void ENGINE_load_gost(void) + { + ENGINE *toadd =engine_gost(); + if (!toadd) return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } +#endif + diff --git a/engines/ccgost/keywrap.c b/engines/ccgost/gost_keywrap.c index 4e7d675a73..014499077f 100644 --- a/engines/ccgost/keywrap.c +++ b/engines/ccgost/gost_keywrap.c @@ -9,7 +9,7 @@ **********************************************************************/ #include <string.h> #include "gost89.h" -#include "keywrap.h" +#include "gost_keywrap.h" /* Diversifies key using random UserKey Material * Implements RFC 4357 p 6.5 key diversification algorithm @@ -20,31 +20,36 @@ * */ void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey) -{ + { u4 k,s1,s2; int i,j,mask; unsigned char S[8]; memcpy(outputKey,inputKey,32); - for (i=0;i<8;i++) { + for (i=0;i<8;i++) + { /* Make array of integers from key */ /* Compute IV S*/ s1=0,s2=0; - for (j=0,mask=1;j<8;j++,mask<<=1) { + for (j=0,mask=1;j<8;j++,mask<<=1) + { k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)| (outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24); - if (mask & ukm[i]) { + if (mask & ukm[i]) + { s1+=k; - } else { + } + else + { s2+=k; + } } - } S[0]=s1&0xff; S[1]=(s1>>8)&0xff; S[2]=(s1>>16)&0xff; S[3]=(s1>>24)&0xff; S[4]=s2&0xff; S[5]=(s2>>8)&0xff; S[6]=(s2>>16)&0xff; S[7]=(s2>>24)&0xff; gost_key(ctx,outputKey); gost_enc_cfb(ctx,S,outputKey,outputKey,4); - } -} + } + } /* @@ -58,7 +63,7 @@ void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const un int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm, const unsigned char *sessionKey, unsigned char *wrappedKey) -{ + { unsigned char kek_ukm[32]; keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm); gost_key(ctx,kek_ukm); @@ -66,7 +71,7 @@ int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const un gost_enc(ctx,sessionKey,wrappedKey+8,4); gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40); return 1; -} + } /* * Unwraps key using RFC 4357 6.4 * ctx - gost encryption context, initialized with some S-boxes @@ -79,19 +84,20 @@ int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const un */ int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, - const unsigned char *wrappedKey, unsigned char *sessionKey) -{ + const unsigned char *wrappedKey, unsigned char *sessionKey) + { unsigned char kek_ukm[32],cek_mac[4]; keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey - /* First 8 bytes of wrapped Key is ukm */ - ,kek_ukm); + /* First 8 bytes of wrapped Key is ukm */ + ,kek_ukm); gost_key(ctx,kek_ukm); gost_dec(ctx,wrappedKey+8,sessionKey,4); gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac); - if (memcmp(cek_mac,wrappedKey+40,4)) { - return 0; - } + if (memcmp(cek_mac,wrappedKey+40,4)) + { + return 0; + } return 1; -} + } diff --git a/engines/ccgost/keywrap.h b/engines/ccgost/gost_keywrap.h index 5553c92ff6..37c2a0f73d 100644 --- a/engines/ccgost/keywrap.h +++ b/engines/ccgost/gost_keywrap.h @@ -1,5 +1,5 @@ /********************************************************************** - * keywrap.c * + * gost_keywrap.h * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h new file mode 100644 index 0000000000..dece3b5145 --- /dev/null +++ b/engines/ccgost/gost_lcl.h @@ -0,0 +1,206 @@ +#ifndef GOST_TOOLS_H +#define GOST_TOOLS_H +/********************************************************************** + * gost_lcl.h * + * Copyright (c) 2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Internal declarations used in GOST engine * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +#include <openssl/bn.h> +#include <openssl/evp.h> +#include <openssl/dsa.h> +#include <openssl/asn1t.h> +#include <openssl/x509.h> +#include <openssl/engine.h> +#include <openssl/ec.h> +#include <unistd.h> +#include "gost89.h" +#include "gosthash.h" +/* Control commands */ +#define GOST_PARAM_CRYPT_PARAMS 0 +#define GOST_PARAM_MAX 0 +#define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) + + 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); + int gost_set_default_param(int param, const char *value); + +/* method registration */ + + int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info); + int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags); + +/* Gost-specific pmeth control-function parameters */ +#define param_ctrl_string "paramset" +#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) +/* Pmeth internal representation */ + struct gost_pmeth_data { + int sign_param_nid; /* Should be set whenever parameters are filled */ + EVP_PKEY *eph_seckey; + EVP_MD *md; + }; +/* GOST-specific ASN1 structures */ + + +typedef struct { + ASN1_OCTET_STRING *encrypted_key; + ASN1_OCTET_STRING *imit; +} GOST_KEY_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) + +typedef struct { + ASN1_OBJECT *cipher; + X509_PUBKEY *ephem_key; + ASN1_OCTET_STRING *eph_iv; +} GOST_KEY_AGREEMENT_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) + +typedef struct { + GOST_KEY_INFO *key_info; + GOST_KEY_AGREEMENT_INFO *key_agreement_info; +} GOST_KEY_TRANSPORT; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) + +typedef struct { //FIXME incomplete + GOST_KEY_TRANSPORT *gkt; +} GOST_CLIENT_KEY_EXCHANGE_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) +typedef struct { + ASN1_OBJECT *key_params; + ASN1_OBJECT *hash_params; + ASN1_OBJECT *cipher_params; +} GOST_KEY_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) + +typedef struct { + ASN1_OCTET_STRING *iv; + ASN1_OBJECT *enc_param_set; +} GOST_CIPHER_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) +/*============== Message digest and cipher related structures ==========*/ + /* Structure used as EVP_MD_CTX-md_data. + * It allows to avoid storing in the md-data pointers to + * dynamically allocated memory. + * + * I cannot invent better way to avoid memory leaks, because + * openssl insist on invoking Init on Final-ed digests, and there + * is no reliable way to find out whether pointer in the passed + * md_data is valid or not. + * */ +struct ossl_gost_digest_ctx { + gost_hash_ctx dctx; + gost_ctx cctx; +}; +/* EVP_MD structure for GOST R 34.11 */ +extern EVP_MD digest_gost; + +/* Cipher context used for EVP_CIPHER operation */ +struct ossl_gost_cipher_ctx { + int paramNID; + off_t count; + int key_meshing; + gost_ctx cctx; +}; +/* Structure to map parameter NID to S-block */ +struct gost_cipher_info { + int nid; + gost_subst_block *sblock; + int key_meshing; +}; +#ifdef USE_SSL +/* Context for MAC */ +struct ossl_gost_imit_ctx { + gost_ctx cctx; + unsigned char buffer[8]; + unsigned char partial_block[8]; + off_t count; + int key_meshing; + int bytes_left; + int key_set; +}; +#endif +/* Table which maps parameter NID to S-blocks */ +extern struct gost_cipher_info gost_cipher_list[]; +/* Find encryption params from ASN1_OBJECT */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); +/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ +extern EVP_CIPHER cipher_gost; +#ifdef USE_SSL +#define EVP_MD_FLAG_NEEDS_KEY 0x20 +#define EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH (EVP_MD_CTRL_ALG_CTRL+1) +#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+2) +/* Ciphers and MACs specific for GOST TLS draft */ +extern EVP_CIPHER cipher_gost_vizircfb; +extern EVP_CIPHER cipher_gost_cpacnt; +extern EVP_MD imit_gost_vizir; +extern EVP_MD imit_gost_cpa; +#endif +/* EVP_PKEY_METHOD key encryption callbacks */ +/* From gost94_keyx.c */ +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ); +int pkey_GOST94cc_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, size_t *outlen, const unsigned char* in, size_t in_len ); +int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * in,size_t in_len); +/* 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_GOST01cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * key,size_t key_len); + +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len ); +int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * in,size_t in_len); + +/* Internal functions to make error processing happy */ +int decrypt_cryptocom_key(unsigned char *sess_key,int max_key_len, + const unsigned char *crypted_key,int crypted_key_len, gost_ctx *ctx); +int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len, + unsigned char *crypted_key, gost_ctx *ctx); +/* Internal functions for signature algorithms */ +int fill_GOST94_params(DSA *dsa,int nid); +int fill_GOST2001_params(EC_KEY *eckey, int nid); +int gost_sign_keygen(DSA *dsa) ; +int gost2001_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); + +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 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) ; +/* Store bignum in byte array of given length, prepending by zeros + * if nesseccary */ +int store_bignum(BIGNUM *bn, unsigned char *buf,int len); +/* Read bignum, which can have few MSB all-zeros from buffer*/ +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len); +/* Pack GOST R 34.10 signature according to CryptoCom rules */ +int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen); +/* Pack GOST R 34.10 signature according to CryptoPro rules */ +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen); +/* Unpack GOST R 34.10 signature according to CryptoCom rules */ +DSA_SIG *unpack_cc_signature(const 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*/ +BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) ; +/* Find NID by GOST 94 parameters */ +int gost94_nid_by_params(DSA *p) ; + + +#endif diff --git a/engines/ccgost/md_gost.c b/engines/ccgost/gost_md.c index b0fede6d34..445679daa9 100644 --- a/engines/ccgost/md_gost.c +++ b/engines/ccgost/gost_md.c @@ -7,7 +7,7 @@ * Requires OpenSSL 0.9.9 for compilation * **********************************************************************/ #include <string.h> -#include "md.h" +#include "gost_lcl.h" #include "gosthash.h" #include "e_gost_err.h" @@ -19,51 +19,52 @@ 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_gost= -{ - NID_id_GostR3411_94, - NID_undef, - 32, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, - gost_digest_init, - gost_digest_update, - gost_digest_final, - gost_digest_copy, - gost_digest_cleanup, - NULL, - NULL, - {NID_undef,NID_undef,0,0,0}, - 32, - sizeof(struct ossl_gost_digest_ctx ), - NULL -}; + { + NID_id_GostR3411_94, + NID_undef, + 32, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, + gost_digest_init, + gost_digest_update, + gost_digest_final, + gost_digest_copy, + gost_digest_cleanup, + NULL, + NULL, + {NID_undef,NID_undef,0,0,0}, + 32, + sizeof(struct ossl_gost_digest_ctx ), + NULL + }; int gost_digest_init(EVP_MD_CTX *ctx) -{ + { struct ossl_gost_digest_ctx *c = ctx->md_data; memset(&(c->dctx),0,sizeof(gost_hash_ctx)); gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet); c->dctx.cipher_ctx= &(c->cctx); return 1; -} + } int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count) -{ + { return hash_block((gost_hash_ctx *)ctx->md_data,data,count); -} + } int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md) -{ + { return finish_hash((gost_hash_ctx *)ctx->md_data,md); -} + } int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) -{ - memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx)); - return 1; -} + { + memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx)); + return 1; + } -int gost_digest_cleanup(EVP_MD_CTX *ctx) { +int gost_digest_cleanup(EVP_MD_CTX *ctx) + { memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx)); return 1; -} + } diff --git a/engines/ccgost/params.c b/engines/ccgost/gost_params.c index 37aa23d653..40fc343af1 100644 --- a/engines/ccgost/params.c +++ b/engines/ccgost/gost_params.c @@ -7,7 +7,7 @@ * OpenSSL 0.9.9 libraries required to compile and use * * this code * **********************************************************************/ -#include "paramset.h" +#include "gost_params.h" #include <openssl/objects.h> /* Parameters of GOST 34.10 */ diff --git a/engines/ccgost/paramset.h b/engines/ccgost/gost_params.h index 002ac7857b..4c3f5567d7 100644 --- a/engines/ccgost/paramset.h +++ b/engines/ccgost/gost_params.h @@ -1,5 +1,5 @@ /********************************************************************** - * paramset.h * + * gost_params.h * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * diff --git a/engines/ccgost/pmeth.c b/engines/ccgost/gost_pmeth.c index 2698e4f937..d8f23e0639 100644 --- a/engines/ccgost/pmeth.c +++ b/engines/ccgost/gost_pmeth.c @@ -1,5 +1,5 @@ /********************************************************************** - * pmeth.c * + * gost_pmeth.c * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * @@ -13,107 +13,115 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> -#include "meth.h" -#include "pmeth.h" -#include "sign.h" -#include "gostkeyx.h" -#include "paramset.h" -#include "tools.h" +#include "gost_params.h" +#include "gost_lcl.h" #include "e_gost_err.h" /*-------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) { +static int pkey_gost_init(EVP_PKEY_CTX *ctx) + { struct gost_pmeth_data *data; data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); if (!data) return 0; memset(data,0,sizeof(struct gost_pmeth_data)); EVP_PKEY_CTX_set_data(ctx,data); return 1; -} + } + /* Copies contents of gost_pmeth_data structure */ static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ + { struct gost_pmeth_data *dst_data,*src_data; - if (!pkey_gost_init(dst)) { + if (!pkey_gost_init(dst)) + { return 0; - } + } src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); *dst_data = *src_data; - if (src_data -> eph_seckey) { + if (src_data -> eph_seckey) + { dst_data ->eph_seckey = NULL; - } + } return 1; -} + } + /* Frees up gost_pmeth_data structure */ -static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx) { +static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx) + { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey); OPENSSL_free(data); -} + } + /* --------------------- control functions ------------------------------*/ static int pkey_gost_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ + { struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) - { + { case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { - 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; - } - pctx->md = (EVP_MD *)p2; - return 1; + GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; } - break; + pctx->md = (EVP_MD *)p2; + return 1; + } + break; case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: - return 1; + return 1; case EVP_PKEY_CTRL_GOST_PARAMSET: pctx->sign_param_nid = (int)p1; - pctx->crypt_param_nid= (int)p2; return 1; - } + } return -2; -} + } -static int pkey_gost_ctrl94cc_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if(!strcmp(type, param_ctrl_string)) { +static int pkey_gost_ctrl94cc_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if(!strcmp(type, param_ctrl_string)) + { return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - NID_id_GostR3410_94_CryptoPro_A_ParamSet, - (void *)NID_id_Gost28147_89_cc); - } + NID_id_GostR3410_94_CryptoPro_A_ParamSet, + NULL); + } return -2; -} + } -static int pkey_gost_ctrl01cc_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if(!strcmp(type, param_ctrl_string)) { +static int pkey_gost_ctrl01cc_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if(!strcmp(type, param_ctrl_string)) + { return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - NID_id_GostR3410_2001_ParamSet_cc, - (void *) - NID_id_Gost28147_89_cc); - } + NID_id_GostR3410_2001_ParamSet_cc,NULL); + } return -2; -} -static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ + } + +static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { int param_nid=0; - if(!strcmp(type, param_ctrl_string)) { - if (!value) { + if(!strcmp(type, param_ctrl_string)) + { + if (!value) + { return 0; - } - if (strlen(value) == 1) { - switch(toupper(value[0])) { + } + if (strlen(value) == 1) + { + switch(toupper(value[0])) + { case 'A': param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; break; @@ -129,9 +137,12 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, default: return 0; break; + } } - } else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) { - switch (toupper(value[1])) { + else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + { + switch (toupper(value[1])) + { case 'A': param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; break; @@ -144,39 +155,48 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, default: return 0; break; + } } - } else { + else + { R3410_params *p = R3410_paramset; param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { + if (param_nid == NID_undef) + { return 0; - } - for (;p->nid != NID_undef;p++) { + } + for (;p->nid != NID_undef;p++) + { if (p->nid == param_nid) break; - } - if (p->nid == NID_undef) { + } + if (p->nid == NID_undef) + { GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, - GOST_R_INVALID_PARAMSET); + GOST_R_INVALID_PARAMSET); return 0; + } } - } - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, (void *)NID_id_Gost28147_89_CryptoPro_A_ParamSet); - } + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } return -2; -} + } -static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ +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) { + if(!strcmp(type, param_ctrl_string)) + { + if (!value) + { return 0; - } - if (strlen(value) == 1) { - switch(toupper(value[0])) { + } + if (strlen(value) == 1) + { + switch(toupper(value[0])) + { case 'A': param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet; break; @@ -192,9 +212,12 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, default: return 0; break; + } } - } else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) { - switch (toupper(value[1])) { + else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + { + switch (toupper(value[1])) + { case 'A': param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet; break; @@ -204,172 +227,198 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, default: return 0; break; + } } - } else { + else + { R3410_2001_params *p = R3410_2001_paramset; param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { + if (param_nid == NID_undef) + { return 0; - } - for (;p->nid != NID_undef;p++) { + } + for (;p->nid != NID_undef;p++) + { if (p->nid == param_nid) break; - } - if (p->nid == NID_undef) { + } + if (p->nid == NID_undef) + { GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, - GOST_R_INVALID_PARAMSET); + GOST_R_INVALID_PARAMSET); return 0; + } } - } - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, (void *)NID_id_Gost28147_89_CryptoPro_A_ParamSet); - } + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } return -2; -} + } + /* --------------------- key generation --------------------------------*/ /* Generates GOST 94 key and assigns it setting specified type */ static int pkey_gost94_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type) -{ + { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); DSA *dsa=NULL; - if (data->sign_param_nid == NID_undef) { - if (type== NID_id_GostR3410_94_cc) { + if (data->sign_param_nid == NID_undef) + { + if (type== NID_id_GostR3410_94_cc) + { data->sign_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - } else { + } + else + { GOSTerr(GOST_F_PKEY_GOST94_KEYGEN, - GOST_R_NO_PARAMETERS_SET); + GOST_R_NO_PARAMETERS_SET); return 0; - } - } + } + } dsa = DSA_new(); - if (!fill_GOST94_params(dsa,data->sign_param_nid)) { + if (!fill_GOST94_params(dsa,data->sign_param_nid)) + { DSA_free(dsa); return 0; - } + } gost_sign_keygen(dsa); EVP_PKEY_assign(pkey,type,dsa); return 1; -} + } + /* Generates Gost_R3410_94_cc key */ -static int pkey_gost94cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { +static int pkey_gost94cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94_cc); -} + } /* Generates Gost_R3410_94_cp key */ -static int pkey_gost94cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { +static int pkey_gost94cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94); -} + } + /* Generates GOST_R3410 2001 key and assigns it using specified type */ static int pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type) -{ + { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_KEY *ec=NULL; - if (data->sign_param_nid == NID_undef) { - if (type == NID_id_GostR3410_2001_cc) { + if (data->sign_param_nid == NID_undef) + { + if (type == NID_id_GostR3410_2001_cc) + { data->sign_param_nid = NID_id_GostR3410_2001_ParamSet_cc; - } else { + } + else { GOSTerr(GOST_F_PKEY_GOST01_KEYGEN, - GOST_R_NO_PARAMETERS_SET); + GOST_R_NO_PARAMETERS_SET); return 0; + } } - } ec = EC_KEY_new(); - if (!fill_GOST2001_params(ec,data->sign_param_nid)) { + if (!fill_GOST2001_params(ec,data->sign_param_nid)) + { EC_KEY_free(ec); return 0; - } + } gost2001_keygen(ec); EVP_PKEY_assign(pkey,type,ec); return 1; -} + } + /* Generates GOST R3410 2001_cc key */ -static int pkey_gost01cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { +static int pkey_gost01cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001_cc); -} + } /* Generates GOST R3410 2001_cp key */ -static int pkey_gost01cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { +static int pkey_gost01cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001); -} + } + /* ----------- sign callbacks --------------------------------------*/ static int pkey_gost94_cc_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); if (!siglen) return 0; - if (!sig) - { + 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) { + if (!unpacked_sig) + { return 0; + } + return pack_sign_cc(unpacked_sig,32,sig,siglen); } - return pack_sign_cc(unpacked_sig,32,sig,siglen); - - -} static int pkey_gost94_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); if (!siglen) return 0; - if (!sig) - { + 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) { + if (!unpacked_sig) + { return 0; - } + } return pack_sign_cp(unpacked_sig,32,sig,siglen); - - -} + } + static int pkey_gost01_cc_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); if (!siglen) return 0; - if (!sig) - { + if (!sig) + { *siglen= 64; /* better to check size of curve order*/ return 1; - } + } unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { + if (!unpacked_sig) + { return 0; - } + } return pack_sign_cc(unpacked_sig,32,sig,siglen); -} + } + static int pkey_gost01_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); if (!siglen) return 0; - if (!sig) - { + if (!sig) + { *siglen= 64; /* better to check size of curve order*/ return 1; - } + } unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { + if (!unpacked_sig) + { return 0; - } + } return pack_sign_cp(unpacked_sig,32,sig,siglen); -} + } + /* ------------------- verify callbacks ---------------------------*/ static int pkey_gost94_cc_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_cc_signature(sig,siglen); @@ -377,11 +426,11 @@ static int pkey_gost94_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); DSA_SIG_free(s); return ok; -} + } 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) -{ + { int ok = 0; EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); DSA_SIG *s=unpack_cp_signature(sig,siglen); @@ -389,10 +438,11 @@ static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); DSA_SIG_free(s); return ok; -} + } + static int pkey_gost01_cc_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_cc_signature(sig,siglen); @@ -405,11 +455,11 @@ static int pkey_gost01_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); DSA_SIG_free(s); return ok; -} + } 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) -{ + { int ok = 0; EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); DSA_SIG *s=unpack_cp_signature(sig,siglen); @@ -422,11 +472,12 @@ static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); DSA_SIG_free(s); return ok; -} + } + /* ------------- encrypt init -------------------------------------*/ /* Generates ephermeral key */ -static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) -{ +static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) + { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EVP_PKEY *eph_key = EVP_PKEY_new(); EVP_PKEY *old_key =EVP_PKEY_CTX_get0_pkey(ctx); @@ -434,46 +485,50 @@ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey); EVP_PKEY_assign(eph_key,EVP_PKEY_base_id(old_key),NULL); if (!EVP_PKEY_copy_parameters(eph_key,old_key)) return 0; - switch (EVP_PKEY_base_id(old_key)) { - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: - gost2001_keygen(EVP_PKEY_get0(eph_key)); - break; - case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: - gost_sign_keygen(EVP_PKEY_get0(eph_key)); - break; + switch (EVP_PKEY_base_id(old_key)) + { + case NID_id_GostR3410_2001: + case NID_id_GostR3410_2001_cc: + gost2001_keygen(EVP_PKEY_get0(eph_key)); + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_94_cc: + gost_sign_keygen(EVP_PKEY_get0(eph_key)); + break; - } + } data->eph_seckey=eph_key; return 1; -} + } + /* ----------------------------------------------------------------*/ -int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) { +int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) + { *pmeth = EVP_PKEY_meth_new(id, flags); if (!*pmeth) return 0; - switch (id) { + switch (id) + { case NID_id_GostR3410_94_cc: - EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94cc_str); + EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94cc_str); EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cc_keygen); EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cc_sign); EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cc_verify); - EVP_PKEY_meth_set_encrypt(*pmeth, + EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, pkey_GOST94cc_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cc_decrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cc_decrypt); break; case NID_id_GostR3410_94: EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_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, + 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_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); break; @@ -484,9 +539,9 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) { EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cc_keygen); - EVP_PKEY_meth_set_encrypt(*pmeth, + EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, pkey_GOST01cc_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cc_decrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cc_decrypt); break; /* There is intentionally no break here */ case NID_id_GostR3410_2001: @@ -496,13 +551,13 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) { EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen); - EVP_PKEY_meth_set_encrypt(*pmeth, + EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, pkey_GOST01cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); break; default: //Unsupported method return 0; - } + } EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init); EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup); @@ -510,5 +565,5 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) { //FIXME derive etc... return 1; -} + } diff --git a/engines/ccgost/gost_sign.c b/engines/ccgost/gost_sign.c index d4c9e5d3ff..126757e271 100644 --- a/engines/ccgost/gost_sign.c +++ b/engines/ccgost/gost_sign.c @@ -13,29 +13,31 @@ #include <openssl/dsa.h> #include <openssl/evp.h> -#include "sign.h" -#include "paramset.h" -#include "tools.h" +#include "gost_params.h" +#include "gost_lcl.h" #include "e_gost_err.h" -#ifdef DEBUG_SIGN -void dump_signature(const char *message,const unsigned char *buffer,size_t len) { - size_t i; - fprintf(stderr,"signature %s Length=%d",message,len); - for (i=0; i<len; i++) { - if (i% 16 ==0) fputc('\n',stderr); - fprintf (stderr," %02x",buffer[i]); +#ifdef DEBUG_SIGN +void dump_signature(const char *message,const unsigned char *buffer,size_t len) + { + size_t i; + fprintf(stderr,"signature %s Length=%d",message,len); + for (i=0; i<len; i++) + { + if (i% 16 ==0) fputc('\n',stderr); + fprintf (stderr," %02x",buffer[i]); } - fprintf(stderr,"\nEnd of signature\n"); -} + fprintf(stderr,"\nEnd of signature\n"); + } -void dump_dsa_sig(const char *message, DSA_SIG *sig) { +void dump_dsa_sig(const char *message, DSA_SIG *sig) + { fprintf(stderr,"%s\nR=",message); BN_print_fp(stderr,sig->r); fprintf(stderr,"\nS="); BN_print_fp(stderr,sig->s); fprintf(stderr,"\n"); -} + } #else @@ -46,48 +48,52 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig) { /* * Computes signature and returns it as DSA_SIG structure */ -DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) -{ +DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa) + { BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL; DSA_SIG *newsig = DSA_SIG_new(); BIGNUM *md = hashsum2bn(dgst); /* check if H(M) mod q is zero */ BN_CTX *ctx=BN_CTX_new(); BN_CTX_start(ctx); - if (!newsig) - { + if (!newsig) + { GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY); goto err; - } + } tmp=BN_CTX_get(ctx); k = BN_CTX_get(ctx); tmp2 = BN_CTX_get(ctx); BN_mod(tmp,md,dsa->q,ctx); - if (BN_is_zero(tmp)) - { + if (BN_is_zero(tmp)) + { BN_one(md); - } - do { - do { + } + do + { + do + { /*Generate random number k less than q*/ BN_rand_range(k,dsa->q); /* generate r = (a^x mod p) mod q */ BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx); if (!(newsig->r)) newsig->r=BN_new(); BN_mod(newsig->r,tmp,dsa->q,ctx); - } while (BN_is_zero(newsig->r)); + } + while (BN_is_zero(newsig->r)); /* generate s = (xr + k(Hm)) mod q */ BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx); BN_mod_mul(tmp2,k,md,dsa->q,ctx); if (!newsig->s) newsig->s=BN_new(); BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx); - } while (BN_is_zero(newsig->s)); -err: + } + while (BN_is_zero(newsig->s)); + err: BN_free(md); BN_CTX_end(ctx); BN_CTX_free(ctx); return newsig; -} + } /* @@ -95,9 +101,8 @@ err: * and frees up DSA_SIG structure */ -int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen) -{ - +int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) + { *siglen = 2*order; memset(sig,0,*siglen); store_bignum(s->r, sig,order); @@ -105,14 +110,13 @@ int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen) dump_signature("serialized",sig,*siglen); DSA_SIG_free(s); return 1; -} + } /* * Packs signature according to Cryptopro rules * and frees up DSA_SIG structure */ -int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen) -{ - +int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) + { *siglen = 2*order; memset(sig,0,*siglen); store_bignum(s->s, sig, order); @@ -120,19 +124,16 @@ int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen) dump_signature("serialized",sig,*siglen); DSA_SIG_free(s); return 1; -} - - - + } /* * Verifies signature passed as DSA_SIG structure * - */ + */ int gost_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa) -{ + DSA_SIG *sig, DSA *dsa) + { BIGNUM *md, *tmp=NULL; BIGNUM *q2=NULL; BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL; @@ -142,11 +143,11 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len, BN_CTX_start(ctx); if (BN_cmp(sig->s,dsa->q)>=1|| - BN_cmp(sig->r,dsa->q)>=1) - { - GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); - return 0; - } + BN_cmp(sig->r,dsa->q)>=1) + { + GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + return 0; + } md=hashsum2bn(dgst); tmp=BN_CTX_get(ctx); @@ -159,9 +160,10 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len, u = BN_CTX_get(ctx); BN_mod(tmp,md,dsa->q,ctx); - if (BN_is_zero(tmp)) { + if (BN_is_zero(tmp)) + { BN_one(md); - } + } BN_copy(q2,dsa->q); BN_sub_word(q2,2); BN_mod_exp(v,md,q2,dsa->q,ctx); @@ -177,44 +179,47 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len, BN_free(md); BN_CTX_end(ctx); BN_CTX_free(ctx); - if (ok!=0) { + if (ok!=0) + { GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH); - } + } return (ok==0); -} + } /* * Computes public keys for GOST R 34.10-94 algorithm - * + * */ int gost94_compute_public(DSA *dsa) -{ + { /* Now fill algorithm parameters with correct values */ BN_CTX *ctx = BN_CTX_new(); - if (!dsa->g) { + if (!dsa->g) + { GOSTerr(GOST_F_GOST_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED); return 0; - } + } /* Compute public key y = a^x mod p */ dsa->pub_key=BN_new(); BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx); BN_CTX_free(ctx); return 1; -} + } /* * Fill GOST 94 params, searching them in R3410_paramset array * by nid of paramset - * - */ -int fill_GOST94_params(DSA *dsa,int nid) { + * + */ +int fill_GOST94_params(DSA *dsa,int nid) + { R3410_params *params=R3410_paramset; while (params->nid!=NID_undef && params->nid !=nid) params++; - if (params->nid == NID_undef) - { + if (params->nid == NID_undef) + { GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET); return 0; - } + } #define dump_signature(a,b,c) if (dsa->p) { BN_free(dsa->p); } dsa->p=NULL; @@ -226,77 +231,90 @@ int fill_GOST94_params(DSA *dsa,int nid) { dsa->g=NULL; BN_dec2bn(&(dsa->g),params->a); return 1; -} + } /* * Generate GOST R 34.10-94 keypair - * * - */ -int gost_sign_keygen(DSA *dsa) -{ + * + */ +int gost_sign_keygen(DSA *dsa) + { dsa->priv_key = BN_new(); BN_rand_range(dsa->priv_key,dsa->q); return gost94_compute_public( dsa); -} + } + /* Unpack signature according to cryptocom rules */ -DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen) -{ +DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen) + { DSA_SIG *s; s = DSA_SIG_new(); - if (s == NULL) { + if (s == NULL) + { GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY); return(NULL); - } + } s->r = getbnfrombuf(sig, siglen/2); s->s = getbnfrombuf(sig + siglen/2, siglen/2); return s; -} + } + /* Unpack signature according to cryptopro rules */ -DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) -{ +DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) + { DSA_SIG *s; s = DSA_SIG_new(); - if (s == NULL) { + if (s == NULL) + { GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY); return NULL; - } + } s->s = getbnfrombuf(sig , siglen/2); s->r = getbnfrombuf(sig + siglen/2, siglen/2); return s; -} + } + /* Convert little-endian byte array into bignum */ -BIGNUM *hashsum2bn(const unsigned char *dgst) -{ unsigned char buf[32]; - int i; - for (i=0;i<32;i++) { - buf[31-i]=dgst[i]; - } - return getbnfrombuf(buf,32); -} +BIGNUM *hashsum2bn(const unsigned char *dgst) + { + unsigned char buf[32]; + int i; + for (i=0;i<32;i++) + { + buf[31-i]=dgst[i]; + } + return getbnfrombuf(buf,32); + } /* Convert byte buffer to bignum, skipping leading zeros*/ -BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len) { - while (*buf==0&&len>0) { +BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len) + { + while (*buf==0&&len>0) + { buf++; len--; - } - if (len) { + } + if (len) + { return BN_bin2bn(buf,len,NULL); - } else { + } + else + { BIGNUM *b=BN_new(); BN_zero(b); return b; + } } -} + /* 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 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; -} - + } diff --git a/engines/ccgost/gosthash.c b/engines/ccgost/gosthash.c index 5978dbabaa..1acd16317b 100644 --- a/engines/ccgost/gosthash.c +++ b/engines/ccgost/gosthash.c @@ -28,60 +28,64 @@ /* Following functions are various bit meshing routines used in * GOST R 34.11-94 algorithms */ static void swap_bytes (byte *w, byte *k) -{ + { int i,j; for (i=0;i<4;i++) for (j=0;j<8;j++) k[i+4*j]=w[8*i+j]; -} + } + /* was A_A */ static void circle_xor8 (const byte *w, byte *k) -{ + { byte buf[8]; int i; memcpy(buf,w,8); memcpy(k,w+8,24); for(i=0;i<8;i++) k[i+24]=buf[i]^k[i]; -} + } + /* was R_R */ static void transform_3 (byte *data) -{ + { unsigned short int acc; acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])| ((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8); memmove(data,data+2,30); data[30]=acc&0xff; data[31]=acc>>8; -} + } /* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ static int add_blocks(int n,byte *left, const byte *right) -{ - int i; - int carry=0; - int sum; - for (i=0;i<n;i++) - { + { + int i; + int carry=0; + int sum; + for (i=0;i<n;i++) + { sum=(int)left[i]+(int)right[i]+carry; left[i]=sum & 0xff; carry=sum>>8; - } - return carry; -} + } + return carry; + } + /* Xor two sequences of bytes */ -static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len) { +static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len) + { size_t i; for (i=0;i<len;i++) result[i]=a[i]^b[i]; -} + } /* * Calculate H(i+1) = Hash(Hi,Mi) * Where H and M are 32 bytes long */ static int hash_step(gost_ctx *c,byte *H,const byte *M) -{ + { static byte U[32],W[32],V[32],S[32],Key[32]; int i; /* Compute first key */ @@ -126,20 +130,23 @@ static int hash_step(gost_ctx *c,byte *H,const byte *M) transform_3(S); memcpy(H,S,32); return 1; -} + } /* Initialize gost_hash ctx - cleans up temporary structures and * set up substitution blocks */ -int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block) { +int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block) + { memset(ctx,0,sizeof(gost_hash_ctx)); ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx)); - if (!ctx->cipher_ctx) { - return 0; - } + if (!ctx->cipher_ctx) + { + return 0; + } gost_init(ctx->cipher_ctx,subst_block); return 1; -} + } + /* * Free cipher CTX if it is dynamically allocated. Do not use * if cipher ctx is statically allocated as in OpenSSL implementation of @@ -147,86 +154,77 @@ int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block) * */ void done_gost_hash_ctx(gost_hash_ctx *ctx) -{ + { /* No need to use gost_destroy, because cipher keys are not really * secret when hashing */ MYFREE(ctx->cipher_ctx); -} + } + /* * reset state of hash context to begin hashing new message */ -int start_hash(gost_hash_ctx *ctx) { +int start_hash(gost_hash_ctx *ctx) + { if (!ctx->cipher_ctx) return 0; memset(&(ctx->H),0,32); memset(&(ctx->S),0,32); ctx->len = 0L; ctx->left=0; return 1; -} + } + /* * Hash block of arbitrary length * * */ -int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length) { +int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length) + { const byte *curptr=block; const byte *barrier=block+(length-32);/* Last byte we can safely hash*/ - gost_ctx *save_c = ctx->cipher_ctx; - if (ctx->left) { + if (ctx->left) + { /*There are some bytes from previous step*/ int add_bytes = 32-ctx->left; - if (add_bytes>length) { + if (add_bytes>length) + { add_bytes = length; - } + } memcpy(&(ctx->remainder[ctx->left]),block,add_bytes); ctx->left+=add_bytes; - if (ctx->left<32) { + if (ctx->left<32) + { return 1; - } - if (ctx->left>32) { - abort(); - } + } curptr=block+add_bytes; hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder); - if (save_c!=ctx->cipher_ctx) { - abort(); - } add_blocks(32,ctx->S,ctx->remainder); - if (save_c!=ctx->cipher_ctx) { - abort(); - } ctx->len+=32; ctx->left=0; - } + } while (curptr<=barrier) - { + { hash_step(ctx->cipher_ctx,ctx->H,curptr); - if (save_c!=ctx->cipher_ctx) { - abort(); - } add_blocks(32,ctx->S,curptr); - if (save_c!=ctx->cipher_ctx) { - abort(); - } ctx->len+=32; curptr+=32; - } - if (curptr!=block+length) { - ctx->left=block+length-curptr; - if (ctx->left>32) { - abort(); } + if (curptr!=block+length) + { + ctx->left=block+length-curptr; memcpy(ctx->remainder,curptr,ctx->left); - } + } return 1; -} + } + /* * Compute hash value from current state of ctx * state of hash ctx becomes invalid and cannot be used for further * hashing. */ -int finish_hash(gost_hash_ctx *ctx,byte *hashval) { +int finish_hash(gost_hash_ctx *ctx,byte *hashval) + { byte buf[32]; byte H[32]; byte S[32]; @@ -234,23 +232,25 @@ int finish_hash(gost_hash_ctx *ctx,byte *hashval) { byte *bptr; memcpy(H,ctx->H,32); memcpy(S,ctx->S,32); - if (ctx->left) { + if (ctx->left) + { memset(buf,0,32); memcpy(buf,ctx->remainder,ctx->left); hash_step(ctx->cipher_ctx,H,buf); add_blocks(32,S,buf); fin_len+=ctx->left; - } + } memset(buf,0,32); bptr=buf; fin_len<<=3; /* Hash length in BITS!!*/ - while(fin_len>0) { + while(fin_len>0) + { *(bptr++)=fin_len&0xFF; fin_len>>=8; - }; + }; hash_step(ctx->cipher_ctx,H,buf); hash_step(ctx->cipher_ctx,H,S); memcpy(hashval,H,32); return 1; -} + } diff --git a/engines/ccgost/gosthash.h b/engines/ccgost/gosthash.h index d9889cae2d..bd26aeb276 100644 --- a/engines/ccgost/gosthash.h +++ b/engines/ccgost/gosthash.h @@ -1,5 +1,5 @@ /********************************************************************** - * gosthash.c * + * gosthash.h * * Copyright (c) 2005-2006 Cryptocom LTD * * This file is distributed under the same license as OpenSSL * * * diff --git a/engines/ccgost/gostkeyx.h b/engines/ccgost/gostkeyx.h deleted file mode 100644 index 56fc6a2372..0000000000 --- a/engines/ccgost/gostkeyx.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef GOSTKEYX_H -#define GOSTKEYX_H -/********************************************************************** - * gostkeyx.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of the key transport functions for GOST pkey methods * - * * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include <openssl/evp.h> -#include "gost89.h" -/* EVP_PKEY_METHOD callbacks */ -/* From gost94_keyx.c */ -int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* key, size_t key_len ); -int pkey_GOST94cc_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, size_t *outlen, const unsigned char* in, size_t in_len ); -int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * in,size_t in_len); -/* 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_GOST01cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * key,size_t key_len); - -int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len ); -int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char * in,size_t in_len); - -/* Internal functions to make error processing happy */ -int decrypt_cryptocom_key(unsigned char *sess_key,int max_key_len, - const unsigned char *crypted_key,int crypted_key_len, gost_ctx *ctx); -int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len, - unsigned char *crypted_key, gost_ctx *ctx); -/*int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh) ;*/ -/* - * Computes 256 bit key exchange key for CryptoCom variation of GOST 94 - * algorithm - *//* -int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key) ; -DH *make_ephemeral_key(EVP_PKEY *pubk,BIGNUM *ephemeral_key); -int make_cp_exchange_key(DH *dh,EVP_PKEY *pubk, unsigned char *shared_key); -*/ -#endif diff --git a/engines/ccgost/gostsum.1 b/engines/ccgost/gostsum.1 deleted file mode 100644 index 3dfd7e40d0..0000000000 --- a/engines/ccgost/gostsum.1 +++ /dev/null @@ -1,78 +0,0 @@ -.\" Hey, Emacs! This is an -*- nroff -*- source file. -.TH MD5SUM 1 "29th November 1995" "Lankester et al." "Debian GNU/Linux" -.SH NAME -gostsum \- generates or checks GOST R34.11-94 message digests - -.SH SYNOPSIS -.B gostsum -[\-bv] [\-c [file]] | [file...] - -.SH DESCRIPTION -.B gostsum -generates or checks GOST hash sums. The algorithm to generate the -is reasonably fast and strong enough for most cases. Exact -specification of the algorithm is in -.I GOST R34.11-94. - -Normally -.B gostsum -generates checksums of all files given to it as a parameter and prints -the checksums followed by the filenames. If, however, -.B \-c -is specified, only one filename parameter is allowed. This file should -contain checksums and filenames to which these checksums refer to, and -the files listed in that file are checked against the checksums listed -there. See option -.B \-c -for more information. - -.SS OPTIONS -.TP -.B \-b -Use binary mode. In unix environment, only difference between this and -the normal mode is an asterisk preceding the filename in the output. -.TP -.B \-c -Check md5sum of all files listed in -.I file -against the checksum listed in the same file. The actual format of that -file is the same as output of -.B md5sum. -That is, each line in the file describes a file. A line looks like: - -.B <hashsum> <filename> - -So, for example, if a file was created and its message digest calculated -like so: - -.B echo foo > hash\-test\-file; gost5sum hash\-test\-file - -.B gost5sum -would report: - -.B d3b07384d113edec49eaa6238ad5ff00\ md5\-test\-file - -.TP -.B \-v -Be more verbose. Print filenames when checking (with \-c). - -.TP -.B -t -Use test parameter set. -.B gostsum supports two sets of parameters (which are really parameters -of GOST 28147-89 block cipher) specified in the IETF draft -.B draft-popov-cryptopro-cpalgs-02.txt -By default, cryptopro paramset is used. This option enables use of test -paramset as specified in appendices to the GOST. - -.SH BUGS - -This manpage is not quite accurate and has formatting inconsistent -with other manpages. - -.B gostsum -does not accept standard options like -.BR \-\-help . - -.SH AUTHOR - diff --git a/engines/ccgost/gostsum.c b/engines/ccgost/gostsum.c index 92bd5f9419..d57112eb54 100644 --- a/engines/ccgost/gostsum.c +++ b/engines/ccgost/gostsum.c @@ -5,8 +5,8 @@ * * * Almost drop-in replacement for md5sum and sha1sum * * which computes GOST R 34.11-94 hashsum instead * - * * - **********************************************************************/ + * * + **********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -18,24 +18,24 @@ int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode); int hash_stream(gost_hash_ctx *ctx,int fd, char *sum); int get_line(FILE *f,char *hash,char *filename); -void help() -{ +void help() + { fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n" - "\t-c check message digests (default is generate)\n" - "\t-v verbose, print file names when checking\n" - "\t-b read files in binary mode\n" - "\t-t use test GOST paramset (default is CryptoPro paramset)\n" -"The input for -c should be the list of message digests and file names\n" -"that is printed on stdout by this program when it generates digests.\n"); -exit(3); -} + "\t-c check message digests (default is generate)\n" + "\t-v verbose, print file names when checking\n" + "\t-b read files in binary mode\n" + "\t-t use test GOST paramset (default is CryptoPro paramset)\n" + "The input for -c should be the list of message digests and file names\n" + "that is printed on stdout by this program when it generates digests.\n"); + exit(3); + } #ifndef O_BINARY #define O_BINARY 0 #endif -int main(int argc,char **argv) -{ +int main(int argc,char **argv) + { int c,i; int verbose=0; int errors=0; @@ -44,141 +44,167 @@ int main(int argc,char **argv) FILE *check_file = NULL; gost_hash_ctx ctx; - while( (c=getopt(argc,argv,"bc::tv"))!=-1) - { - switch (c) + while( (c=getopt(argc,argv,"bc::tv"))!=-1) { - case 'v': verbose=1; break; - case 't': b= &GostR3411_94_TestParamSet; break; - case 'b': open_mode |= O_BINARY; break; - case 'c': if (optarg) { + switch (c) + { + case 'v': verbose=1; break; + case 't': b= &GostR3411_94_TestParamSet; break; + case 'b': open_mode |= O_BINARY; break; + case 'c': + if (optarg) + { check_file = fopen(optarg,"r"); - if (!check_file) { + if (!check_file) + { perror(optarg); exit(2); + } } - } else { + else + { check_file= stdin; - } - break; - default: + } + break; + default: fprintf(stderr,"invalid option %c",optopt); help(); + } } - } init_gost_hash_ctx(&ctx,b); - if (check_file) - { + if (check_file) + { char inhash[65],calcsum[65],filename[PATH_MAX]; int failcount=0,count=0;; - if (check_file==stdin && optind<argc) - { + if (check_file==stdin && optind<argc) + { check_file=fopen(argv[optind],"r"); - if (!check_file) - { + if (!check_file) + { perror(argv[optind]); exit(2); - } - } - while (get_line(check_file,inhash,filename)) - { - if (!hash_file(&ctx,filename,calcsum,open_mode)) { - exit (2); + } } - count++; - if (!strncmp(calcsum,inhash,65)) + while (get_line(check_file,inhash,filename)) { - if (verbose) { + if (!hash_file(&ctx,filename,calcsum,open_mode)) + { + exit (2); + } + count++; + if (!strncmp(calcsum,inhash,65)) + { + if (verbose) + { fprintf(stderr,"%s\tOK\n",filename); + } } - } else { - if (verbose) { + else + { + if (verbose) + { fprintf(stderr,"%s\tFAILED\n",filename); - } else { + } + else + { fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n", - argv[0],filename); - } + argv[0],filename); + } failcount++; + } } - } - if (verbose && failcount) { + if (verbose && failcount) + { fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n", - argv[0],failcount,count); - } + argv[0],failcount,count); + } exit (failcount?1:0); - } - if (optind==argc) { + } + if (optind==argc) + { char sum[65]; - if (!hash_stream(&ctx,fileno(stdin),sum)) { + if (!hash_stream(&ctx,fileno(stdin),sum)) + { perror("stdin"); exit(1); - } + } printf("%s -\n",sum); exit(0); - } - for (i=optind;i<argc;i++) { + } + for (i=optind;i<argc;i++) + { char sum[65]; - if (!hash_file(&ctx,argv[i],sum,open_mode)) { + if (!hash_file(&ctx,argv[i],sum,open_mode)) + { errors++; - } else { + } + else + { printf("%s %s\n",sum,argv[i]); - } - } + } + } exit(errors?1:0); -} + } -int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode) -{ +int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode) + { int fd; - if ((fd=open(filename,mode))<0) { + if ((fd=open(filename,mode))<0) + { perror(filename); return 0; - } - if (!hash_stream(ctx,fd,sum)) { + } + if (!hash_stream(ctx,fd,sum)) + { perror(filename); return 0; - } + } close(fd); return 1; -} + } -int hash_stream(gost_hash_ctx *ctx,int fd, char *sum) -{ +int hash_stream(gost_hash_ctx *ctx,int fd, char *sum) + { unsigned char buffer[BUF_SIZE]; ssize_t bytes; int i; start_hash(ctx); - while ((bytes=read(fd,buffer,BUF_SIZE))>0) { + while ((bytes=read(fd,buffer,BUF_SIZE))>0) + { hash_block(ctx,buffer,bytes); - } - if (bytes<0) { + } + if (bytes<0) + { return 0; - } + } finish_hash(ctx,buffer); - for (i=0;i<32;i++) { - sprintf(sum+2*i,"%02x",buffer[31-i]); - } + for (i=0;i<32;i++) + { + sprintf(sum+2*i,"%02x",buffer[31-i]); + } return 1; -} + } -int get_line(FILE *f,char *hash,char *filename) { +int get_line(FILE *f,char *hash,char *filename) + { int i; if (fread(hash,1,64,f)<64) return 0; hash[64]=0; - for (i=0;i<64;i++) - { + for (i=0;i<64;i++) + { if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F' - && hash[i]<'a')||hash[i]>'f') - { + && hash[i]<'a')||hash[i]>'f') + { fprintf(stderr,"Not a hash value '%s'\n",hash); return 0; - } - } - if (fgetc(f)!=' ') { + } + } + if (fgetc(f)!=' ') + { fprintf(stderr,"Malformed input line\n"); return 0; - } + } i=strlen(fgets(filename,PATH_MAX,f)); while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0; return 1; -} + } diff --git a/engines/ccgost/md.h b/engines/ccgost/md.h deleted file mode 100644 index 7cf0af2a6b..0000000000 --- a/engines/ccgost/md.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef GOST_MD_H -#define GOST_MD_H -/********************************************************************** - * md.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of GOST R 34.11 bindings to OpenSSL * - * * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include <unistd.h> -#include <openssl/err.h> -#include <openssl/evp.h> -#include "gost89.h" -#include "gosthash.h" -#ifdef __cplusplus - extern "C" { -#endif - - /* Structure used as EVP_MD_CTX-md_data. - * It allows to avoid storing in the md-data pointers to - * dynamically allocated memory. - * - * I cannot invent better way to avoid memory leaks, because - * openssl insist on invoking Init on Final-ed digests, and there - * is no reliable way to find out whether pointer in the passed - * md_data is valid or not. - * */ -struct ossl_gost_digest_ctx { - gost_hash_ctx dctx; - gost_ctx cctx; -}; - -extern EVP_MD digest_gost; - - -#ifdef __cplusplus - }; -#endif -#endif diff --git a/engines/ccgost/meth.h b/engines/ccgost/meth.h deleted file mode 100644 index 863046648c..0000000000 --- a/engines/ccgost/meth.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CCE_METH_H -#define CCE_METH_H -/********************************************************************** - * meth.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of method registration functions * - * * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info); - int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags); -#ifdef __cplusplus - }; -#endif - -#endif diff --git a/engines/ccgost/pmeth.h b/engines/ccgost/pmeth.h deleted file mode 100644 index a94f778f09..0000000000 --- a/engines/ccgost/pmeth.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef GOST_PMETH_H -#define GOST_PMETH_H -/********************************************************************** - * pmeth.h * - * Copyright (c) 2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of GOST PKEY context internal data * - * * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include <openssl/bn.h> -#include <openssl/evp.h> - -/* Gost-specific control-function parameters */ -#define param_ctrl_string "paramset" -#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) - - struct gost_pmeth_data { - int sign_param_nid; /* Should be set whenever parameters are filled */ - int crypt_param_nid; - EVP_PKEY *eph_seckey; - EVP_MD *md; - }; - -#endif diff --git a/engines/ccgost/sign.h b/engines/ccgost/sign.h deleted file mode 100644 index c697c4fedb..0000000000 --- a/engines/ccgost/sign.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef GOST_SIGN_H -#define GOST_SIGN_H -/********************************************************************** - * sign.h * - * Copyright (c) 2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of internal funtions implementing GOST R 34.10 * - * signature and key generation * - * OpenSSL 0.9.9 libraries required to compile and use * - * this code * - **********************************************************************/ -#include <openssl/evp.h> -#include <openssl/dsa.h> -#include <openssl/ec.h> -int fill_GOST94_params(DSA *dsa,int nid); -int fill_GOST2001_params(EC_KEY *eckey, int nid); -int gost_sign_keygen(DSA *dsa) ; -int gost2001_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); - -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 gost94_compute_public(DSA *dsa) ; -#endif diff --git a/engines/ccgost/tools.h b/engines/ccgost/tools.h deleted file mode 100644 index db3d6089f3..0000000000 --- a/engines/ccgost/tools.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef GOST_TOOLS_H -#define GOST_TOOLS_H -/********************************************************************** - * sign.h * - * Copyright (c) 2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Miscellaneous functions used in GOST engine * - * OpenSSL 0.9.9 libraries required to compile and use * - * this code * - **********************************************************************/ -#include <openssl/evp.h> -#include <openssl/dsa.h> - -/* from gost_sign.c */ -/* Convert GOST R 34.11 hash sum to bignum according to standard */ -BIGNUM *hashsum2bn(const unsigned char *dgst) ; -/* Store bignum in byte array of given length, prepending by zeros - * if nesseccary */ -int store_bignum(BIGNUM *bn, unsigned char *buf,int len); -/* Read bignum, which can have few MSB all-zeros from buffer*/ -BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len); -/* Pack GOST R 34.10 signature according to CryptoCom rules */ -int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen); -/* Pack GOST R 34.10 signature according to CryptoPro rules */ -int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen); -/* Unpack GOST R 34.10 signature according to CryptoCom rules */ -DSA_SIG *unpack_cc_signature(const 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*/ -BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey) ; -/* Find NID by GOST 94 parameters */ -int gost94_nid_by_params(DSA *p) ; - - -#endif |