Updated version of gost engine.
This commit is contained in:
parent
1182301ca7
commit
926c41bd29
@ -1,122 +1,269 @@
|
|||||||
# OPENSSL_DIR is a root directory of openssl sources
|
DIR=ccgost
|
||||||
THISDIR?=$(shell perl -MCwd -e 'print getcwd')
|
TOP=../..
|
||||||
OPENSSL_DIR?=$(THISDIR)/../openssl
|
CC=cc
|
||||||
ENGINE_ID?=gost
|
INCLUDES= -I../../include
|
||||||
TESTSUITE_DIR?=$(THISDIR)/test-suite
|
CFLAG=-g
|
||||||
FOR?=$(HOST)
|
MAKEFILE= Makefile
|
||||||
CC=gcc
|
AR= ar r
|
||||||
CFLAGS=-fPIC -g -Wall -I$(OPENSSL_DIR)/include
|
CFLAGS= $(INCLUDES) $(CFLAG)
|
||||||
LDFLAGS=-g -L $(OPENSSL_DIR) -static-libgcc
|
LIB=$(TOP)/libcrypto.a
|
||||||
ifeq "$(FOR)" "s64"
|
|
||||||
CFLAGS+=-m64
|
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
|
||||||
LDFLAGS+=-m64
|
|
||||||
endif
|
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
|
||||||
OS:=$(shell uname -s)
|
|
||||||
ifeq "$(OS)" "FreeBSD"
|
SRC=$(LIBSRC)
|
||||||
LIBDIR:=$(shell LD_LIBRARY_PATH=$(OPENSSL_DIR) $(OPENSSL_DIR)/apps/openssl version -d|sed -e 's/^[^"]*"//' -e 's/".*$$//')/lib
|
|
||||||
LDFLAGS+=-rpath $(LIBDIR)
|
LIBNAME=gost
|
||||||
endif
|
|
||||||
|
top:
|
||||||
|
(cd $(TOP); $(MAKE) DIRS=engines EDIRS=$(DIR) sub_all)
|
||||||
|
|
||||||
|
all: lib
|
||||||
|
|
||||||
|
tags:
|
||||||
|
ctags $(SRC)
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
tests:
|
||||||
|
|
||||||
|
depend:
|
||||||
|
@if [ -z "$(THIS)" ]; then \
|
||||||
|
$(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
|
||||||
|
else \
|
||||||
|
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
files:
|
||||||
|
|
||||||
|
|
||||||
ifeq "$(FOR)" "w32"
|
|
||||||
ENGINE_LIB?=$(ENGINE_ID)$(DLLSUFFIX)
|
lint:
|
||||||
DLLSUFFIX=.dll
|
lint -DLINT $(INCLUDES) $(SRC)>fluff
|
||||||
EXESUFFIX=.exe
|
|
||||||
CFLAGS+=-mno-cygwin
|
dclean:
|
||||||
LDFLAGS+=-mno-cygwin
|
$(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
|
||||||
ifeq "$(OS)" "Linux"
|
mv -f Makefile.new $(MAKEFILE)
|
||||||
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:
|
clean:
|
||||||
rm -f core gosttest gostsum *.o gost_test openssl.cnf* $(ENGINE_LIB)
|
rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff *.so *.sl *.dll
|
||||||
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)
|
|
||||||
|
|
||||||
tests: openssl.cnf.2
|
# DO NOT DELETE THIS LINE -- make depend depends on it.
|
||||||
OPENSSL_DIR=$(OPENSSL_DIR) $(MAKE) -C $(TESTSUITE_DIR) CONFADD=$(THISDIR)/openssl.cnf.2
|
|
||||||
|
|
||||||
# depedencies
|
|
||||||
#
|
|
||||||
#
|
|
||||||
gost_sign.o: gost_sign.c sign.h paramset.h tools.h e_gost_err.h
|
|
||||||
|
|
||||||
pmeth.o: pmeth.c meth.h pmeth.h sign.h paramset.h e_gost_err.h
|
|
||||||
|
|
||||||
ameth.o: ameth.c tools.h meth.h pmeth.h gost_asn1.h crypt.h e_gost_err.h paramset.h
|
|
||||||
|
|
||||||
keywrap.o: keywrap.c gost89.h keywrap.h
|
|
||||||
|
|
||||||
gost2001.o: gost2001.c tools.h sign.h paramset.h e_gost_err.h
|
|
||||||
|
|
||||||
engine.o: engine.c md.h crypt.h meth.h e_gost_err.h
|
|
||||||
|
|
||||||
|
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
|
gost89.o: gost89.c gost89.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h
|
||||||
gost_asn1.o: gost_asn1.c gost_asn1.h
|
gost94_keyx.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
|
||||||
gost_crypt.o: gost_crypt.c crypt.h gost89.h e_gost_err.h gost_asn1.h
|
gost94_keyx.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
|
||||||
gosthash.o: gosthash.c gost89.h gosthash.h
|
gost94_keyx.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/engine.h ../../include/openssl/evp.h
|
||||||
md_gost.o: md_gost.c md.h gosthash.h e_gost_err.h
|
gost94_keyx.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/objects.h
|
||||||
params.o: params.c paramset.h
|
gost94_keyx.o: ../../include/openssl/opensslconf.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/opensslv.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
|
gost94_keyx.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
|
||||||
|
gost94_keyx.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
|
||||||
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
|
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
|
||||||
|
@ -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
|
|
@ -70,86 +70,86 @@
|
|||||||
|
|
||||||
static ERR_STRING_DATA GOST_str_functs[]=
|
static ERR_STRING_DATA GOST_str_functs[]=
|
||||||
{
|
{
|
||||||
{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"},
|
{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_DECRYPT_CRYPTOCOM_KEY), "decrypt_cryptocom_key"},
|
||||||
{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"},
|
{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_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"},
|
||||||
{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_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_GET_ENCRYPTION_PARAMS), "get_encryption_params"},
|
||||||
{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"},
|
{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_SIGN), "GOST2001_DO_SIGN"},
|
||||||
{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"},
|
{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_GET_ASN1_PARAMETERS), "gost89_get_asn1_parameters"},
|
||||||
{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "gost89_set_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_GOST94_COPY_PARAMETERS), "GOST94_COPY_PARAMETERS"},
|
||||||
{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "gost_cipher_ctl"},
|
{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_COMPUTE_PUBLIC), "GOST_COMPUTE_PUBLIC"},
|
||||||
{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"},
|
{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"},
|
||||||
{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"},
|
{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"},
|
||||||
{ERR_FUNC(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001), "MAKE_RFC4490_KEYTRANSPORT_2001"},
|
{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_GOST01), "PARAM_COPY_GOST01"},
|
||||||
{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"},
|
{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_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_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_DECRYPT), "pkey_GOST01cc_decrypt"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST01CC_ENCRYPT), "pkey_GOST01cc_encrypt"},
|
{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_GOST01CP_ENCRYPT), "pkey_GOST01cp_encrypt"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST01_KEYGEN), "PKEY_GOST01_KEYGEN"},
|
{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_DECRYPT), "pkey_GOST94cc_decrypt"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST94CC_ENCRYPT), "pkey_GOST94cc_encrypt"},
|
{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_DECRYPT), "pkey_GOST94cp_decrypt"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "pkey_GOST94cp_encrypt"},
|
{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_GOST94_KEYGEN), "PKEY_GOST94_KEYGEN"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"},
|
{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_CTRL01_STR), "PKEY_GOST_CTRL01_STR"},
|
||||||
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_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_PRIV_DECODE_GOST_94), "PRIV_DECODE_GOST_94"},
|
||||||
{ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"},
|
{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_DECODE_GOST94), "PUB_DECODE_GOST94"},
|
||||||
{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"},
|
{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_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"},
|
||||||
{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
|
{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
static ERR_STRING_DATA GOST_str_reasons[]=
|
static ERR_STRING_DATA GOST_str_reasons[]=
|
||||||
{
|
{
|
||||||
{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
|
{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_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
|
||||||
{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
|
{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_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_MAC) ,"error computing mac"},
|
||||||
{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
|
{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_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_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_ENCRYPTED_KEY),"error storing encrypted key"},
|
||||||
{ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"},
|
{ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"},
|
||||||
{ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"},
|
{ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"},
|
||||||
{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
|
{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
|
||||||
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"},
|
{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_CIPHER_PARAM_OID),"invalid cipher param oid"},
|
||||||
{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
|
{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_ENCRYPTED_KEY_SIZE),"invalid encrypted key size"},
|
||||||
{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"},
|
{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_IV_LENGTH) ,"invalid iv length"},
|
||||||
{ERR_REASON(GOST_R_INVALID_PARAMSET) ,"invalid paramset"},
|
{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_INITALIZED),"key is not initalized"},
|
||||||
{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
|
{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_KEY_PARAMETERS_MISSING),"key parameters missing"},
|
||||||
{ERR_REASON(GOST_R_MALLOC_FAILURE) ,"malloc failure"},
|
{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_NOT_ENOUGH_SPACE_FOR_KEY),"not enough space for key"},
|
||||||
{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"},
|
{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"},
|
||||||
{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"},
|
{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"},
|
||||||
{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
|
{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_ERROR),"random generator error"},
|
||||||
{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"},
|
{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_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_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_MISMATCH) ,"signature mismatch"},
|
||||||
{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
|
{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_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"},
|
||||||
{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
|
{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -157,8 +157,8 @@ static ERR_STRING_DATA GOST_str_reasons[]=
|
|||||||
#ifdef GOST_LIB_NAME
|
#ifdef GOST_LIB_NAME
|
||||||
static ERR_STRING_DATA GOST_lib_name[]=
|
static ERR_STRING_DATA GOST_lib_name[]=
|
||||||
{
|
{
|
||||||
{0 ,GOST_LIB_NAME},
|
{0 ,GOST_LIB_NAME},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
* Implementation of GOST R 34.10-2001 *
|
* Implementation of GOST R 34.10-2001 *
|
||||||
* Requires OpenSSL 0.9.9 for compilation *
|
* Requires OpenSSL 0.9.9 for compilation *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#include "tools.h"
|
#include "gost_lcl.h"
|
||||||
#include "sign.h"
|
#include "gost_params.h"
|
||||||
#include "paramset.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include <openssl/ecdsa.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
|
* Also fils DSA->q field with copy of EC_GROUP order field to make
|
||||||
* DSA_size function work
|
* 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;
|
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;
|
BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
|
||||||
EC_POINT *P=NULL;
|
EC_POINT *P=NULL;
|
||||||
BN_CTX *ctx=BN_CTX_new();
|
BN_CTX *ctx=BN_CTX_new();
|
||||||
@ -48,7 +48,8 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid) {
|
|||||||
y=BN_CTX_get(ctx);
|
y=BN_CTX_get(ctx);
|
||||||
q=BN_CTX_get(ctx);
|
q=BN_CTX_get(ctx);
|
||||||
while (params->nid!=NID_undef && params->nid != nid) params++;
|
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);
|
GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -76,14 +77,13 @@ int fill_GOST2001_params(EC_KEY *eckey, int nid) {
|
|||||||
|
|
||||||
EC_KEY_set_group(eckey,grp);
|
EC_KEY_set_group(eckey,grp);
|
||||||
ok=1;
|
ok=1;
|
||||||
err:
|
err:
|
||||||
EC_POINT_free(P);
|
EC_POINT_free(P);
|
||||||
EC_GROUP_free(grp);
|
EC_GROUP_free(grp);
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
return ok;
|
return ok;
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -91,7 +91,8 @@ err:
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) {
|
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
|
||||||
|
{
|
||||||
DSA_SIG *newsig = NULL;
|
DSA_SIG *newsig = NULL;
|
||||||
BIGNUM *md = hashsum2bn(dgst);
|
BIGNUM *md = hashsum2bn(dgst);
|
||||||
BIGNUM *order = NULL;
|
BIGNUM *order = NULL;
|
||||||
@ -127,28 +128,33 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) {
|
|||||||
}
|
}
|
||||||
k =BN_CTX_get(ctx);
|
k =BN_CTX_get(ctx);
|
||||||
C=EC_POINT_new(group);
|
C=EC_POINT_new(group);
|
||||||
do {
|
do
|
||||||
do {
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
if (!BN_rand_range(k,order))
|
if (!BN_rand_range(k,order))
|
||||||
{
|
{
|
||||||
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
|
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
|
||||||
DSA_SIG_free(newsig);
|
DSA_SIG_free(newsig);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx)) {
|
if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
|
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
|
||||||
DSA_SIG_free(newsig);
|
DSA_SIG_free(newsig);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!X) X=BN_CTX_get(ctx);
|
if (!X) X=BN_CTX_get(ctx);
|
||||||
if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx)) {
|
if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
|
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
|
||||||
DSA_SIG_free(newsig);
|
DSA_SIG_free(newsig);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (!r) r=BN_CTX_get(ctx);
|
if (!r) r=BN_CTX_get(ctx);
|
||||||
BN_nnmod(r,X,order,ctx);
|
BN_nnmod(r,X,order,ctx);
|
||||||
} while (BN_is_zero(r));
|
}
|
||||||
|
while (BN_is_zero(r));
|
||||||
/* s = (r*priv_key+k*e) mod order */
|
/* s = (r*priv_key+k*e) mod order */
|
||||||
if (!tmp) tmp = BN_CTX_get(ctx);
|
if (!tmp) tmp = BN_CTX_get(ctx);
|
||||||
BN_mod_mul(tmp,priv_key,r,order,ctx);
|
BN_mod_mul(tmp,priv_key,r,order,ctx);
|
||||||
@ -156,23 +162,25 @@ DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey) {
|
|||||||
BN_mod_mul(tmp2,k,e,order,ctx);
|
BN_mod_mul(tmp2,k,e,order,ctx);
|
||||||
if (!s) s=BN_CTX_get(ctx);
|
if (!s) s=BN_CTX_get(ctx);
|
||||||
BN_mod_add(s,tmp,tmp2,order,ctx);
|
BN_mod_add(s,tmp,tmp2,order,ctx);
|
||||||
} while (BN_is_zero(s));
|
}
|
||||||
|
while (BN_is_zero(s));
|
||||||
|
|
||||||
newsig->s=BN_dup(s);
|
newsig->s=BN_dup(s);
|
||||||
newsig->r=BN_dup(r);
|
newsig->r=BN_dup(r);
|
||||||
err:
|
err:
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
EC_POINT_free(C);
|
EC_POINT_free(C);
|
||||||
BN_free(md);
|
BN_free(md);
|
||||||
return newsig;
|
return newsig;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Verifies gost 2001 signature
|
* Verifies gost 2001 signature
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
|
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();
|
BN_CTX *ctx=BN_CTX_new();
|
||||||
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
||||||
BIGNUM *order;
|
BIGNUM *order;
|
||||||
@ -242,32 +250,36 @@ int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
|
|||||||
BN_print_fp(stderr,R);
|
BN_print_fp(stderr,R);
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
#endif
|
#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);
|
GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ok = 1;
|
ok = 1;
|
||||||
}
|
}
|
||||||
err:
|
err:
|
||||||
EC_POINT_free(C);
|
EC_POINT_free(C);
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
BN_free(md);
|
BN_free(md);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Computes GOST R 34.10-2001 public key
|
* Computes GOST R 34.10-2001 public key
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int gost2001_compute_public(EC_KEY *ec)
|
int gost2001_compute_public(EC_KEY *ec)
|
||||||
{
|
{
|
||||||
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
||||||
EC_POINT *pub_key=NULL;
|
EC_POINT *pub_key=NULL;
|
||||||
const BIGNUM *priv_key=NULL;
|
const BIGNUM *priv_key=NULL;
|
||||||
BN_CTX *ctx=NULL;
|
BN_CTX *ctx=NULL;
|
||||||
int ok=0;
|
int ok=0;
|
||||||
|
|
||||||
if (!group) {
|
if (!group)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
|
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -285,29 +297,32 @@ int gost2001_compute_public(EC_KEY *ec)
|
|||||||
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
|
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
|
||||||
goto err;
|
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);
|
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ok = 256;
|
ok = 256;
|
||||||
err:
|
err:
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
EC_POINT_free(pub_key);
|
EC_POINT_free(pub_key);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Generates GOST R 34.10-2001 keypair
|
* 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();
|
BIGNUM *order = BN_new(),*d=BN_new();
|
||||||
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
const EC_GROUP *group = EC_KEY_get0_group(ec);
|
||||||
EC_GROUP_get_order(group,order,NULL);
|
EC_GROUP_get_order(group,order,NULL);
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
if (!BN_rand_range(d,order))
|
if (!BN_rand_range(d,order))
|
||||||
{
|
{
|
||||||
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
|
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
|
||||||
@ -315,10 +330,11 @@ int gost2001_keygen(EC_KEY *ec) {
|
|||||||
BN_free(order);
|
BN_free(order);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} while (BN_is_zero(d));
|
}
|
||||||
|
while (BN_is_zero(d));
|
||||||
EC_KEY_set_private_key(ec,d);
|
EC_KEY_set_private_key(ec,d);
|
||||||
BN_free(d);
|
BN_free(d);
|
||||||
BN_free(order);
|
BN_free(order);
|
||||||
return gost2001_compute_public(ec);
|
return gost2001_compute_public(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,49 +13,48 @@
|
|||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
#include "gost89.h"
|
#include "gost89.h"
|
||||||
#include "gosthash.h"
|
#include "gosthash.h"
|
||||||
#include "gost_asn1.h"
|
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
#include "keywrap.h"
|
#include "gost_keywrap.h"
|
||||||
#include "crypt.h"
|
#include "gost_lcl.h"
|
||||||
#include "sign.h"
|
|
||||||
#include "pmeth.h"
|
|
||||||
#include "tools.h"
|
|
||||||
#include "gostkeyx.h"
|
|
||||||
|
|
||||||
/* Transform ECDH shared key into little endian as required by Cryptocom
|
/* Transform ECDH shared key into little endian as required by Cryptocom
|
||||||
* key exchange */
|
* 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;
|
const char* inbuf= in;
|
||||||
char* outbuf= out;
|
char* outbuf= out;
|
||||||
int i;
|
int i;
|
||||||
if (*outlen < inlen) {
|
if (*outlen < inlen)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i=0;i<inlen;i++) {
|
for (i=0;i<inlen;i++)
|
||||||
|
{
|
||||||
outbuf[inlen-1-i]=inbuf[i];
|
outbuf[inlen-1-i]=inbuf[i];
|
||||||
}
|
}
|
||||||
*outlen = inlen;
|
*outlen = inlen;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create gost 2001 ephemeral key with same parameters as peer key */
|
/* 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 *out = EC_KEY_new();
|
||||||
EC_KEY_copy(out,peer_key);
|
EC_KEY_copy(out,peer_key);
|
||||||
EC_KEY_set_private_key(out,seckey);
|
EC_KEY_set_private_key(out,seckey);
|
||||||
gost2001_compute_public(out);
|
gost2001_compute_public(out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
/* Packs GOST elliptic curve key into EVP_PKEY setting same parameters
|
/* Packs GOST elliptic curve key into EVP_PKEY setting same parameters
|
||||||
* as in passed pubkey
|
* as in passed pubkey
|
||||||
*/
|
*/
|
||||||
static EVP_PKEY *ec_ephemeral_key_to_EVP(EVP_PKEY *pubk,int type,EC_KEY *ephemeral)
|
static EVP_PKEY *ec_ephemeral_key_to_EVP(EVP_PKEY *pubk,int type,EC_KEY *ephemeral)
|
||||||
{
|
{
|
||||||
EVP_PKEY *newkey;
|
EVP_PKEY *newkey;
|
||||||
newkey = EVP_PKEY_new();
|
newkey = EVP_PKEY_new();
|
||||||
EVP_PKEY_assign(newkey,type,ephemeral);
|
EVP_PKEY_assign(newkey,type,ephemeral);
|
||||||
return newkey;
|
return newkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EVP_PKEY_METHOD callback encrypt
|
* 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,
|
int pkey_GOST01cc_encrypt (EVP_PKEY_CTX *pctx,unsigned char *out,
|
||||||
size_t *out_len, const unsigned char *key,size_t key_len)
|
size_t *out_len, const unsigned char *key,size_t key_len)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
|
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||||
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
|
||||||
GOST_KEY_TRANSPORT *gkt = NULL;
|
GOST_KEY_TRANSPORT *gkt = NULL;
|
||||||
@ -116,7 +115,8 @@ int pkey_GOST01cc_encrypt (EVP_PKEY_CTX *pctx,unsigned char *out,
|
|||||||
goto err;
|
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);
|
GOSTerr(GOST_F_PKEY_GOST01CC_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -124,15 +124,16 @@ int pkey_GOST01cc_encrypt (EVP_PKEY_CTX *pctx,unsigned char *out,
|
|||||||
gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc);
|
gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc);
|
||||||
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret = 1;
|
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret = 1;
|
||||||
;
|
;
|
||||||
err:
|
err:
|
||||||
if (gkt) GOST_KEY_TRANSPORT_free(gkt);
|
if (gkt) GOST_KEY_TRANSPORT_free(gkt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* EVP_PKEY_METHOD callback decrypt
|
* EVP_PKEY_METHOD callback decrypt
|
||||||
* Implementation of GOST2001 key transport, cryptocom variation
|
* 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 */
|
/* Form DH params from compute shared key */
|
||||||
EVP_PKEY *priv=EVP_PKEY_CTX_get0_pkey(pctx);
|
EVP_PKEY *priv=EVP_PKEY_CTX_get0_pkey(pctx);
|
||||||
GOST_KEY_TRANSPORT *gkt = NULL;
|
GOST_KEY_TRANSPORT *gkt = NULL;
|
||||||
@ -145,14 +146,16 @@ int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l
|
|||||||
const EC_POINT *pub_key_point;
|
const EC_POINT *pub_key_point;
|
||||||
EVP_PKEY *eph_key;
|
EVP_PKEY *eph_key;
|
||||||
|
|
||||||
if (!key) {
|
if (!key)
|
||||||
|
{
|
||||||
*key_len = 32;
|
*key_len = 32;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Parse passed octet string and find out public key, iv and HMAC*/
|
/* Parse passed octet string and find out public key, iv and HMAC*/
|
||||||
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
||||||
in_len);
|
in_len);
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -185,20 +188,23 @@ int pkey_GOST01cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l
|
|||||||
}
|
}
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
/* check HMAC of session key*/
|
/* 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);
|
GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_ERROR_COMPUTING_MAC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* HMAC of session key is not correct */
|
/* HMAC of session key is not correct */
|
||||||
if (memcmp(hmac,hmac_comp,4)!=0) {
|
if (memcmp(hmac,hmac_comp,4)!=0)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH);
|
GOSTerr(GOST_F_PKEY_GOST01CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of CryptoPro VKO 34.10-2001 algorithm */
|
/* 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];
|
unsigned char ukm_be[8],databuf[64],hashbuf[64];
|
||||||
BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
|
BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
|
||||||
const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
|
const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
|
||||||
@ -207,7 +213,8 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons
|
|||||||
gost_hash_ctx hash_ctx;
|
gost_hash_ctx hash_ctx;
|
||||||
BN_CTX *ctx = BN_CTX_new();
|
BN_CTX *ctx = BN_CTX_new();
|
||||||
|
|
||||||
for (i=0;i<8;i++) {
|
for (i=0;i<8;i++)
|
||||||
|
{
|
||||||
ukm_be[7-i]=ukm[i];
|
ukm_be[7-i]=ukm[i];
|
||||||
}
|
}
|
||||||
BN_CTX_start(ctx);
|
BN_CTX_start(ctx);
|
||||||
@ -226,7 +233,8 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons
|
|||||||
store_bignum(Y,databuf,32);
|
store_bignum(Y,databuf,32);
|
||||||
store_bignum(X,databuf+32,32);
|
store_bignum(X,databuf+32,32);
|
||||||
/* And reverse byte order of whole buffer */
|
/* And reverse byte order of whole buffer */
|
||||||
for (i=0;i<64;i++) {
|
for (i=0;i<64;i++)
|
||||||
|
{
|
||||||
hashbuf[63-i]=databuf[i];
|
hashbuf[63-i]=databuf[i];
|
||||||
}
|
}
|
||||||
init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
|
init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
|
||||||
@ -239,7 +247,7 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons
|
|||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
EC_POINT_free(pnt);
|
EC_POINT_free(pnt);
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates ephemeral key based on pubk algorithm
|
/* Generates ephemeral key based on pubk algorithm
|
||||||
* computes shared key using VKO and returns filled up
|
* computes shared key using VKO and returns filled up
|
||||||
@ -249,7 +257,7 @@ static int VKO_compute_key(unsigned char *shared_key,size_t shared_key_size,cons
|
|||||||
GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_key,
|
GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_key,
|
||||||
const unsigned char *key,size_t keylen, unsigned char *ukm,
|
const unsigned char *key,size_t keylen, unsigned char *ukm,
|
||||||
size_t ukm_len)
|
size_t ukm_len)
|
||||||
{
|
{
|
||||||
|
|
||||||
const struct gost_cipher_info *param=get_encryption_params(NULL);
|
const struct gost_cipher_info *param=get_encryption_params(NULL);
|
||||||
EC_KEY *ephemeral = NULL;
|
EC_KEY *ephemeral = NULL;
|
||||||
@ -260,7 +268,8 @@ GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_ke
|
|||||||
EVP_PKEY *newkey=NULL;
|
EVP_PKEY *newkey=NULL;
|
||||||
|
|
||||||
/* Do not use vizir cipher parameters with cryptopro */
|
/* 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;
|
param= gost_cipher_list+1;
|
||||||
}
|
}
|
||||||
ephemeral = make_ec_ephemeral_key(EVP_PKEY_get0(pubk),eph_key);
|
ephemeral = make_ec_ephemeral_key(EVP_PKEY_get0(pubk),eph_key);
|
||||||
@ -268,21 +277,26 @@ GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_ke
|
|||||||
gost_init(&ctx,param->sblock);
|
gost_init(&ctx,param->sblock);
|
||||||
keyWrapCryptoPro(&ctx,shared_key,ukm,key,crypted_key);
|
keyWrapCryptoPro(&ctx,shared_key,ukm,key,crypted_key);
|
||||||
gkt = GOST_KEY_TRANSPORT_new();
|
gkt = GOST_KEY_TRANSPORT_new();
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
|
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
|
||||||
ukm,8)) {
|
ukm,8))
|
||||||
|
{
|
||||||
goto memerr;
|
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;
|
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;
|
goto memerr;
|
||||||
}
|
}
|
||||||
newkey = ec_ephemeral_key_to_EVP(pubk,NID_id_GostR3410_2001,ephemeral);
|
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);
|
GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -290,13 +304,13 @@ GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,BIGNUM *eph_ke
|
|||||||
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
|
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
|
||||||
EVP_PKEY_free(newkey);
|
EVP_PKEY_free(newkey);
|
||||||
return gkt;
|
return gkt;
|
||||||
memerr:
|
memerr:
|
||||||
GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001,
|
GOSTerr(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001,
|
||||||
GOST_R_MALLOC_FAILURE);
|
GOST_R_MALLOC_FAILURE);
|
||||||
err:
|
err:
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* EVP_PKEY_METHOD callback encrypt
|
* 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)
|
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;
|
GOST_KEY_TRANSPORT *gkt=NULL;
|
||||||
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
|
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||||
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
|
||||||
unsigned char ukm[8];
|
unsigned char ukm[8];
|
||||||
int ret=0;
|
int ret=0;
|
||||||
if (RAND_bytes(ukm,8)<=0) {
|
if (RAND_bytes(ukm,8)<=0)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
|
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
|
||||||
GOST_R_RANDOM_GENERATOR_FAILURE);
|
GOST_R_RANDOM_GENERATOR_FAILURE);
|
||||||
return 0;
|
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;
|
goto err;
|
||||||
}
|
}
|
||||||
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret =1;
|
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,&out))>0) ret =1;
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
return ret;
|
return ret;
|
||||||
err:
|
err:
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/* Public, because it would be needed in SSL implementation */
|
/* Public, because it would be needed in SSL implementation */
|
||||||
int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,GOST_KEY_TRANSPORT *gkt,
|
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 wrappedKey[44];
|
||||||
unsigned char sharedKey[32];
|
unsigned char sharedKey[32];
|
||||||
gost_ctx ctx;
|
gost_ctx ctx;
|
||||||
@ -347,7 +363,8 @@ int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,GOST_KEY_TRANSPORT *gkt,
|
|||||||
memcpy(wrappedKey+40,gkt->key_info->imit->data,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)),
|
VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(eph_key)),
|
||||||
EVP_PKEY_get0(priv),wrappedKey);
|
EVP_PKEY_get0(priv),wrappedKey);
|
||||||
if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key_buf)) {
|
if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key_buf))
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,
|
GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,
|
||||||
GOST_R_ERROR_COMPUTING_SHARED_KEY);
|
GOST_R_ERROR_COMPUTING_SHARED_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
@ -355,31 +372,34 @@ int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,GOST_KEY_TRANSPORT *gkt,
|
|||||||
|
|
||||||
EVP_PKEY_free(eph_key);
|
EVP_PKEY_free(eph_key);
|
||||||
return 32;
|
return 32;
|
||||||
err:
|
err:
|
||||||
EVP_PKEY_free(eph_key);
|
EVP_PKEY_free(eph_key);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* EVP_PKEY_METHOD callback decrypt
|
* EVP_PKEY_METHOD callback decrypt
|
||||||
* Implementation of GOST2001 key transport, cryptopo variation
|
* 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;
|
const unsigned char *p = in;
|
||||||
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
|
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||||
GOST_KEY_TRANSPORT *gkt = NULL;
|
GOST_KEY_TRANSPORT *gkt = NULL;
|
||||||
int ret=0;
|
int ret=0;
|
||||||
|
|
||||||
if (!key) {
|
if (!key)
|
||||||
|
{
|
||||||
*key_len = 32;
|
*key_len = 32;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
||||||
in_len);
|
in_len);
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
GOSTerr(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = decrypt_rfc4490_shared_key_2001(priv,gkt,key,*key_len);
|
ret = decrypt_rfc4490_shared_key_2001(priv,gkt,key,*key_len);
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ gost_subst_block GostR3411_94_TestParamSet = {
|
|||||||
{0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
|
{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},
|
{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}
|
{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 */
|
/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */
|
||||||
gost_subst_block GostR3411_94_CryptoProParamSet= {
|
gost_subst_block GostR3411_94_CryptoProParamSet= {
|
||||||
{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
|
{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
|
||||||
@ -39,11 +39,11 @@ gost_subst_block GostR3411_94_CryptoProParamSet= {
|
|||||||
{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
|
{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},
|
{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}
|
{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
/* Test paramset from GOST 28147 */
|
/* Test paramset from GOST 28147 */
|
||||||
gost_subst_block Gost28147_TestParamSet =
|
gost_subst_block Gost28147_TestParamSet =
|
||||||
{
|
{
|
||||||
{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
|
{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},
|
{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},
|
{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},
|
{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},
|
{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}
|
{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},
|
{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},
|
{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}
|
{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
|
||||||
};
|
};
|
||||||
/* 1.2.643.2.2.31.2 */
|
/* 1.2.643.2.2.31.2 */
|
||||||
gost_subst_block Gost28147_CryptoProParamSetB=
|
gost_subst_block Gost28147_CryptoProParamSetB=
|
||||||
{
|
{
|
||||||
{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
|
{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},
|
{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},
|
{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},
|
{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},
|
{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}
|
{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
|
||||||
};
|
};
|
||||||
/* 1.2.643.2.2.31.3 */
|
/* 1.2.643.2.2.31.3 */
|
||||||
gost_subst_block Gost28147_CryptoProParamSetC=
|
gost_subst_block Gost28147_CryptoProParamSetC=
|
||||||
{
|
{
|
||||||
{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
|
{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},
|
{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},
|
{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},
|
{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},
|
{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}
|
{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 1.2.643.2.2.31.4 */
|
/* 1.2.643.2.2.31.4 */
|
||||||
gost_subst_block Gost28147_CryptoProParamSetD=
|
gost_subst_block Gost28147_CryptoProParamSetD=
|
||||||
{
|
{
|
||||||
{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
|
{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},
|
{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},
|
{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},
|
{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},
|
{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}
|
{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const byte CryptoProKeyMeshingKey[]={
|
const byte CryptoProKeyMeshingKey[]={
|
||||||
@ -112,31 +112,33 @@ const byte CryptoProKeyMeshingKey[]={
|
|||||||
0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
|
0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
|
||||||
0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
|
0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
|
||||||
0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
|
0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
|
||||||
};
|
};
|
||||||
/* Initialization of gost_ctx subst blocks*/
|
/* 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;
|
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->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->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->k43[i] = (b->k4[i>>4] <<4 | b->k3 [i &15])<<8;
|
||||||
c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15];
|
c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Part of GOST 28147 algorithm moved into separate function */
|
/* Part of GOST 28147 algorithm moved into separate function */
|
||||||
static word32
|
static word32 f(gost_ctx *c,word32 x)
|
||||||
f(gost_ctx *c,word32 x)
|
{
|
||||||
{ x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]|
|
x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]|
|
||||||
c->k43[x>> 8 & 255] | c->k21[x & 255];
|
c->k43[x>> 8 & 255] | c->k21[x & 255];
|
||||||
/* Rotate left 11 bits */
|
/* Rotate left 11 bits */
|
||||||
return x<<11 | x>>(32-11);
|
return x<<11 | x>>(32-11);
|
||||||
}
|
}
|
||||||
/* Low-level encryption routine - encrypts one 64 bit block*/
|
/* Low-level encryption routine - encrypts one 64 bit block*/
|
||||||
void gostcrypt(gost_ctx *c, const byte *in, byte *out)
|
void gostcrypt(gost_ctx *c, const byte *in, byte *out)
|
||||||
{
|
{
|
||||||
register word32 n1, n2; /* As named in the GOST */
|
register word32 n1, n2; /* As named in the GOST */
|
||||||
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
|
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
|
||||||
n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
|
n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
|
||||||
@ -164,10 +166,10 @@ void gostcrypt(gost_ctx *c, const byte *in, byte *out)
|
|||||||
|
|
||||||
out[0] = (n2&0xff); out[1] = (n2>>8)&0xff; out[2]=(n2>>16)&0xff; out[3]=n2>>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;
|
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 */
|
/* Low-level decryption routine. Decrypts one 64-bit block */
|
||||||
void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
|
void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
|
||||||
{
|
{
|
||||||
register word32 n1, n2; /* As named in the GOST */
|
register word32 n1, n2; /* As named in the GOST */
|
||||||
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
|
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
|
||||||
n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<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]);
|
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[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[4] = (n1&0xff); out[5] = (n1>>8)&0xff; out[6]=(n1>>16)&0xff; out[7]=n1>>24;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypts several blocks in ECB mode */
|
/* Encrypts several blocks in ECB mode */
|
||||||
void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
|
void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<blocks;i++){
|
for(i=0;i<blocks;i++)
|
||||||
|
{
|
||||||
gostcrypt(c,clear,cipher);
|
gostcrypt(c,clear,cipher);
|
||||||
clear+=8;
|
clear+=8;
|
||||||
cipher+=8;
|
cipher+=8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Decrypts several blocks in ECB mode */
|
/* Decrypts several blocks in ECB mode */
|
||||||
void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
|
void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<blocks;i++) {
|
for(i=0;i<blocks;i++)
|
||||||
|
{
|
||||||
gostdecrypt(c,cipher,clear);
|
gostdecrypt(c,cipher,clear);
|
||||||
clear+=8;
|
clear+=8;
|
||||||
cipher+=8;
|
cipher+=8;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Encrypts several full blocks in CFB mode using 8byte IV */
|
/* 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 cur_iv[8];
|
||||||
byte gamma[8];
|
byte gamma[8];
|
||||||
int i,j;
|
int i,j;
|
||||||
const byte *in;
|
const byte *in;
|
||||||
byte *out;
|
byte *out;
|
||||||
memcpy(cur_iv,iv,8);
|
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);
|
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];
|
cur_iv[j]=out[j]=in[j]^gamma[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
/* Decrypts several full blocks in CFB mode using 8byte IV */
|
/* 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 cur_iv[8];
|
||||||
byte gamma[8];
|
byte gamma[8];
|
||||||
int i,j;
|
int i,j;
|
||||||
const byte *in;
|
const byte *in;
|
||||||
byte *out;
|
byte *out;
|
||||||
memcpy(cur_iv,iv,8);
|
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);
|
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];
|
out[j]=(cur_iv[j]=in[j])^gamma[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypts one block using specified key */
|
/* Encrypts one block using specified key */
|
||||||
void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock)
|
void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock)
|
||||||
{
|
{
|
||||||
gost_key(c,key);
|
gost_key(c,key);
|
||||||
gostcrypt(c,inblock,outblock);
|
gostcrypt(c,inblock,outblock);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
/* Set 256 bit key into context */
|
/* Set 256 bit key into context */
|
||||||
void gost_key(gost_ctx *c, const byte *k)
|
void gost_key(gost_ctx *c, const byte *k)
|
||||||
{
|
{
|
||||||
int i,j;
|
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);
|
c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve 256-bit key from context */
|
/* Retrieve 256-bit key from context */
|
||||||
void gost_get_key(gost_ctx *c, byte *k)
|
void gost_get_key(gost_ctx *c, byte *k)
|
||||||
{
|
{
|
||||||
int i,j;
|
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]=c->k[i]& 0xFF;
|
||||||
k[j+1]=(c->k[i]>>8 )&0xFF;
|
k[j+1]=(c->k[i]>>8 )&0xFF;
|
||||||
k[j+2]=(c->k[i]>>16) &0xFF;
|
k[j+2]=(c->k[i]>>16) &0xFF;
|
||||||
k[j+3]=(c->k[i]>>24) &0xFF;
|
k[j+3]=(c->k[i]>>24) &0xFF;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
/* Initalize context. Provides default value for subst_block */
|
/* Initalize context. Provides default value for subst_block */
|
||||||
void gost_init(gost_ctx *c, const gost_subst_block *b)
|
void gost_init(gost_ctx *c, const gost_subst_block *b)
|
||||||
{
|
{
|
||||||
if(!b) {
|
if(!b)
|
||||||
|
{
|
||||||
b=&GostR3411_94_TestParamSet;
|
b=&GostR3411_94_TestParamSet;
|
||||||
}
|
}
|
||||||
kboxinit(c,b);
|
kboxinit(c,b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleans up key from context */
|
/* Cleans up key from context */
|
||||||
void gost_destroy(gost_ctx *c)
|
void gost_destroy(gost_ctx *c)
|
||||||
{
|
{
|
||||||
int i; for(i=0;i<8;i++) c->k[i]=0;
|
int i; for(i=0;i<8;i++) c->k[i]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute GOST 28147 mac block
|
/* Compute GOST 28147 mac block
|
||||||
*
|
*
|
||||||
@ -297,11 +310,12 @@ void gost_destroy(gost_ctx *c)
|
|||||||
* buffer - 8-byte mac state buffer
|
* buffer - 8-byte mac state buffer
|
||||||
* block 8-byte block to process.
|
* block 8-byte block to process.
|
||||||
* */
|
* */
|
||||||
void mac_block(gost_ctx *c,byte *buffer,const byte *block) {
|
void mac_block(gost_ctx *c,byte *buffer,const byte *block)
|
||||||
|
{
|
||||||
register word32 n1, n2; /* As named in the GOST */
|
register word32 n1, n2; /* As named in the GOST */
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<8; i++) {
|
for (i=0; i<8; i++)
|
||||||
|
{
|
||||||
buffer[i]^=block[i];
|
buffer[i]^=block[i];
|
||||||
}
|
}
|
||||||
n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24);
|
n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24);
|
||||||
@ -320,57 +334,62 @@ void mac_block(gost_ctx *c,byte *buffer,const byte *block) {
|
|||||||
|
|
||||||
buffer[0] = (n1&0xff); buffer[1] = (n1>>8)&0xff; buffer[2]=(n1>>16)&0xff; buffer[3]=n1>>24;
|
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;
|
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 */
|
/* 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 nbytes= nbits >> 3;
|
||||||
int rembits = nbits & 7;
|
int rembits = nbits & 7;
|
||||||
int mask =rembits?((1<rembits)-1):0;
|
int mask =rembits?((1<rembits)-1):0;
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<nbytes;i++) out[i]=buffer[i];
|
for (i=0;i<nbytes;i++) out[i]=buffer[i];
|
||||||
if (rembits) out[i]=buffer[i]&mask;
|
if (rembits) out[i]=buffer[i]&mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute mac of specified length (in bits) from data.
|
/* Compute mac of specified length (in bits) from data.
|
||||||
* Context should be initialized with key and subst blocks */
|
* Context should be initialized with key and subst blocks */
|
||||||
int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
|
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 buffer[8]={0,0,0,0,0,0,0,0};
|
||||||
byte buf2[8];
|
byte buf2[8];
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i+8<=data_len;i+=8)
|
for (i=0;i+8<=data_len;i+=8)
|
||||||
mac_block(ctx,buffer,data+i);
|
mac_block(ctx,buffer,data+i);
|
||||||
if (i<data_len) {
|
if (i<data_len)
|
||||||
|
{
|
||||||
memset(buf2,0,8);
|
memset(buf2,0,8);
|
||||||
memcpy(buf2,data+i,data_len-i);
|
memcpy(buf2,data+i,data_len-i);
|
||||||
mac_block(ctx,buffer,buf2);
|
mac_block(ctx,buffer,buf2);
|
||||||
}
|
}
|
||||||
get_mac(buffer,mac_len,mac);
|
get_mac(buffer,mac_len,mac);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
|
/* 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,
|
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 buffer[8];
|
||||||
byte buf2[8];
|
byte buf2[8];
|
||||||
int i;
|
int i;
|
||||||
memcpy (buffer,iv,8);
|
memcpy (buffer,iv,8);
|
||||||
for (i=0;i+8<=data_len;i+=8)
|
for (i=0;i+8<=data_len;i+=8)
|
||||||
mac_block(ctx,buffer,data+i);
|
mac_block(ctx,buffer,data+i);
|
||||||
if (i<data_len) {
|
if (i<data_len)
|
||||||
|
{
|
||||||
memset(buf2,0,8);
|
memset(buf2,0,8);
|
||||||
memcpy(buf2,data+i,data_len-i);
|
memcpy(buf2,data+i,data_len-i);
|
||||||
mac_block(ctx,buffer,buf2);
|
mac_block(ctx,buffer,buf2);
|
||||||
}
|
}
|
||||||
get_mac(buffer,mac_len,mac);
|
get_mac(buffer,mac_len,mac);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implements key meshing algorithm by modifing ctx and IV in place */
|
/* 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];
|
unsigned char newkey[32],newiv[8];
|
||||||
/* Set static keymeshing key */
|
/* Set static keymeshing key */
|
||||||
/* "Decrypt" key with 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 */
|
/* Encrypt iv with new key */
|
||||||
gostcrypt(ctx,iv,newiv);
|
gostcrypt(ctx,iv,newiv);
|
||||||
memcpy(iv,newiv,8);
|
memcpy(iv,newiv,8);
|
||||||
}
|
}
|
||||||
|
@ -14,24 +14,21 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
|
|
||||||
#include "gostkeyx.h"
|
|
||||||
#include "gost_asn1.h"
|
|
||||||
#include "gost89.h"
|
#include "gost89.h"
|
||||||
#include "gosthash.h"
|
#include "gosthash.h"
|
||||||
#include "crypt.h"
|
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
#include "pmeth.h"
|
#include "gost_keywrap.h"
|
||||||
#include "keywrap.h"
|
#include "gost_lcl.h"
|
||||||
#include "tools.h"
|
|
||||||
/* Common functions for both 94 and 2001 key exchange schemes */
|
/* Common functions for both 94 and 2001 key exchange schemes */
|
||||||
int decrypt_cryptocom_key(unsigned char *sess_key,int max_key_len,
|
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 i;
|
||||||
int j;
|
int j;
|
||||||
int blocks = crypted_key_len >>3;
|
int blocks = crypted_key_len >>3;
|
||||||
unsigned char gamma[8];
|
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);
|
GOSTerr(GOST_F_DECRYPT_CRYPTOCOM_KEY,GOST_R_NOT_ENOUGH_SPACE_FOR_KEY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -54,10 +51,10 @@ int decrypt_cryptocom_key(unsigned char *sess_key,int max_key_len,
|
|||||||
sess_key[j]=gamma[j]^crypted_key[j];
|
sess_key[j]=gamma[j]^crypted_key[j];
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len,
|
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 i;
|
||||||
int j;
|
int j;
|
||||||
unsigned char gamma[8];
|
unsigned char gamma[8];
|
||||||
@ -69,7 +66,7 @@ int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len,
|
|||||||
gamma[j]=crypted_key[i+j]=sess_key[i+j]^gamma[j];
|
gamma[j]=crypted_key[i+j]=sess_key[i+j]^gamma[j];
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* Implementation of the Diffi-Hellman key agreement scheme based on
|
/* Implementation of the Diffi-Hellman key agreement scheme based on
|
||||||
* GOST-94 keys */
|
* GOST-94 keys */
|
||||||
|
|
||||||
@ -78,23 +75,24 @@ int encrypt_cryptocom_key(const unsigned char *sess_key,int key_len,
|
|||||||
* algorigthm
|
* algorigthm
|
||||||
*/
|
*/
|
||||||
static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh)
|
static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh)
|
||||||
{
|
{
|
||||||
unsigned char be_key[128];
|
unsigned char be_key[128];
|
||||||
int i,key_size;
|
int i,key_size;
|
||||||
key_size=DH_compute_key(be_key,pub_key,dh);
|
key_size=DH_compute_key(be_key,pub_key,dh);
|
||||||
if (!key_size) return 0;
|
if (!key_size) return 0;
|
||||||
memset(pair_key,0,128);
|
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];
|
pair_key[i]=be_key[key_size-1-i];
|
||||||
}
|
}
|
||||||
return key_size;
|
return key_size;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Computes 256 bit key exchange key for CryptoCom variation of GOST 94
|
* Computes 256 bit key exchange key for CryptoCom variation of GOST 94
|
||||||
* algorithm
|
* algorithm
|
||||||
*/
|
*/
|
||||||
static int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key)
|
static int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key)
|
||||||
{
|
{
|
||||||
unsigned char dh_key [128];
|
unsigned char dh_key [128];
|
||||||
int i;
|
int i;
|
||||||
/* Compute key */
|
/* Compute key */
|
||||||
@ -106,33 +104,38 @@ static int make_gost_shared_key(DH *dh,EVP_PKEY *pubk,unsigned char *shared_key)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (DH_size(dh)==128)
|
if (DH_size(dh)==128)
|
||||||
for (i=0;i<64;i++) {
|
{
|
||||||
|
for (i=0;i<64;i++)
|
||||||
|
{
|
||||||
dh_key[i]^=dh_key[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];
|
shared_key[i]=dh_key[i]^dh_key[32+i];
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DH *make_ephemeral_key(EVP_PKEY *pubk,BIGNUM *ephemeral_key)
|
static DH *make_ephemeral_key(EVP_PKEY *pubk,BIGNUM *ephemeral_key)
|
||||||
{
|
{
|
||||||
DH *dh = DH_new();
|
DH *dh = DH_new();
|
||||||
dh->g = BN_dup(pubk->pkey.dsa->g);
|
dh->g = BN_dup(pubk->pkey.dsa->g);
|
||||||
dh->p = BN_dup(pubk->pkey.dsa->p);
|
dh->p = BN_dup(pubk->pkey.dsa->p);
|
||||||
dh->priv_key = BN_dup(ephemeral_key);
|
dh->priv_key = BN_dup(ephemeral_key);
|
||||||
/* Generate ephemeral key pair */
|
/* Generate ephemeral key pair */
|
||||||
if (!DH_generate_key(dh)) {
|
if (!DH_generate_key(dh))
|
||||||
|
{
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return dh;
|
return dh;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Computes 256 bit Key exchange key as specified in RFC 4357
|
* 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)
|
static int make_cp_exchange_key(DH *dh,EVP_PKEY *pubk, unsigned char *shared_key)
|
||||||
{
|
{
|
||||||
unsigned char dh_key [128];
|
unsigned char dh_key [128];
|
||||||
gost_hash_ctx hash_ctx;
|
gost_hash_ctx hash_ctx;
|
||||||
memset(dh_key,0,128);
|
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);
|
finish_hash(&hash_ctx,shared_key);
|
||||||
done_gost_hash_ctx(&hash_ctx);
|
done_gost_hash_ctx(&hash_ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVP_PKEY_METHOD callback encrypt for
|
/* EVP_PKEY_METHOD callback encrypt for
|
||||||
* GOST R 34.10-94 cryptopro modification
|
* 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 )
|
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;
|
GOST_KEY_TRANSPORT *gkt=NULL;
|
||||||
DH *dh = NULL;
|
DH *dh = NULL;
|
||||||
unsigned char shared_key[32], ukm[8],crypted_key[44];
|
unsigned char shared_key[32], ukm[8],crypted_key[44];
|
||||||
@ -159,8 +163,8 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
|
|||||||
int size=-1;
|
int size=-1;
|
||||||
gost_ctx cctx;
|
gost_ctx cctx;
|
||||||
|
|
||||||
|
if (!(data->eph_seckey))
|
||||||
if (!(data->eph_seckey)) {
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
||||||
GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT);
|
GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT);
|
||||||
return -1;
|
return -1;
|
||||||
@ -169,54 +173,62 @@ int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
|
|||||||
dh = make_ephemeral_key(pubk,gost_get_priv_key(data->eph_seckey));
|
dh = make_ephemeral_key(pubk,gost_get_priv_key(data->eph_seckey));
|
||||||
gost_init(&cctx,param->sblock);
|
gost_init(&cctx,param->sblock);
|
||||||
make_cp_exchange_key(dh,pubk,shared_key);
|
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,
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
||||||
GOST_R_RANDOM_GENERATOR_FAILURE);
|
GOST_R_RANDOM_GENERATOR_FAILURE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
|
keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
|
||||||
gkt = GOST_KEY_TRANSPORT_new();
|
gkt = GOST_KEY_TRANSPORT_new();
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
goto memerr;
|
goto memerr;
|
||||||
}
|
}
|
||||||
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
|
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
|
||||||
ukm,8)) {
|
ukm,8))
|
||||||
|
{
|
||||||
goto memerr;
|
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;
|
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;
|
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);
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
|
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
|
||||||
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
|
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
|
||||||
*outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out);
|
*outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out);
|
||||||
if (!size) {
|
if (!size)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
|
||||||
size=-1;
|
size=-1;
|
||||||
}
|
}
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return 1;
|
return 1;
|
||||||
memerr:
|
memerr:
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
||||||
GOST_R_MALLOC_FAILURE);
|
GOST_R_MALLOC_FAILURE);
|
||||||
err:
|
err:
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVP_PKEY_METHOD callback encrypt for
|
/* EVP_PKEY_METHOD callback encrypt for
|
||||||
* GOST R 34.10-94 cryptocom modification
|
* 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)
|
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);
|
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
||||||
/* create DH structure filling parameters from passed pub_key */
|
/* create DH structure filling parameters from passed pub_key */
|
||||||
@ -227,7 +239,8 @@ int pkey_GOST94cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
|
|||||||
unsigned char shared_key[32],encrypted_key[32],hmac[4],
|
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,
|
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
|
||||||
GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT);
|
GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT);
|
||||||
return -1;
|
return -1;
|
||||||
@ -274,19 +287,20 @@ int pkey_GOST94cc_encrypt (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen
|
|||||||
GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_STORING_ENCRYPTED_KEY);
|
GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_ERROR_STORING_ENCRYPTED_KEY);
|
||||||
goto err;
|
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);
|
GOSTerr(GOST_F_PKEY_GOST94CC_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
|
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
|
||||||
gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc);
|
gkt->key_agreement_info->cipher = OBJ_nid2obj(NID_id_Gost28147_89_cc);
|
||||||
*outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out);
|
*outlen = i2d_GOST_KEY_TRANSPORT(gkt,&out);
|
||||||
err:
|
err:
|
||||||
if (gkt) GOST_KEY_TRANSPORT_free(gkt);
|
if (gkt) GOST_KEY_TRANSPORT_free(gkt);
|
||||||
if (dh) DH_free(dh);
|
if (dh) DH_free(dh);
|
||||||
if (newkey) EVP_PKEY_free(newkey);
|
if (newkey) EVP_PKEY_free(newkey);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EVP_PLEY_METHOD callback decrypt for
|
/* EVP_PLEY_METHOD callback decrypt for
|
||||||
* GOST R 34.10-94 cryptopro modification
|
* GOST R 34.10-94 cryptopro modification
|
||||||
@ -302,7 +316,8 @@ int pkey_GOST94cp_decrypt (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_le
|
|||||||
EVP_PKEY *eph_key=NULL;
|
EVP_PKEY *eph_key=NULL;
|
||||||
EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
|
|
||||||
if (!key) {
|
if (!key)
|
||||||
|
{
|
||||||
*key_len = 32;
|
*key_len = 32;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -312,7 +327,8 @@ int pkey_GOST94cp_decrypt (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_le
|
|||||||
dh->priv_key = BN_dup(priv->pkey.dsa->priv_key);
|
dh->priv_key = BN_dup(priv->pkey.dsa->priv_key);
|
||||||
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
||||||
in_len);
|
in_len);
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return 0;
|
return 0;
|
||||||
@ -327,7 +343,8 @@ int pkey_GOST94cp_decrypt (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_le
|
|||||||
OPENSSL_assert(gkt->key_info->imit->length==4);
|
OPENSSL_assert(gkt->key_info->imit->length==4);
|
||||||
memcpy(wrappedKey+40,gkt->key_info->imit->data,4);
|
memcpy(wrappedKey+40,gkt->key_info->imit->data,4);
|
||||||
make_cp_exchange_key(dh,eph_key,sharedKey);
|
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,
|
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
|
||||||
GOST_R_ERROR_COMPUTING_SHARED_KEY);
|
GOST_R_ERROR_COMPUTING_SHARED_KEY);
|
||||||
goto err;
|
goto err;
|
||||||
@ -342,14 +359,14 @@ err:
|
|||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
/* EVP_PKEY_METHOD callback decrypt for
|
/* EVP_PKEY_METHOD callback decrypt for
|
||||||
* GOST R 34.10-94 cryptocom modification
|
* 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)
|
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 */
|
/* Form DH params from compute shared key */
|
||||||
GOST_KEY_TRANSPORT *gkt = NULL;
|
GOST_KEY_TRANSPORT *gkt = NULL;
|
||||||
const unsigned char *p=in;
|
const unsigned char *p=in;
|
||||||
@ -362,7 +379,8 @@ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l
|
|||||||
EVP_PKEY *eph_key;
|
EVP_PKEY *eph_key;
|
||||||
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
|
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
|
||||||
|
|
||||||
if (!key) {
|
if (!key)
|
||||||
|
{
|
||||||
*key_len = 32;
|
*key_len = 32;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -373,7 +391,8 @@ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l
|
|||||||
/* Parse passed octet string and find out public key, iv and HMAC*/
|
/* Parse passed octet string and find out public key, iv and HMAC*/
|
||||||
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
|
||||||
in_len);
|
in_len);
|
||||||
if (!gkt) {
|
if (!gkt)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
|
||||||
DH_free(dh);
|
DH_free(dh);
|
||||||
return 0;
|
return 0;
|
||||||
@ -407,14 +426,16 @@ int pkey_GOST94cc_decrypt (EVP_PKEY_CTX *pctx, unsigned char *key, size_t *key_l
|
|||||||
}
|
}
|
||||||
GOST_KEY_TRANSPORT_free(gkt);
|
GOST_KEY_TRANSPORT_free(gkt);
|
||||||
/* check HMAC of session key*/
|
/* 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);
|
GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_ERROR_COMPUTING_MAC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* HMAC of session key is not correct */
|
/* HMAC of session key is not correct */
|
||||||
if (memcmp(hmac,hmac_comp,4)!=0) {
|
if (memcmp(hmac,hmac_comp,4)!=0)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH);
|
GOSTerr(GOST_F_PKEY_GOST94CC_DECRYPT,GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* ameth.c *
|
* gost_ameth.c *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
||||||
@ -10,20 +10,16 @@
|
|||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "meth.h"
|
#include "gost_params.h"
|
||||||
#include "pmeth.h"
|
#include "gost_lcl.h"
|
||||||
#include "paramset.h"
|
|
||||||
#include "gost_asn1.h"
|
|
||||||
#include "crypt.h"
|
|
||||||
#include "sign.h"
|
|
||||||
#include "tools.h"
|
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
|
|
||||||
int gost94_nid_by_params(DSA *p)
|
int gost94_nid_by_params(DSA *p)
|
||||||
{
|
{
|
||||||
R3410_params *gost_params;
|
R3410_params *gost_params;
|
||||||
BIGNUM *q=BN_new();
|
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);
|
BN_dec2bn(&q,gost_params->q);
|
||||||
if (!BN_cmp(q,p->q))
|
if (!BN_cmp(q,p->q))
|
||||||
{
|
{
|
||||||
@ -33,22 +29,24 @@ int gost94_nid_by_params(DSA *p)
|
|||||||
}
|
}
|
||||||
BN_free(q);
|
BN_free(q);
|
||||||
return NID_undef;
|
return NID_undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
|
static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
|
||||||
{
|
{
|
||||||
ASN1_STRING *params = ASN1_STRING_new();
|
ASN1_STRING *params = ASN1_STRING_new();
|
||||||
GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
|
GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new();
|
||||||
int pkey_param_nid = NID_undef;
|
int pkey_param_nid = NID_undef;
|
||||||
int cipher_param_nid = NID_undef;
|
int cipher_param_nid = NID_undef;
|
||||||
if (!params || !gkp) {
|
if (!params || !gkp)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
|
GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
|
||||||
ERR_R_MALLOC_FAILURE);
|
ERR_R_MALLOC_FAILURE);
|
||||||
ASN1_STRING_free(params);
|
ASN1_STRING_free(params);
|
||||||
params = NULL;
|
params = NULL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
switch (EVP_PKEY_base_id(key)) {
|
switch (EVP_PKEY_base_id(key))
|
||||||
|
{
|
||||||
case NID_id_GostR3410_2001_cc:
|
case NID_id_GostR3410_2001_cc:
|
||||||
pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc;
|
pkey_param_nid = NID_id_GostR3410_2001_ParamSet_cc;
|
||||||
cipher_param_nid = NID_id_Gost28147_89_cc;
|
cipher_param_nid = NID_id_Gost28147_89_cc;
|
||||||
@ -63,7 +61,8 @@ static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
|
|||||||
break;
|
break;
|
||||||
case NID_id_GostR3410_94:
|
case NID_id_GostR3410_94:
|
||||||
pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
|
pkey_param_nid = (int) gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key));
|
||||||
if (pkey_param_nid == NID_undef) {
|
if (pkey_param_nid == NID_undef)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
|
GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS,
|
||||||
GOST_R_INVALID_GOST94_PARMSET);
|
GOST_R_INVALID_GOST94_PARMSET);
|
||||||
ASN1_STRING_free(params);
|
ASN1_STRING_free(params);
|
||||||
@ -86,15 +85,16 @@ static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
params ->type = V_ASN1_SEQUENCE;
|
params ->type = V_ASN1_SEQUENCE;
|
||||||
err:
|
err:
|
||||||
GOST_KEY_PARAMS_free(gkp);
|
GOST_KEY_PARAMS_free(gkp);
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parses GOST algorithm parameters from X509_ALGOR and
|
/* Parses GOST algorithm parameters from X509_ALGOR and
|
||||||
* modifies pkey setting NID and parameters
|
* modifies pkey setting NID and parameters
|
||||||
*/
|
*/
|
||||||
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
|
static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
|
||||||
{
|
{
|
||||||
ASN1_OBJECT *palg_obj =NULL;
|
ASN1_OBJECT *palg_obj =NULL;
|
||||||
int ptype = V_ASN1_UNDEF;
|
int ptype = V_ASN1_UNDEF;
|
||||||
int pkey_nid = NID_undef,param_nid = NID_undef;
|
int pkey_nid = NID_undef,param_nid = NID_undef;
|
||||||
@ -103,7 +103,8 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
|
|||||||
GOST_KEY_PARAMS *gkp = NULL;
|
GOST_KEY_PARAMS *gkp = NULL;
|
||||||
|
|
||||||
X509_ALGOR_get0(&palg_obj, &ptype, (void **) (&pval), palg);
|
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,
|
GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
|
||||||
GOST_R_BAD_KEY_PARAMETERS_FORMAT);
|
GOST_R_BAD_KEY_PARAMETERS_FORMAT);
|
||||||
return 0;
|
return 0;
|
||||||
@ -112,18 +113,22 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
|
|||||||
pkey_nid = OBJ_obj2nid(palg_obj);
|
pkey_nid = OBJ_obj2nid(palg_obj);
|
||||||
|
|
||||||
gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
|
gkp = d2i_GOST_KEY_PARAMS(NULL,&p,pval->length);
|
||||||
if (!gkp) {
|
if (!gkp)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS,
|
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);
|
param_nid = OBJ_obj2nid(gkp->key_params);
|
||||||
GOST_KEY_PARAMS_free(gkp);
|
GOST_KEY_PARAMS_free(gkp);
|
||||||
EVP_PKEY_set_type(pkey,pkey_nid);
|
EVP_PKEY_set_type(pkey,pkey_nid);
|
||||||
switch (pkey_nid) {
|
switch (pkey_nid)
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94:
|
case NID_id_GostR3410_94:
|
||||||
case NID_id_GostR3410_94_cc:
|
case NID_id_GostR3410_94_cc:
|
||||||
{ DSA *dsa= EVP_PKEY_get0(pkey);
|
{
|
||||||
if (!dsa) {
|
DSA *dsa= EVP_PKEY_get0(pkey);
|
||||||
|
if (!dsa)
|
||||||
|
{
|
||||||
dsa = DSA_new();
|
dsa = DSA_new();
|
||||||
if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
|
if (!EVP_PKEY_assign(pkey,pkey_nid,dsa)) return 0;
|
||||||
}
|
}
|
||||||
@ -132,27 +137,30 @@ static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg)
|
|||||||
}
|
}
|
||||||
case NID_id_GostR3410_2001:
|
case NID_id_GostR3410_2001:
|
||||||
case NID_id_GostR3410_2001_cc:
|
case NID_id_GostR3410_2001_cc:
|
||||||
{ EC_KEY *ec = EVP_PKEY_get0(pkey);
|
{
|
||||||
if (!ec) {
|
EC_KEY *ec = EVP_PKEY_get0(pkey);
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
ec = EC_KEY_new();
|
ec = EC_KEY_new();
|
||||||
if (!EVP_PKEY_assign(pkey,pkey_nid,ec)) return 0;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
|
static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
|
||||||
{
|
{
|
||||||
switch (EVP_PKEY_base_id(pkey)) {
|
switch (EVP_PKEY_base_id(pkey))
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94:
|
case NID_id_GostR3410_94:
|
||||||
case NID_id_GostR3410_94_cc:
|
case NID_id_GostR3410_94_cc:
|
||||||
{ DSA *dsa = EVP_PKEY_get0(pkey);
|
{
|
||||||
if (!dsa) {
|
DSA *dsa = EVP_PKEY_get0(pkey);
|
||||||
|
if (!dsa)
|
||||||
|
{
|
||||||
dsa = DSA_new();
|
dsa = DSA_new();
|
||||||
EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
|
EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),dsa);
|
||||||
}
|
}
|
||||||
@ -163,8 +171,10 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
|
|||||||
}
|
}
|
||||||
case NID_id_GostR3410_2001:
|
case NID_id_GostR3410_2001:
|
||||||
case NID_id_GostR3410_2001_cc:
|
case NID_id_GostR3410_2001_cc:
|
||||||
{ EC_KEY *ec = EVP_PKEY_get0(pkey);
|
{
|
||||||
if (!ec) {
|
EC_KEY *ec = EVP_PKEY_get0(pkey);
|
||||||
|
if (!ec)
|
||||||
|
{
|
||||||
ec = EC_KEY_new();
|
ec = EC_KEY_new();
|
||||||
EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
|
EVP_PKEY_assign(pkey,EVP_PKEY_base_id(pkey),ec);
|
||||||
}
|
}
|
||||||
@ -173,17 +183,19 @@ static int gost_set_priv_key(EVP_PKEY *pkey,BIGNUM *priv)
|
|||||||
gost2001_compute_public(ec);
|
gost2001_compute_public(ec);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey)
|
BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey)
|
||||||
{
|
{
|
||||||
switch (EVP_PKEY_base_id(pkey)) {
|
switch (EVP_PKEY_base_id(pkey))
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94:
|
case NID_id_GostR3410_94:
|
||||||
case NID_id_GostR3410_94_cc:
|
case NID_id_GostR3410_94_cc:
|
||||||
{ DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
|
{
|
||||||
if (!dsa) {
|
DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey);
|
||||||
|
if (!dsa)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!dsa->priv_key) return NULL;
|
if (!dsa->priv_key) return NULL;
|
||||||
@ -192,33 +204,37 @@ BIGNUM* gost_get_priv_key(const EVP_PKEY *pkey)
|
|||||||
}
|
}
|
||||||
case NID_id_GostR3410_2001:
|
case NID_id_GostR3410_2001:
|
||||||
case NID_id_GostR3410_2001_cc:
|
case NID_id_GostR3410_2001_cc:
|
||||||
{ EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
|
{
|
||||||
|
EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey);
|
||||||
const BIGNUM* priv;
|
const BIGNUM* priv;
|
||||||
if (!ec) {
|
if (!ec)
|
||||||
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
|
if (!(priv=EC_KEY_get0_private_key(ec))) return NULL;
|
||||||
return BN_dup(priv);
|
return BN_dup(priv);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
|
static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
|
||||||
long arg1, void *arg2)
|
long arg1, void *arg2)
|
||||||
{
|
{
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
||||||
if (arg1 == 0) {
|
if (arg1 == 0)
|
||||||
|
{
|
||||||
X509_ALGOR *alg1 = NULL, *alg2 = NULL;
|
X509_ALGOR *alg1 = NULL, *alg2 = NULL;
|
||||||
int nid = EVP_PKEY_base_id(pkey);
|
int nid = EVP_PKEY_base_id(pkey);
|
||||||
PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO*)arg2,
|
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),
|
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94),
|
||||||
V_ASN1_NULL, 0);
|
V_ASN1_NULL, 0);
|
||||||
if (nid == NID_undef) {
|
if (nid == NID_undef)
|
||||||
|
{
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
|
X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0);
|
||||||
@ -229,7 +245,8 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
|
|||||||
{
|
{
|
||||||
X509_ALGOR *alg;
|
X509_ALGOR *alg;
|
||||||
ASN1_STRING * params = encode_gost_algor_params(pkey);
|
ASN1_STRING * params = encode_gost_algor_params(pkey);
|
||||||
if (!params) {
|
if (!params)
|
||||||
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
|
PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO*)arg2, &alg);
|
||||||
@ -243,21 +260,27 @@ static int pkey_ctrl_gost(EVP_PKEY *pkey, int op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
/*----------------------- free functions * ------------------------------*/
|
/*----------------------- free functions * ------------------------------*/
|
||||||
static void pkey_free_gost94(EVP_PKEY *key) {
|
static void pkey_free_gost94(EVP_PKEY *key)
|
||||||
if (key->pkey.dsa) {
|
{
|
||||||
|
if (key->pkey.dsa)
|
||||||
|
{
|
||||||
DSA_free(key->pkey.dsa);
|
DSA_free(key->pkey.dsa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void pkey_free_gost01(EVP_PKEY *key) {
|
|
||||||
if (key->pkey.ec) {
|
static void pkey_free_gost01(EVP_PKEY *key)
|
||||||
|
{
|
||||||
|
if (key->pkey.ec)
|
||||||
|
{
|
||||||
EC_KEY_free(key->pkey.ec);
|
EC_KEY_free(key->pkey.ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------ private key functions -----------------------------*/
|
/* ------------------ private key functions -----------------------------*/
|
||||||
static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
|
static int priv_decode_gost( EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf)
|
||||||
{
|
{
|
||||||
const unsigned char *pkey_buf = NULL,*p=NULL;
|
const unsigned char *pkey_buf = NULL,*p=NULL;
|
||||||
int priv_len = 0;
|
int priv_len = 0;
|
||||||
BIGNUM *pk_num=NULL;
|
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))
|
if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf))
|
||||||
return 0;
|
return 0;
|
||||||
p = pkey_buf;
|
p = pkey_buf;
|
||||||
if (!decode_gost_algor_params(pk,palg)) {
|
if (!decode_gost_algor_params(pk,palg))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
priv_key=d2i_ASN1_INTEGER(NULL,&p,priv_len);
|
if (V_ASN1_OCTET_STRING == *p)
|
||||||
if (!priv_key) {
|
{
|
||||||
}
|
/* New format - Little endian octet string */
|
||||||
|
unsigned char rev_buf[32];
|
||||||
if (!(pk_num = ASN1_INTEGER_to_BN(priv_key, NULL))) {
|
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,
|
GOSTerr(GOST_F_PRIV_DECODE_GOST_94,
|
||||||
EVP_R_DECODE_ERROR);
|
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);
|
ret= gost_set_priv_key(pk,pk_num);
|
||||||
BN_free(pk_num);
|
BN_free(pk_num);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------*/
|
/* ----------------------------------------------------------------------*/
|
||||||
static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
|
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_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
|
||||||
ASN1_STRING *params = encode_gost_algor_params(pk);
|
ASN1_STRING *params = encode_gost_algor_params(pk);
|
||||||
unsigned char *priv_buf = NULL;
|
unsigned char *priv_buf = NULL;
|
||||||
@ -295,7 +341,8 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
|
|||||||
BIGNUM *key;
|
BIGNUM *key;
|
||||||
|
|
||||||
ASN1_INTEGER *asn1key=NULL;
|
ASN1_INTEGER *asn1key=NULL;
|
||||||
if (!params) {
|
if (!params)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
key = gost_get_priv_key(pk);
|
key = gost_get_priv_key(pk);
|
||||||
@ -305,11 +352,11 @@ static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk)
|
|||||||
ASN1_INTEGER_free(asn1key);
|
ASN1_INTEGER_free(asn1key);
|
||||||
return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
|
return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_SEQUENCE,params,
|
||||||
priv_buf,priv_len);
|
priv_buf,priv_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent,
|
static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent,
|
||||||
ASN1_PCTX *pctx)
|
ASN1_PCTX *pctx)
|
||||||
{
|
{
|
||||||
BIGNUM *key;
|
BIGNUM *key;
|
||||||
if (!BIO_indent(out,indent,128)) return 0;
|
if (!BIO_indent(out,indent,128)) return 0;
|
||||||
key = gost_get_priv_key(pkey);
|
key = gost_get_priv_key(pkey);
|
||||||
@ -317,25 +364,27 @@ static int priv_print_gost (BIO *out,const EVP_PKEY *pkey, int indent,
|
|||||||
BN_print(out,key);
|
BN_print(out,key);
|
||||||
BN_free(key);
|
BN_free(key);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------*/
|
/* ---------------------------------------------------------------------*/
|
||||||
static int param_missing_gost94(const EVP_PKEY *pk)
|
static int param_missing_gost94(const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
|
const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
|
||||||
if (!dsa) return 1;
|
if (!dsa) return 1;
|
||||||
if (!dsa->q) return 1;
|
if (!dsa->q) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int param_missing_gost01(const EVP_PKEY *pk)
|
static int param_missing_gost01(const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
|
const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
|
||||||
if (!ec) return 1;
|
if (!ec) return 1;
|
||||||
if (!EC_KEY_get0_group(ec)) return 1;
|
if (!EC_KEY_get0_group(ec)) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
|
static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
|
||||||
{
|
{
|
||||||
const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
|
const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from);
|
||||||
DSA *dto = EVP_PKEY_get0(to);
|
DSA *dto = EVP_PKEY_get0(to);
|
||||||
if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to))
|
if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to))
|
||||||
@ -363,50 +412,58 @@ static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from)
|
|||||||
if (dto->priv_key)
|
if (dto->priv_key)
|
||||||
gost94_compute_public(dto);
|
gost94_compute_public(dto);
|
||||||
return 1;
|
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);
|
EC_KEY *eto = EVP_PKEY_get0(to);
|
||||||
const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from);
|
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,
|
GOSTerr(GOST_F_PARAM_COPY_GOST01,
|
||||||
GOST_R_INCOMPATIBLE_ALGORITHMS);
|
GOST_R_INCOMPATIBLE_ALGORITHMS);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!efrom) {
|
if (!efrom)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PARAM_COPY_GOST94,
|
GOSTerr(GOST_F_PARAM_COPY_GOST94,
|
||||||
GOST_R_KEY_PARAMETERS_MISSING);
|
GOST_R_KEY_PARAMETERS_MISSING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!eto) {
|
if (!eto)
|
||||||
|
{
|
||||||
eto = EC_KEY_new();
|
eto = EC_KEY_new();
|
||||||
EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
|
EVP_PKEY_assign(to,EVP_PKEY_base_id(from),eto);
|
||||||
}
|
}
|
||||||
EC_KEY_set_group(eto,EC_GROUP_dup(EC_KEY_get0_group(efrom)));
|
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);
|
gost2001_compute_public(eto);
|
||||||
}
|
}
|
||||||
return 1;
|
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 *da = EVP_PKEY_get0((EVP_PKEY *)a);
|
||||||
const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
|
const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
|
||||||
if (!BN_cmp(da->q,db->q)) return 1;
|
if (!BN_cmp(da->q,db->q)) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) {
|
|
||||||
|
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)))==
|
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)))) {
|
EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)b))))
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Public key functions * --------------------------------------*/
|
/* ---------- Public key functions * --------------------------------------*/
|
||||||
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
|
static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
|
||||||
{
|
{
|
||||||
X509_ALGOR *palg = NULL;
|
X509_ALGOR *palg = NULL;
|
||||||
const unsigned char *pubkey_buf = NULL;
|
const unsigned char *pubkey_buf = NULL;
|
||||||
unsigned char *databuf;
|
unsigned char *databuf;
|
||||||
@ -436,19 +493,21 @@ static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub)
|
|||||||
OPENSSL_free(databuf);
|
OPENSSL_free(databuf);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
ASN1_OBJECT *algobj = NULL;
|
ASN1_OBJECT *algobj = NULL;
|
||||||
ASN1_OCTET_STRING *octet = NULL;
|
ASN1_OCTET_STRING *octet = NULL;
|
||||||
void *pval = NULL;
|
void *pval = NULL;
|
||||||
unsigned char *buf=NULL,*databuf,*sptr;
|
unsigned char *buf=NULL,*databuf,*sptr;
|
||||||
int i,j,data_len,ret=0;
|
int i,j,data_len,ret=0;
|
||||||
|
|
||||||
int ptype;
|
int ptype = V_ASN1_UNDEF;
|
||||||
DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
|
DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
|
||||||
algobj = OBJ_nid2obj(EVP_PKEY_base_id(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);
|
ASN1_STRING *params = encode_gost_algor_params(pk);
|
||||||
pval = params;
|
pval = params;
|
||||||
ptype = V_ASN1_SEQUENCE;
|
ptype = V_ASN1_SEQUENCE;
|
||||||
@ -468,9 +527,10 @@ static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
ASN1_BIT_STRING_free(octet);
|
ASN1_BIT_STRING_free(octet);
|
||||||
if (ret <0) return 0;
|
if (ret <0) return 0;
|
||||||
return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
|
return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
|
static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
|
||||||
{
|
{
|
||||||
X509_ALGOR *palg = NULL;
|
X509_ALGOR *palg = NULL;
|
||||||
const unsigned char *pubkey_buf = NULL;
|
const unsigned char *pubkey_buf = NULL;
|
||||||
unsigned char *databuf;
|
unsigned char *databuf;
|
||||||
@ -497,10 +557,13 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
|
|||||||
{
|
{
|
||||||
databuf[j]=octet->data[i];
|
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);
|
X= getbnfrombuf(databuf,octet->length/2);
|
||||||
Y= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
|
Y= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Y= getbnfrombuf(databuf,octet->length/2);
|
Y= getbnfrombuf(databuf,octet->length/2);
|
||||||
X= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
|
X= getbnfrombuf(databuf+(octet->length/2),octet->length/2);
|
||||||
}
|
}
|
||||||
@ -524,9 +587,10 @@ static int pub_decode_gost01(EVP_PKEY *pk,X509_PUBKEY *pub)
|
|||||||
/*EC_POINT_free(pub_key);*/
|
/*EC_POINT_free(pub_key);*/
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
ASN1_OBJECT *algobj = NULL;
|
ASN1_OBJECT *algobj = NULL;
|
||||||
ASN1_OCTET_STRING *octet = NULL;
|
ASN1_OCTET_STRING *octet = NULL;
|
||||||
void *pval = NULL;
|
void *pval = NULL;
|
||||||
@ -535,10 +599,11 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
const EC_POINT *pub_key;
|
const EC_POINT *pub_key;
|
||||||
BIGNUM *X,*Y,*order;
|
BIGNUM *X,*Y,*order;
|
||||||
const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
|
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));
|
algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
|
||||||
if (pk->save_parameters) {
|
if (pk->save_parameters)
|
||||||
|
{
|
||||||
ASN1_STRING *params = encode_gost_algor_params(pk);
|
ASN1_STRING *params = encode_gost_algor_params(pk);
|
||||||
pval = params;
|
pval = params;
|
||||||
ptype = V_ASN1_SEQUENCE;
|
ptype = V_ASN1_SEQUENCE;
|
||||||
@ -546,7 +611,8 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
order = BN_new();
|
order = BN_new();
|
||||||
EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
|
EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
|
||||||
pub_key=EC_KEY_get0_public_key(ec);
|
pub_key=EC_KEY_get0_public_key(ec);
|
||||||
if (!pub_key) {
|
if (!pub_key)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PUB_ENCODE_GOST01,
|
GOSTerr(GOST_F_PUB_ENCODE_GOST01,
|
||||||
GOST_R_PUBLIC_KEY_UNDEFINED);
|
GOST_R_PUBLIC_KEY_UNDEFINED);
|
||||||
return 0;
|
return 0;
|
||||||
@ -559,10 +625,13 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
BN_free(order);
|
BN_free(order);
|
||||||
databuf = OPENSSL_malloc(data_len);
|
databuf = OPENSSL_malloc(data_len);
|
||||||
memset(databuf,0,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(X,databuf,data_len/2);
|
||||||
store_bignum(Y,databuf+data_len/2,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(X,databuf+data_len/2,data_len/2);
|
||||||
store_bignum(Y,databuf,data_len/2);
|
store_bignum(Y,databuf,data_len/2);
|
||||||
}
|
}
|
||||||
@ -571,7 +640,8 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
octet = ASN1_OCTET_STRING_new();
|
octet = ASN1_OCTET_STRING_new();
|
||||||
ASN1_STRING_set(octet,NULL,data_len);
|
ASN1_STRING_set(octet,NULL,data_len);
|
||||||
sptr=ASN1_STRING_data(octet);
|
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];
|
sptr[i]=databuf[j];
|
||||||
}
|
}
|
||||||
OPENSSL_free(databuf);
|
OPENSSL_free(databuf);
|
||||||
@ -579,19 +649,22 @@ static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
|
|||||||
ASN1_BIT_STRING_free(octet);
|
ASN1_BIT_STRING_free(octet);
|
||||||
if (ret <0) return 0;
|
if (ret <0) return 0;
|
||||||
return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
|
return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
|
static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b)
|
||||||
{
|
{
|
||||||
const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
|
const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a);
|
||||||
const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
|
const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b);
|
||||||
if (da && db && da->pub_key && db->pub_key
|
if (da && db && da->pub_key && db->pub_key
|
||||||
&& !BN_cmp(da->pub_key,db->pub_key)) {
|
&& !BN_cmp(da->pub_key,db->pub_key))
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_cmp_gost01(const EVP_PKEY *a,const EVP_PKEY *b)
|
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 *ea = EVP_PKEY_get0((EVP_PKEY *)a);
|
||||||
const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
|
const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b);
|
||||||
const EC_POINT *ka,*kb;
|
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;
|
if (!ka || !kb) return 0;
|
||||||
ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
|
ret = (0==EC_POINT_cmp(EC_KEY_get0_group(ea),ka,kb,NULL)) ;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
|
static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||||
ASN1_PCTX *pctx)
|
ASN1_PCTX *pctx)
|
||||||
{
|
{
|
||||||
const BIGNUM *key;
|
const BIGNUM *key;
|
||||||
if (!BIO_indent(out,indent,128)) return 0;
|
if (!BIO_indent(out,indent,128)) return 0;
|
||||||
key = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
|
key = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key;
|
||||||
if (!key) return 0;
|
if (!key) return 0;
|
||||||
BN_print(out,key);
|
BN_print(out,key);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
|
static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||||
ASN1_PCTX *pctx)
|
ASN1_PCTX *pctx)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_size_gost(const EVP_PKEY *pk)
|
static int pkey_size_gost(const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
return 64;
|
return 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_bits_gost(const EVP_PKEY *pk)
|
static int pkey_bits_gost(const EVP_PKEY *pk)
|
||||||
{
|
{
|
||||||
return 256;
|
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,
|
*ameth = EVP_PKEY_asn1_new(nid,
|
||||||
ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
|
ASN1_PKEY_SIGPARAM_NULL, pemstr, info);
|
||||||
if (!*ameth) return 0;
|
if (!*ameth) return 0;
|
||||||
switch (nid) {
|
switch (nid)
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94_cc:
|
case NID_id_GostR3410_94_cc:
|
||||||
case NID_id_GostR3410_94:
|
case NID_id_GostR3410_94:
|
||||||
EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
|
EVP_PKEY_asn1_set_free (*ameth, pkey_free_gost94);
|
||||||
@ -668,4 +748,4 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
@ -9,7 +9,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include "gost_asn1.h"
|
#include "gost_lcl.h"
|
||||||
|
|
||||||
ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
|
ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
|
||||||
ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
|
ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
|
||||||
|
@ -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
|
|
@ -1,17 +1,16 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* gost_crypt.c *
|
* gost_crypt.c *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
||||||
* OpenSSL interface to GOST 28147-89 cipher functions *
|
* OpenSSL interface to GOST 28147-89 cipher functions *
|
||||||
* Requires OpenSSL 0.9.9 for compilation *
|
* Requires OpenSSL 0.9.9 for compilation *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "crypt.h"
|
|
||||||
#include "gost89.h"
|
#include "gost89.h"
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
#include "e_gost_err.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,
|
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
|
#ifdef USE_SSL
|
||||||
@ -143,130 +142,154 @@ EVP_MD imit_gost_cpa =
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Correspondence between gost parameter OIDs and substitution blocks
|
* Correspondence between gost parameter OIDs and substitution blocks
|
||||||
* NID field is filed by register_gost_NID function in engine.c
|
* NID field is filed by register_gost_NID function in engine.c
|
||||||
* upon engine initialization
|
* upon engine initialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct gost_cipher_info gost_cipher_list[]={
|
struct gost_cipher_info gost_cipher_list[]=
|
||||||
|
{
|
||||||
/* NID */ /* Subst block */ /* Key meshing*/
|
/* NID */ /* Subst block */ /* Key meshing*/
|
||||||
/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
|
/*{NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0},*/
|
||||||
{NID_id_Gost28147_89_cc,&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_A_ParamSet,&Gost28147_CryptoProParamSetA,1},
|
||||||
{NID_id_Gost28147_89_CryptoPro_B_ParamSet,&Gost28147_CryptoProParamSetB,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_C_ParamSet,&Gost28147_CryptoProParamSetC,1},
|
||||||
{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
|
{NID_id_Gost28147_89_CryptoPro_D_ParamSet,&Gost28147_CryptoProParamSetD,1},
|
||||||
{NID_undef,NULL,0}
|
{NID_undef,NULL,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* get encryption parameters from crypto network settings
|
/* get encryption parameters from crypto network settings
|
||||||
FIXME For now we use environment var CRYPT_PARAMS as place to
|
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 */
|
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) {
|
const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj)
|
||||||
int nid;
|
{
|
||||||
struct gost_cipher_info *param;
|
int nid;
|
||||||
if (!obj) {
|
struct gost_cipher_info *param;
|
||||||
const char * params = getenv("CRYPT_PARAMS");
|
if (!obj)
|
||||||
|
{
|
||||||
|
const char * params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS);
|
||||||
if (!params || !strlen(params))
|
if (!params || !strlen(params))
|
||||||
return &gost_cipher_list[0];
|
return &gost_cipher_list[0];
|
||||||
|
|
||||||
nid = OBJ_txt2nid(params);
|
nid = OBJ_txt2nid(params);
|
||||||
if (nid == NID_undef) {
|
if (nid == NID_undef)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
|
GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,
|
||||||
GOST_R_INVALID_CIPHER_PARAM_OID);
|
GOST_R_INVALID_CIPHER_PARAM_OID);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
nid= OBJ_obj2nid(obj);
|
nid= OBJ_obj2nid(obj);
|
||||||
}
|
}
|
||||||
for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid;
|
for (param=gost_cipher_list;param->sblock!=NULL && param->nid!=nid;
|
||||||
param++);
|
param++);
|
||||||
if (!param->sblock) {
|
if (!param->sblock)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
|
GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS,GOST_R_INVALID_CIPHER_PARAMS);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
return param;
|
|
||||||
|
|
||||||
}
|
|
||||||
/* Sets cipher param from paramset NID. */
|
/* Sets cipher param from paramset NID. */
|
||||||
int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c,int 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)));
|
const struct gost_cipher_info *param;
|
||||||
if (!param) return 0;
|
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 */
|
/* Initializes EVP_CIPHER_CTX by paramset NID */
|
||||||
static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
const unsigned char *iv, int enc, int paramNID,int mode) {
|
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;
|
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
||||||
if (key) gost_key(&(c->cctx),key);
|
if (ctx->app_data == NULL)
|
||||||
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
{
|
||||||
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
if (!gost_cipher_set_param(c,paramNID)) return 0;
|
||||||
return 1;
|
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 */
|
/* Initializes EVP_CIPHER_CTX with fixed cryptopro A paramset */
|
||||||
int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
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)
|
||||||
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
{
|
||||||
gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
|
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
||||||
c->key_meshing=1;
|
gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
|
||||||
c->count=0;
|
c->key_meshing=1;
|
||||||
gost_key(&(c->cctx),key);
|
c->count=0;
|
||||||
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
gost_key(&(c->cctx),key);
|
||||||
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||||
return 1;
|
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||||
}
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializes EVP_CIPHER_CTX with fixed vizir paramset */
|
/* Initializes EVP_CIPHER_CTX with fixed vizir paramset */
|
||||||
int gost_cipher_init_vizir(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
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)
|
||||||
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
{
|
||||||
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
|
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
||||||
c->key_meshing=0;
|
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
|
||||||
c->count=0;
|
c->key_meshing=0;
|
||||||
gost_key(&(c->cctx),key);
|
c->count=0;
|
||||||
|
gost_key(&(c->cctx),key);
|
||||||
|
|
||||||
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
if(iv) memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||||
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initializes EVP_CIPHER_CTX with default values */
|
/* Initializes EVP_CIPHER_CTX with default values */
|
||||||
int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
|
||||||
const unsigned char *iv, int enc) {
|
const unsigned char *iv, int enc)
|
||||||
return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
|
{
|
||||||
}
|
return gost_cipher_init_param(ctx,key,iv,enc,NID_undef,EVP_CIPH_CFB_MODE);
|
||||||
|
}
|
||||||
/* Wrapper around gostcrypt function from gost89.c which perform
|
/* Wrapper around gostcrypt function from gost89.c which perform
|
||||||
* key meshing when nesseccary
|
* key meshing when nesseccary
|
||||||
*/
|
*/
|
||||||
static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf) {
|
static void gost_crypt_mesh (void *ctx,unsigned char *iv,unsigned char *buf)
|
||||||
|
{
|
||||||
struct ossl_gost_cipher_ctx *c = ctx;
|
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);
|
cryptopro_key_meshing(&(c->cctx),iv);
|
||||||
}
|
}
|
||||||
gostcrypt(&(c->cctx),iv,buf);
|
gostcrypt(&(c->cctx),iv,buf);
|
||||||
c->count+=8;
|
c->count+=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf) {
|
static void gost_cnt_next (void *ctx, unsigned char *iv, unsigned char *buf)
|
||||||
struct ossl_gost_cipher_ctx *c = ctx;
|
{
|
||||||
word32 g,go;
|
struct ossl_gost_cipher_ctx *c = ctx;
|
||||||
unsigned char buf1[8];
|
word32 g,go;
|
||||||
if (c->count && c->key_meshing && c->count %1024 ==0) {
|
unsigned char buf1[8];
|
||||||
|
if (c->count && c->key_meshing && c->count %1024 ==0)
|
||||||
|
{
|
||||||
cryptopro_key_meshing(&(c->cctx),iv);
|
cryptopro_key_meshing(&(c->cctx),iv);
|
||||||
}
|
}
|
||||||
if (c->count==0) {
|
if (c->count==0)
|
||||||
gostcrypt(&(c->cctx),iv,buf1);
|
{
|
||||||
} else {
|
gostcrypt(&(c->cctx),iv,buf1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
memcpy(buf1,iv,8);
|
memcpy(buf1,iv,8);
|
||||||
}
|
}
|
||||||
g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
|
g = buf1[0]|(buf1[1]<<8)|(buf1[2]<<16)|(buf1[3]<<24);
|
||||||
g += 0x01010101;
|
g += 0x01010101;
|
||||||
buf1[0]=g&0xff; buf1[1]=(g>>8)&0xff; buf1[2]=(g>>16)&0xff; buf1[3]=(g>>24)&0xff;
|
buf1[0]=g&0xff; buf1[1]=(g>>8)&0xff; buf1[2]=(g>>16)&0xff; buf1[3]=(g>>24)&0xff;
|
||||||
@ -278,116 +301,139 @@ gostcrypt(&(c->cctx),iv,buf1);
|
|||||||
buf1[4]=g&0xff; buf1[5]=(g>>8)&0xff; buf1[6]=(g>>16)&0xff; buf1[7]=(g>>24)&0xff;
|
buf1[4]=g&0xff; buf1[5]=(g>>8)&0xff; buf1[6]=(g>>16)&0xff; buf1[7]=(g>>24)&0xff;
|
||||||
memcpy(iv,buf1,8);
|
memcpy(iv,buf1,8);
|
||||||
gostcrypt(&(c->cctx),buf1,buf);
|
gostcrypt(&(c->cctx),buf1,buf);
|
||||||
c->count +=8;
|
c->count +=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GOST encryption in CFB mode */
|
/* GOST encryption in CFB mode */
|
||||||
int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
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)
|
||||||
const unsigned char *in_ptr=in;
|
{
|
||||||
unsigned char *out_ptr=out;
|
const unsigned char *in_ptr=in;
|
||||||
int i=0;
|
unsigned char *out_ptr=out;
|
||||||
int j;
|
int i=0;
|
||||||
|
int j=0;
|
||||||
/* process partial block if any */
|
/* process partial block if any */
|
||||||
if (ctx->num)
|
if (ctx->num)
|
||||||
{
|
{
|
||||||
for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
|
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;
|
if (!ctx->encrypt) ctx->buf[j+8]=*in_ptr;
|
||||||
*out_ptr=ctx->buf[j]^(*in_ptr);
|
*out_ptr=ctx->buf[j]^(*in_ptr);
|
||||||
if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
|
if (ctx->encrypt) ctx->buf[j+8]=*out_ptr;
|
||||||
}
|
}
|
||||||
if (j==8) {
|
if (j==8)
|
||||||
|
{
|
||||||
memcpy(ctx->iv,ctx->buf+8,8);
|
memcpy(ctx->iv,ctx->buf+8,8);
|
||||||
ctx->num=0;
|
ctx->num=0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ctx->num=j;
|
ctx->num=j;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) {
|
for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
|
||||||
|
{
|
||||||
/*block cipher current iv */
|
/*block cipher current iv */
|
||||||
gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
|
gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
|
||||||
/*xor next block of input text with it and output it*/
|
/*xor next block of input text with it and output it*/
|
||||||
/*output this block */
|
/*output this block */
|
||||||
if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
|
if (!ctx->encrypt) memcpy(ctx->iv,in_ptr,8);
|
||||||
for (j=0;j<8;j++) {
|
for (j=0;j<8;j++)
|
||||||
|
{
|
||||||
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
||||||
}
|
}
|
||||||
/* Encrypt */
|
/* Encrypt */
|
||||||
/* Next iv is next block of cipher text*/
|
/* Next iv is next block of cipher text*/
|
||||||
if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
|
if (ctx->encrypt) memcpy(ctx->iv,out_ptr,8);
|
||||||
}
|
}
|
||||||
/* Process rest of buffer */
|
/* Process rest of buffer */
|
||||||
if (i<inl) {
|
if (i<inl)
|
||||||
|
{
|
||||||
gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
|
gost_crypt_mesh(ctx->cipher_data,ctx->iv,ctx->buf);
|
||||||
if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
|
if (!ctx->encrypt) memcpy(ctx->buf+8,in_ptr,j);
|
||||||
for (j=0;i<inl;j++,i++) {
|
for (j=0;i<inl;j++,i++)
|
||||||
|
{
|
||||||
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
||||||
}
|
}
|
||||||
ctx->num = j;
|
ctx->num = j;
|
||||||
if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
|
if (ctx->encrypt) memcpy(ctx->buf+8,out_ptr,j);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ctx->num = 0;
|
ctx->num = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out,
|
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)
|
||||||
const unsigned char *in_ptr=in;
|
{
|
||||||
unsigned char *out_ptr=out;
|
const unsigned char *in_ptr=in;
|
||||||
int i=0;
|
unsigned char *out_ptr=out;
|
||||||
int j;
|
int i=0;
|
||||||
|
int j;
|
||||||
/* process partial block if any */
|
/* process partial block if any */
|
||||||
if (ctx->num)
|
if (ctx->num)
|
||||||
{
|
{
|
||||||
for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
|
for (j=ctx->num,i=0;j<8 && i<inl;j++,i++,in_ptr++,out_ptr++)
|
||||||
{
|
{
|
||||||
*out_ptr=ctx->buf[j]^(*in_ptr);
|
*out_ptr=ctx->buf[j]^(*in_ptr);
|
||||||
}
|
}
|
||||||
if (j==8) {
|
if (j==8)
|
||||||
|
{
|
||||||
ctx->num=0;
|
ctx->num=0;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ctx->num=j;
|
ctx->num=j;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8) {
|
for (;i+8<inl;i+=8,in_ptr+=8,out_ptr+=8)
|
||||||
|
{
|
||||||
/*block cipher current iv */
|
/*block cipher current iv */
|
||||||
/* Encrypt */
|
/* Encrypt */
|
||||||
gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
|
gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
|
||||||
/*xor next block of input text with it and output it*/
|
/*xor next block of input text with it and output it*/
|
||||||
/*output this block */
|
/*output this block */
|
||||||
for (j=0;j<8;j++) {
|
for (j=0;j<8;j++)
|
||||||
|
{
|
||||||
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Process rest of buffer */
|
/* Process rest of buffer */
|
||||||
if (i<inl) {
|
if (i<inl)
|
||||||
|
{
|
||||||
gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
|
gost_cnt_next(ctx->cipher_data,ctx->iv,ctx->buf);
|
||||||
for (j=0;i<inl;j++,i++) {
|
for (j=0;i<inl;j++,i++)
|
||||||
|
{
|
||||||
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
out_ptr[j]=ctx->buf[j]^in_ptr[j];
|
||||||
}
|
}
|
||||||
ctx->num = j;
|
ctx->num = j;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ctx->num = 0;
|
ctx->num = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleaning up of EVP_CIPHER_CTX */
|
/* Cleaning up of EVP_CIPHER_CTX */
|
||||||
int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx)
|
||||||
{
|
{
|
||||||
gost_destroy((gost_ctx *)ctx->cipher_data);
|
gost_destroy((gost_ctx *)ctx->cipher_data);
|
||||||
return 1;
|
ctx->app_data = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
/* Control function for gost cipher */
|
/* Control function for gost cipher */
|
||||||
int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
|
int gost_cipher_ctl(EVP_CIPHER_CTX *ctx,int type,int arg,void *ptr)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EVP_CTRL_RAND_KEY:
|
case EVP_CTRL_RAND_KEY:
|
||||||
{
|
{
|
||||||
if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
|
if (RAND_bytes((unsigned char *)ptr,ctx->key_len)<=0)
|
||||||
@ -400,159 +446,184 @@ switch (type)
|
|||||||
default:
|
default:
|
||||||
GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
|
GOSTerr(GOST_F_GOST_CIPHER_CTL,GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set cipher parameters from ASN1 structure */
|
/* Set cipher parameters from ASN1 structure */
|
||||||
int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
|
int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
|
||||||
{
|
{
|
||||||
int len=0;
|
int len=0;
|
||||||
unsigned char *buf=NULL;
|
unsigned char *buf=NULL;
|
||||||
unsigned char *p=NULL;
|
unsigned char *p=NULL;
|
||||||
struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
|
struct ossl_gost_cipher_ctx *c = ctx->cipher_data;
|
||||||
GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
|
GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new();
|
||||||
ASN1_OCTET_STRING *os = NULL;
|
ASN1_OCTET_STRING *os = NULL;
|
||||||
if (!gcp) {
|
if (!gcp)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) {
|
if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len))
|
||||||
|
{
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
GOST_CIPHER_PARAMS_free(gcp);
|
||||||
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ASN1_OBJECT_free(gcp->enc_param_set);
|
ASN1_OBJECT_free(gcp->enc_param_set);
|
||||||
gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
|
gcp->enc_param_set = OBJ_nid2obj(c->paramNID);
|
||||||
|
|
||||||
len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
|
len = i2d_GOST_CIPHER_PARAMS(gcp, NULL);
|
||||||
p = buf = (unsigned char*)OPENSSL_malloc(len);
|
p = buf = (unsigned char*)OPENSSL_malloc(len);
|
||||||
if (!buf) {
|
if (!buf)
|
||||||
|
{
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
GOST_CIPHER_PARAMS_free(gcp);
|
||||||
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
i2d_GOST_CIPHER_PARAMS(gcp, &p);
|
i2d_GOST_CIPHER_PARAMS(gcp, &p);
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
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);
|
OPENSSL_free(buf);
|
||||||
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
OPENSSL_free(buf);
|
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 */
|
/* Store parameters into ASN1 structure */
|
||||||
int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
|
int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx,ASN1_TYPE *params)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int len;
|
int len;
|
||||||
GOST_CIPHER_PARAMS *gcp = NULL;
|
GOST_CIPHER_PARAMS *gcp = NULL;
|
||||||
unsigned char *p = params->value.sequence->data;
|
unsigned char *p = params->value.sequence->data;
|
||||||
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
struct ossl_gost_cipher_ctx *c=ctx->cipher_data;
|
||||||
if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) {
|
if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE)
|
||||||
|
{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
|
gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p,
|
||||||
params->value.sequence->length);
|
params->value.sequence->length);
|
||||||
|
|
||||||
len = gcp->iv->length;
|
len = gcp->iv->length;
|
||||||
if (len != ctx->cipher->iv_len) {
|
if (len != ctx->cipher->iv_len)
|
||||||
|
{
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
GOST_CIPHER_PARAMS_free(gcp);
|
||||||
GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
|
GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS,
|
||||||
GOST_R_INVALID_IV_LENGTH);
|
GOST_R_INVALID_IV_LENGTH);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set))) {
|
if (!gost_cipher_set_param(c,OBJ_obj2nid(gcp->enc_param_set)))
|
||||||
|
{
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
GOST_CIPHER_PARAMS_free(gcp);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(ctx->oiv, gcp->iv->data, len);
|
memcpy(ctx->oiv, gcp->iv->data, len);
|
||||||
|
|
||||||
GOST_CIPHER_PARAMS_free(gcp);
|
GOST_CIPHER_PARAMS_free(gcp);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
|
|
||||||
int gost_imit_init_vizir(EVP_MD_CTX *ctx) {
|
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));
|
struct ossl_gost_imit_ctx *c = ctx->md_data;
|
||||||
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
|
memset(c,0,sizeof(struct ossl_gost_imit_ctx));
|
||||||
return 1;
|
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));
|
int gost_imit_init_cpa(EVP_MD_CTX *ctx)
|
||||||
c->key_meshing=1;
|
{
|
||||||
gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
|
struct ossl_gost_imit_ctx *c = ctx->md_data;
|
||||||
return 1;
|
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)
|
static void mac_block_mesh(struct ossl_gost_imit_ctx *c,unsigned char *data)
|
||||||
{
|
{
|
||||||
char buffer[8];
|
char buffer[8];
|
||||||
/* We are using local buffer for iv because CryptoPro doesn't
|
/* We are using local buffer for iv because CryptoPro doesn't
|
||||||
* interpret internal state of MAC algorithm as iv during keymeshing
|
* interpret internal state of MAC algorithm as iv during keymeshing
|
||||||
* (but does initialize internal state from iv in key transport
|
* (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);
|
cryptopro_key_meshing(&(c->cctx),buffer);
|
||||||
}
|
}
|
||||||
mac_block(&(c->cctx),c->buffer,data);
|
mac_block(&(c->cctx),c->buffer,data);
|
||||||
c->count +=8;
|
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;
|
struct ossl_gost_imit_ctx *c = ctx->md_data;
|
||||||
const unsigned char *p = data;
|
const unsigned char *p = data;
|
||||||
size_t bytes = count,i;
|
size_t bytes = count,i;
|
||||||
if (!(c->key_set)) return 0;
|
if (!(c->key_set)) return 0;
|
||||||
if (c->bytes_left) {
|
if (c->bytes_left)
|
||||||
for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++) {
|
{
|
||||||
|
for (i=c->bytes_left;i<8&&bytes>0;bytes--,i++,p++)
|
||||||
|
{
|
||||||
c->partial_block[i]=*p;
|
c->partial_block[i]=*p;
|
||||||
}
|
}
|
||||||
if (i==8) {
|
if (i==8)
|
||||||
|
{
|
||||||
mac_block_mesh(c,c->partial_block);
|
mac_block_mesh(c,c->partial_block);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
c->bytes_left = i;
|
c->bytes_left = i;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (bytes>8) {
|
while (bytes>8)
|
||||||
|
{
|
||||||
mac_block_mesh(c,p);
|
mac_block_mesh(c,p);
|
||||||
p+=8;
|
p+=8;
|
||||||
bytes-=8;
|
bytes-=8;
|
||||||
}
|
}
|
||||||
if (bytes>0) {
|
if (bytes>0)
|
||||||
|
{
|
||||||
memcpy(c->partial_block,p,bytes);
|
memcpy(c->partial_block,p,bytes);
|
||||||
c->bytes_left=bytes;
|
c->bytes_left=bytes;
|
||||||
}
|
}
|
||||||
return 1;
|
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;
|
struct ossl_gost_imit_ctx *c = ctx->md_data;
|
||||||
if (c->bytes_left) {
|
if (c->bytes_left)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i=c->bytes_left;i<8;i++) {
|
for (i=c->bytes_left;i<8;i++)
|
||||||
|
{
|
||||||
c->partial_block[i]=0;
|
c->partial_block[i]=0;
|
||||||
}
|
}
|
||||||
mac_block_mesh(c,c->partial_block);
|
mac_block_mesh(c,c->partial_block);
|
||||||
}
|
}
|
||||||
get_mac(c->buffer,32,md);
|
get_mac(c->buffer,32,md);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) {
|
|
||||||
switch (type) {
|
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:
|
case EVP_MD_CTRL_GET_TLS_MAC_KEY_LENGTH:
|
||||||
*((unsigned int*)(ptr)) = 32;
|
*((unsigned int*)(ptr)) = 32;
|
||||||
return 1;
|
return 1;
|
||||||
@ -565,15 +636,19 @@ int gost_imit_ctrl(EVP_MD_CTX *ctx,int type, int arg, void *ptr) {
|
|||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int gost_imit_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) {
|
|
||||||
|
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));
|
memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_imit_ctx));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up imit ctx */
|
/* 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));
|
memset(ctx->md_data,0,sizeof(struct ossl_gost_imit_ctx));
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
74
engines/ccgost/gost_ctl.c
Normal file
74
engines/ccgost/gost_ctl.c
Normal file
@ -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;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* engine.c *
|
* gost_eng.c *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
||||||
@ -12,10 +12,7 @@
|
|||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include <openssl/obj_mac.h>
|
#include <openssl/obj_mac.h>
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
#include "md.h"
|
#include "gost_lcl.h"
|
||||||
#include "crypt.h"
|
|
||||||
#include "meth.h"
|
|
||||||
|
|
||||||
static const char *engine_gost_id = "gost";
|
static const char *engine_gost_id = "gost";
|
||||||
static const char *engine_gost_name = "Reference implementation of GOST engine";
|
static const char *engine_gost_name = "Reference implementation of GOST engine";
|
||||||
|
|
||||||
@ -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;
|
*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;
|
return 1;
|
||||||
}
|
}
|
||||||
static int gost_engine_finish(ENGINE *e) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int gost_engine_destroy(ENGINE *e) {
|
static int gost_engine_finish(ENGINE *e)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bind_gost (ENGINE *e,const char *id) {
|
static int gost_engine_destroy(ENGINE *e)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bind_gost (ENGINE *e,const char *id)
|
||||||
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (id && strcmp(id, engine_gost_id)) return 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");
|
printf("ENGINE_set_id failed\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (!ENGINE_set_name(e, engine_gost_name)) {
|
if (!ENGINE_set_name(e, engine_gost_name))
|
||||||
|
{
|
||||||
printf("ENGINE_set_name failed\n");
|
printf("ENGINE_set_name failed\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (!ENGINE_set_digests(e, gost_digests)) {
|
if (!ENGINE_set_digests(e, gost_digests))
|
||||||
|
{
|
||||||
printf("ENGINE_set_digests failed\n");
|
printf("ENGINE_set_digests failed\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (! ENGINE_set_ciphers(e, gost_ciphers)) {
|
if (! ENGINE_set_ciphers(e, gost_ciphers))
|
||||||
|
{
|
||||||
printf("ENGINE_set_ciphers failed\n");
|
printf("ENGINE_set_ciphers failed\n");
|
||||||
goto end;
|
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");
|
printf("ENGINE_set_pkey_meths failed\n");
|
||||||
goto end;
|
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");
|
printf("ENGINE_set_pkey_asn1_meths failed\n");
|
||||||
goto end;
|
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)
|
if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
|
||||||
|| ! ENGINE_set_init_function(e,gost_engine_init)
|
|| ! 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_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;
|
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 */
|
/* These two actually should go in LIST_ADD command */
|
||||||
|| ! EVP_add_cipher(&cipher_gost)
|
|| ! EVP_add_cipher(&cipher_gost)
|
||||||
|| ! EVP_add_digest(&digest_gost)
|
|| ! EVP_add_digest(&digest_gost)
|
||||||
) goto end;
|
)
|
||||||
|
{
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
ERR_load_GOST_strings();
|
ERR_load_GOST_strings();
|
||||||
ret = 1;
|
ret = 1;
|
||||||
end:
|
end:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern __declspec( dllexport )
|
extern __declspec( dllexport )
|
||||||
@ -131,74 +154,63 @@ extern __declspec( dllexport )
|
|||||||
|
|
||||||
IMPLEMENT_DYNAMIC_CHECK_FN();
|
IMPLEMENT_DYNAMIC_CHECK_FN();
|
||||||
//#else
|
//#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 */
|
//#endif /* OPENSSL_NO_DYNAMIC_ENGINE */
|
||||||
|
|
||||||
static int gost_digests(ENGINE *e, const EVP_MD **digest,
|
static int gost_digests(ENGINE *e, const EVP_MD **digest,
|
||||||
const int **nids, int nid)
|
const int **nids, int nid)
|
||||||
{
|
{
|
||||||
int ok =1 ;
|
int ok =1 ;
|
||||||
if (!digest) {
|
if (!digest)
|
||||||
|
{
|
||||||
*nids = gost_digest_nids;
|
*nids = gost_digest_nids;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//printf("Digest no %d requested\n",nid);
|
//printf("Digest no %d requested\n",nid);
|
||||||
if(nid == NID_id_GostR3411_94) {
|
if(nid == NID_id_GostR3411_94)
|
||||||
|
{
|
||||||
*digest = &digest_gost;
|
*digest = &digest_gost;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ok =0;
|
ok =0;
|
||||||
*digest = NULL;
|
*digest = NULL;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
|
static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
|
||||||
const int **nids, int nid) {
|
const int **nids, int nid)
|
||||||
|
{
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
if (!cipher) {
|
if (!cipher)
|
||||||
|
{
|
||||||
*nids = gost_cipher_nids;
|
*nids = gost_cipher_nids;
|
||||||
return 1; /* Only one cipher supported */
|
return 1; /* Only one cipher supported */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nid == NID_id_Gost28147_89) {
|
if(nid == NID_id_Gost28147_89)
|
||||||
|
{
|
||||||
*cipher = &cipher_gost;
|
*cipher = &cipher_gost;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ok = 0;
|
ok = 0;
|
||||||
*cipher = NULL;
|
*cipher = NULL;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
|
static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
|
||||||
const int **nids, int nid)
|
const int **nids, int nid)
|
||||||
{
|
{
|
||||||
if (!pmeth) {
|
if (!pmeth)
|
||||||
|
{
|
||||||
*nids = gost_pkey_meth_nids;
|
*nids = gost_pkey_meth_nids;
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (nid) {
|
switch (nid)
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94_cc: *pmeth = pmeth_GostR3410_94_cc; return 1;
|
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_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_cc: *pmeth = pmeth_GostR3410_2001_cc; return 1;
|
||||||
@ -208,16 +220,18 @@ static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
|
|||||||
|
|
||||||
*pmeth = NULL;
|
*pmeth = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
|
static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
|
||||||
const int **nids, int nid)
|
const int **nids, int nid)
|
||||||
{
|
{
|
||||||
if (!ameth) {
|
if (!ameth)
|
||||||
|
{
|
||||||
*nids = gost_pkey_meth_nids;
|
*nids = gost_pkey_meth_nids;
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
switch (nid) {
|
switch (nid)
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94_cc: *ameth = ameth_GostR3410_94_cc; return 1;
|
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_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_cc: *ameth = ameth_GostR3410_2001_cc; return 1;
|
||||||
@ -227,4 +241,29 @@ static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
|
|||||||
|
|
||||||
*ameth = NULL;
|
*ameth = NULL;
|
||||||
return 0;
|
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
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "gost89.h"
|
#include "gost89.h"
|
||||||
#include "keywrap.h"
|
#include "gost_keywrap.h"
|
||||||
|
|
||||||
/* Diversifies key using random UserKey Material
|
/* Diversifies key using random UserKey Material
|
||||||
* Implements RFC 4357 p 6.5 key diversification algorithm
|
* Implements RFC 4357 p 6.5 key diversification algorithm
|
||||||
@ -20,22 +20,27 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
|
void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const unsigned char *ukm, unsigned char *outputKey)
|
||||||
{
|
{
|
||||||
|
|
||||||
u4 k,s1,s2;
|
u4 k,s1,s2;
|
||||||
int i,j,mask;
|
int i,j,mask;
|
||||||
unsigned char S[8];
|
unsigned char S[8];
|
||||||
memcpy(outputKey,inputKey,32);
|
memcpy(outputKey,inputKey,32);
|
||||||
for (i=0;i<8;i++) {
|
for (i=0;i<8;i++)
|
||||||
|
{
|
||||||
/* Make array of integers from key */
|
/* Make array of integers from key */
|
||||||
/* Compute IV S*/
|
/* Compute IV S*/
|
||||||
s1=0,s2=0;
|
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)|
|
k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
|
||||||
(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
|
(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
|
||||||
if (mask & ukm[i]) {
|
if (mask & ukm[i])
|
||||||
|
{
|
||||||
s1+=k;
|
s1+=k;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
s2+=k;
|
s2+=k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,7 +49,7 @@ void keyDiversifyCryptoPro(gost_ctx *ctx,const unsigned char *inputKey, const un
|
|||||||
gost_key(ctx,outputKey);
|
gost_key(ctx,outputKey);
|
||||||
gost_enc_cfb(ctx,S,outputKey,outputKey,4);
|
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,
|
int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
|
||||||
const unsigned char *sessionKey, unsigned char *wrappedKey)
|
const unsigned char *sessionKey, unsigned char *wrappedKey)
|
||||||
{
|
{
|
||||||
unsigned char kek_ukm[32];
|
unsigned char kek_ukm[32];
|
||||||
keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
|
keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
|
||||||
gost_key(ctx,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_enc(ctx,sessionKey,wrappedKey+8,4);
|
||||||
gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
|
gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Unwraps key using RFC 4357 6.4
|
* Unwraps key using RFC 4357 6.4
|
||||||
* ctx - gost encryption context, initialized with some S-boxes
|
* ctx - gost encryption context, initialized with some S-boxes
|
||||||
@ -80,7 +85,7 @@ int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const un
|
|||||||
|
|
||||||
int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
|
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];
|
unsigned char kek_ukm[32],cek_mac[4];
|
||||||
keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey
|
keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey
|
||||||
/* First 8 bytes of wrapped Key is ukm */
|
/* First 8 bytes of wrapped Key is ukm */
|
||||||
@ -88,10 +93,11 @@ int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
|
|||||||
gost_key(ctx,kek_ukm);
|
gost_key(ctx,kek_ukm);
|
||||||
gost_dec(ctx,wrappedKey+8,sessionKey,4);
|
gost_dec(ctx,wrappedKey+8,sessionKey,4);
|
||||||
gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
|
gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
|
||||||
if (memcmp(cek_mac,wrappedKey+40,4)) {
|
if (memcmp(cek_mac,wrappedKey+40,4))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* keywrap.c *
|
* gost_keywrap.h *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
206
engines/ccgost/gost_lcl.h
Normal file
206
engines/ccgost/gost_lcl.h
Normal file
@ -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
|
@ -7,7 +7,7 @@
|
|||||||
* Requires OpenSSL 0.9.9 for compilation *
|
* Requires OpenSSL 0.9.9 for compilation *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "md.h"
|
#include "gost_lcl.h"
|
||||||
#include "gosthash.h"
|
#include "gosthash.h"
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
|
|||||||
static int gost_digest_cleanup(EVP_MD_CTX *ctx);
|
static int gost_digest_cleanup(EVP_MD_CTX *ctx);
|
||||||
|
|
||||||
EVP_MD digest_gost=
|
EVP_MD digest_gost=
|
||||||
{
|
{
|
||||||
NID_id_GostR3411_94,
|
NID_id_GostR3411_94,
|
||||||
NID_undef,
|
NID_undef,
|
||||||
32,
|
32,
|
||||||
@ -35,35 +35,36 @@ EVP_MD digest_gost=
|
|||||||
32,
|
32,
|
||||||
sizeof(struct ossl_gost_digest_ctx ),
|
sizeof(struct ossl_gost_digest_ctx ),
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
int gost_digest_init(EVP_MD_CTX *ctx)
|
int gost_digest_init(EVP_MD_CTX *ctx)
|
||||||
{
|
{
|
||||||
struct ossl_gost_digest_ctx *c = ctx->md_data;
|
struct ossl_gost_digest_ctx *c = ctx->md_data;
|
||||||
memset(&(c->dctx),0,sizeof(gost_hash_ctx));
|
memset(&(c->dctx),0,sizeof(gost_hash_ctx));
|
||||||
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
|
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
|
||||||
c->dctx.cipher_ctx= &(c->cctx);
|
c->dctx.cipher_ctx= &(c->cctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count)
|
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);
|
return hash_block((gost_hash_ctx *)ctx->md_data,data,count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
|
int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
|
||||||
{
|
{
|
||||||
return finish_hash((gost_hash_ctx *)ctx->md_data,md);
|
return finish_hash((gost_hash_ctx *)ctx->md_data,md);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
|
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));
|
memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
|
||||||
return 1;
|
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));
|
memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
@ -7,7 +7,7 @@
|
|||||||
* OpenSSL 0.9.9 libraries required to compile and use *
|
* OpenSSL 0.9.9 libraries required to compile and use *
|
||||||
* this code *
|
* this code *
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
#include "paramset.h"
|
#include "gost_params.h"
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
/* Parameters of GOST 34.10 */
|
/* Parameters of GOST 34.10 */
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* paramset.h *
|
* gost_params.h *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* pmeth.c *
|
* gost_pmeth.c *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
||||||
@ -13,53 +13,57 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "meth.h"
|
#include "gost_params.h"
|
||||||
#include "pmeth.h"
|
#include "gost_lcl.h"
|
||||||
#include "sign.h"
|
|
||||||
#include "gostkeyx.h"
|
|
||||||
#include "paramset.h"
|
|
||||||
#include "tools.h"
|
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
/*-------init, cleanup, copy - uniform for all algs ---------------*/
|
/*-------init, cleanup, copy - uniform for all algs ---------------*/
|
||||||
/* Allocates new gost_pmeth_data structure and assigns it as data */
|
/* 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;
|
struct gost_pmeth_data *data;
|
||||||
data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
|
data = OPENSSL_malloc(sizeof(struct gost_pmeth_data));
|
||||||
if (!data) return 0;
|
if (!data) return 0;
|
||||||
memset(data,0,sizeof(struct gost_pmeth_data));
|
memset(data,0,sizeof(struct gost_pmeth_data));
|
||||||
EVP_PKEY_CTX_set_data(ctx,data);
|
EVP_PKEY_CTX_set_data(ctx,data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copies contents of gost_pmeth_data structure */
|
/* Copies contents of gost_pmeth_data structure */
|
||||||
static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
|
||||||
{
|
{
|
||||||
struct gost_pmeth_data *dst_data,*src_data;
|
struct gost_pmeth_data *dst_data,*src_data;
|
||||||
if (!pkey_gost_init(dst)) {
|
if (!pkey_gost_init(dst))
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
src_data = EVP_PKEY_CTX_get_data(src);
|
src_data = EVP_PKEY_CTX_get_data(src);
|
||||||
dst_data = EVP_PKEY_CTX_get_data(dst);
|
dst_data = EVP_PKEY_CTX_get_data(dst);
|
||||||
*dst_data = *src_data;
|
*dst_data = *src_data;
|
||||||
if (src_data -> eph_seckey) {
|
if (src_data -> eph_seckey)
|
||||||
|
{
|
||||||
dst_data ->eph_seckey = NULL;
|
dst_data ->eph_seckey = NULL;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Frees up gost_pmeth_data structure */
|
/* 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);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
||||||
if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey);
|
if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey);
|
||||||
OPENSSL_free(data);
|
OPENSSL_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------- control functions ------------------------------*/
|
/* --------------------- control functions ------------------------------*/
|
||||||
static int pkey_gost_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
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);
|
struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case EVP_PKEY_CTRL_MD:
|
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);
|
GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -75,45 +79,49 @@ static int pkey_gost_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||||||
|
|
||||||
case EVP_PKEY_CTRL_GOST_PARAMSET:
|
case EVP_PKEY_CTRL_GOST_PARAMSET:
|
||||||
pctx->sign_param_nid = (int)p1;
|
pctx->sign_param_nid = (int)p1;
|
||||||
pctx->crypt_param_nid= (int)p2;
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost_ctrl94cc_str(EVP_PKEY_CTX *ctx,
|
static int pkey_gost_ctrl94cc_str(EVP_PKEY_CTX *ctx,
|
||||||
const char *type, const char *value)
|
const char *type, const char *value)
|
||||||
{
|
{
|
||||||
if(!strcmp(type, param_ctrl_string)) {
|
if(!strcmp(type, param_ctrl_string))
|
||||||
|
{
|
||||||
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
||||||
NID_id_GostR3410_94_CryptoPro_A_ParamSet,
|
NID_id_GostR3410_94_CryptoPro_A_ParamSet,
|
||||||
(void *)NID_id_Gost28147_89_cc);
|
NULL);
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost_ctrl01cc_str(EVP_PKEY_CTX *ctx,
|
static int pkey_gost_ctrl01cc_str(EVP_PKEY_CTX *ctx,
|
||||||
const char *type, const char *value)
|
const char *type, const char *value)
|
||||||
{
|
{
|
||||||
if(!strcmp(type, param_ctrl_string)) {
|
if(!strcmp(type, param_ctrl_string))
|
||||||
|
{
|
||||||
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
||||||
NID_id_GostR3410_2001_ParamSet_cc,
|
NID_id_GostR3410_2001_ParamSet_cc,NULL);
|
||||||
(void *)
|
|
||||||
NID_id_Gost28147_89_cc);
|
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
|
static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
|
||||||
const char *type, const char *value)
|
const char *type, const char *value)
|
||||||
{
|
{
|
||||||
int param_nid=0;
|
int param_nid=0;
|
||||||
if(!strcmp(type, param_ctrl_string)) {
|
if(!strcmp(type, param_ctrl_string))
|
||||||
if (!value) {
|
{
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strlen(value) == 1) {
|
if (strlen(value) == 1)
|
||||||
switch(toupper(value[0])) {
|
{
|
||||||
|
switch(toupper(value[0]))
|
||||||
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
|
param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
|
||||||
break;
|
break;
|
||||||
@ -130,8 +138,11 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
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':
|
case 'A':
|
||||||
param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
|
param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet;
|
||||||
break;
|
break;
|
||||||
@ -145,16 +156,21 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
R3410_params *p = R3410_paramset;
|
R3410_params *p = R3410_paramset;
|
||||||
param_nid = OBJ_txt2nid(value);
|
param_nid = OBJ_txt2nid(value);
|
||||||
if (param_nid == NID_undef) {
|
if (param_nid == NID_undef)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (;p->nid != NID_undef;p++) {
|
for (;p->nid != NID_undef;p++)
|
||||||
|
{
|
||||||
if (p->nid == param_nid) break;
|
if (p->nid == param_nid) break;
|
||||||
}
|
}
|
||||||
if (p->nid == NID_undef) {
|
if (p->nid == NID_undef)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
|
GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR,
|
||||||
GOST_R_INVALID_PARAMSET);
|
GOST_R_INVALID_PARAMSET);
|
||||||
return 0;
|
return 0;
|
||||||
@ -162,21 +178,25 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
||||||
param_nid, (void *)NID_id_Gost28147_89_CryptoPro_A_ParamSet);
|
param_nid, NULL);
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
|
static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
|
||||||
const char *type, const char *value)
|
const char *type, const char *value)
|
||||||
{
|
{
|
||||||
int param_nid=0;
|
int param_nid=0;
|
||||||
if(!strcmp(type, param_ctrl_string)) {
|
if(!strcmp(type, param_ctrl_string))
|
||||||
if (!value) {
|
{
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strlen(value) == 1) {
|
if (strlen(value) == 1)
|
||||||
switch(toupper(value[0])) {
|
{
|
||||||
|
switch(toupper(value[0]))
|
||||||
|
{
|
||||||
case 'A':
|
case 'A':
|
||||||
param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
|
param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet;
|
||||||
break;
|
break;
|
||||||
@ -193,8 +213,11 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
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':
|
case 'A':
|
||||||
param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
|
param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet;
|
||||||
break;
|
break;
|
||||||
@ -205,16 +228,21 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
R3410_2001_params *p = R3410_2001_paramset;
|
R3410_2001_params *p = R3410_2001_paramset;
|
||||||
param_nid = OBJ_txt2nid(value);
|
param_nid = OBJ_txt2nid(value);
|
||||||
if (param_nid == NID_undef) {
|
if (param_nid == NID_undef)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for (;p->nid != NID_undef;p++) {
|
for (;p->nid != NID_undef;p++)
|
||||||
|
{
|
||||||
if (p->nid == param_nid) break;
|
if (p->nid == param_nid) break;
|
||||||
}
|
}
|
||||||
if (p->nid == NID_undef) {
|
if (p->nid == NID_undef)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
|
GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR,
|
||||||
GOST_R_INVALID_PARAMSET);
|
GOST_R_INVALID_PARAMSET);
|
||||||
return 0;
|
return 0;
|
||||||
@ -222,59 +250,73 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET,
|
||||||
param_nid, (void *)NID_id_Gost28147_89_CryptoPro_A_ParamSet);
|
param_nid, NULL);
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------- key generation --------------------------------*/
|
/* --------------------- key generation --------------------------------*/
|
||||||
/* Generates GOST 94 key and assigns it setting specified type */
|
/* Generates GOST 94 key and assigns it setting specified type */
|
||||||
static int pkey_gost94_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int 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);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
||||||
DSA *dsa=NULL;
|
DSA *dsa=NULL;
|
||||||
if (data->sign_param_nid == NID_undef) {
|
if (data->sign_param_nid == NID_undef)
|
||||||
if (type== NID_id_GostR3410_94_cc) {
|
{
|
||||||
|
if (type== NID_id_GostR3410_94_cc)
|
||||||
|
{
|
||||||
data->sign_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
|
data->sign_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_PKEY_GOST94_KEYGEN,
|
GOSTerr(GOST_F_PKEY_GOST94_KEYGEN,
|
||||||
GOST_R_NO_PARAMETERS_SET);
|
GOST_R_NO_PARAMETERS_SET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dsa = DSA_new();
|
dsa = DSA_new();
|
||||||
if (!fill_GOST94_params(dsa,data->sign_param_nid)) {
|
if (!fill_GOST94_params(dsa,data->sign_param_nid))
|
||||||
|
{
|
||||||
DSA_free(dsa);
|
DSA_free(dsa);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
gost_sign_keygen(dsa);
|
gost_sign_keygen(dsa);
|
||||||
EVP_PKEY_assign(pkey,type,dsa);
|
EVP_PKEY_assign(pkey,type,dsa);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates Gost_R3410_94_cc key */
|
/* 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);
|
return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates Gost_R3410_94_cp key */
|
/* 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);
|
return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates GOST_R3410 2001 key and assigns it using specified type */
|
/* 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)
|
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);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
||||||
EC_KEY *ec=NULL;
|
EC_KEY *ec=NULL;
|
||||||
if (data->sign_param_nid == NID_undef) {
|
if (data->sign_param_nid == NID_undef)
|
||||||
if (type == NID_id_GostR3410_2001_cc) {
|
{
|
||||||
|
if (type == NID_id_GostR3410_2001_cc)
|
||||||
|
{
|
||||||
data->sign_param_nid = NID_id_GostR3410_2001_ParamSet_cc;
|
data->sign_param_nid = NID_id_GostR3410_2001_ParamSet_cc;
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
GOSTerr(GOST_F_PKEY_GOST01_KEYGEN,
|
GOSTerr(GOST_F_PKEY_GOST01_KEYGEN,
|
||||||
GOST_R_NO_PARAMETERS_SET);
|
GOST_R_NO_PARAMETERS_SET);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ec = EC_KEY_new();
|
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);
|
EC_KEY_free(ec);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -282,20 +324,24 @@ static int pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type)
|
|||||||
|
|
||||||
EVP_PKEY_assign(pkey,type,ec);
|
EVP_PKEY_assign(pkey,type,ec);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates GOST R3410 2001_cc key */
|
/* 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);
|
return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001_cc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generates GOST R3410 2001_cp key */
|
/* 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);
|
return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------- sign callbacks --------------------------------------*/
|
/* ----------- sign callbacks --------------------------------------*/
|
||||||
static int pkey_gost94_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
static int pkey_gost94_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||||
const unsigned char *tbs, size_t tbs_len)
|
const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
DSA_SIG *unpacked_sig=NULL;
|
DSA_SIG *unpacked_sig=NULL;
|
||||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
if (!siglen) return 0;
|
if (!siglen) return 0;
|
||||||
@ -305,17 +351,16 @@ static int pkey_gost94_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
||||||
if (!unpacked_sig) {
|
if (!unpacked_sig)
|
||||||
|
{
|
||||||
return 0;
|
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,
|
static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||||
const unsigned char *tbs, size_t tbs_len)
|
const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
DSA_SIG *unpacked_sig=NULL;
|
DSA_SIG *unpacked_sig=NULL;
|
||||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
if (!siglen) return 0;
|
if (!siglen) return 0;
|
||||||
@ -325,16 +370,16 @@ static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
unpacked_sig = gost_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
||||||
if (!unpacked_sig) {
|
if (!unpacked_sig)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return pack_sign_cp(unpacked_sig,32,sig,siglen);
|
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,
|
static int pkey_gost01_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||||
const unsigned char *tbs, size_t tbs_len)
|
const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
DSA_SIG *unpacked_sig=NULL;
|
DSA_SIG *unpacked_sig=NULL;
|
||||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
if (!siglen) return 0;
|
if (!siglen) return 0;
|
||||||
@ -344,14 +389,16 @@ static int pkey_gost01_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
||||||
if (!unpacked_sig) {
|
if (!unpacked_sig)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return pack_sign_cc(unpacked_sig,32,sig,siglen);
|
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,
|
static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
||||||
const unsigned char *tbs, size_t tbs_len)
|
const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
DSA_SIG *unpacked_sig=NULL;
|
DSA_SIG *unpacked_sig=NULL;
|
||||||
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
if (!siglen) return 0;
|
if (!siglen) return 0;
|
||||||
@ -361,15 +408,17 @@ static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey));
|
||||||
if (!unpacked_sig) {
|
if (!unpacked_sig)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return pack_sign_cp(unpacked_sig,32,sig,siglen);
|
return pack_sign_cp(unpacked_sig,32,sig,siglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------- verify callbacks ---------------------------*/
|
/* ------------------- verify callbacks ---------------------------*/
|
||||||
static int pkey_gost94_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
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)
|
size_t siglen, const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
DSA_SIG *s=unpack_cc_signature(sig,siglen);
|
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));
|
if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
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)
|
size_t siglen, const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
DSA_SIG *s=unpack_cp_signature(sig,siglen);
|
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));
|
if (pub_key) ok = gost_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost01_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
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)
|
size_t siglen, const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
DSA_SIG *s=unpack_cc_signature(sig,siglen);
|
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));
|
if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig,
|
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)
|
size_t siglen, const unsigned char *tbs, size_t tbs_len)
|
||||||
{
|
{
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
DSA_SIG *s=unpack_cp_signature(sig,siglen);
|
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));
|
if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key));
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------- encrypt init -------------------------------------*/
|
/* ------------- encrypt init -------------------------------------*/
|
||||||
/* Generates ephermeral key */
|
/* 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);
|
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
|
||||||
EVP_PKEY *eph_key = EVP_PKEY_new();
|
EVP_PKEY *eph_key = EVP_PKEY_new();
|
||||||
EVP_PKEY *old_key =EVP_PKEY_CTX_get0_pkey(ctx);
|
EVP_PKEY *old_key =EVP_PKEY_CTX_get0_pkey(ctx);
|
||||||
@ -434,7 +485,8 @@ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
|
|||||||
if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey);
|
if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey);
|
||||||
EVP_PKEY_assign(eph_key,EVP_PKEY_base_id(old_key),NULL);
|
EVP_PKEY_assign(eph_key,EVP_PKEY_base_id(old_key),NULL);
|
||||||
if (!EVP_PKEY_copy_parameters(eph_key,old_key)) return 0;
|
if (!EVP_PKEY_copy_parameters(eph_key,old_key)) return 0;
|
||||||
switch (EVP_PKEY_base_id(old_key)) {
|
switch (EVP_PKEY_base_id(old_key))
|
||||||
|
{
|
||||||
case NID_id_GostR3410_2001:
|
case NID_id_GostR3410_2001:
|
||||||
case NID_id_GostR3410_2001_cc:
|
case NID_id_GostR3410_2001_cc:
|
||||||
gost2001_keygen(EVP_PKEY_get0(eph_key));
|
gost2001_keygen(EVP_PKEY_get0(eph_key));
|
||||||
@ -450,13 +502,16 @@ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
|
|||||||
|
|
||||||
data->eph_seckey=eph_key;
|
data->eph_seckey=eph_key;
|
||||||
return 1;
|
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);
|
*pmeth = EVP_PKEY_meth_new(id, flags);
|
||||||
if (!*pmeth) return 0;
|
if (!*pmeth) return 0;
|
||||||
|
|
||||||
switch (id) {
|
switch (id)
|
||||||
|
{
|
||||||
case NID_id_GostR3410_94_cc:
|
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_keygen(*pmeth,NULL,pkey_gost94cc_keygen);
|
||||||
@ -510,5 +565,5 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) {
|
|||||||
//FIXME derive etc...
|
//FIXME derive etc...
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -13,29 +13,31 @@
|
|||||||
#include <openssl/dsa.h>
|
#include <openssl/dsa.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
#include "sign.h"
|
#include "gost_params.h"
|
||||||
#include "paramset.h"
|
#include "gost_lcl.h"
|
||||||
#include "tools.h"
|
|
||||||
#include "e_gost_err.h"
|
#include "e_gost_err.h"
|
||||||
|
|
||||||
#ifdef DEBUG_SIGN
|
#ifdef DEBUG_SIGN
|
||||||
void dump_signature(const char *message,const unsigned char *buffer,size_t len) {
|
void dump_signature(const char *message,const unsigned char *buffer,size_t len)
|
||||||
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
fprintf(stderr,"signature %s Length=%d",message,len);
|
fprintf(stderr,"signature %s Length=%d",message,len);
|
||||||
for (i=0; i<len; i++) {
|
for (i=0; i<len; i++)
|
||||||
|
{
|
||||||
if (i% 16 ==0) fputc('\n',stderr);
|
if (i% 16 ==0) fputc('\n',stderr);
|
||||||
fprintf (stderr," %02x",buffer[i]);
|
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);
|
fprintf(stderr,"%s\nR=",message);
|
||||||
BN_print_fp(stderr,sig->r);
|
BN_print_fp(stderr,sig->r);
|
||||||
fprintf(stderr,"\nS=");
|
fprintf(stderr,"\nS=");
|
||||||
BN_print_fp(stderr,sig->s);
|
BN_print_fp(stderr,sig->s);
|
||||||
fprintf(stderr,"\n");
|
fprintf(stderr,"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig) {
|
|||||||
* Computes signature and returns it as DSA_SIG structure
|
* 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;
|
BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
|
||||||
DSA_SIG *newsig = DSA_SIG_new();
|
DSA_SIG *newsig = DSA_SIG_new();
|
||||||
BIGNUM *md = hashsum2bn(dgst);
|
BIGNUM *md = hashsum2bn(dgst);
|
||||||
@ -67,27 +69,31 @@ DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
|
|||||||
{
|
{
|
||||||
BN_one(md);
|
BN_one(md);
|
||||||
}
|
}
|
||||||
do {
|
do
|
||||||
do {
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
/*Generate random number k less than q*/
|
/*Generate random number k less than q*/
|
||||||
BN_rand_range(k,dsa->q);
|
BN_rand_range(k,dsa->q);
|
||||||
/* generate r = (a^x mod p) mod q */
|
/* generate r = (a^x mod p) mod q */
|
||||||
BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
|
BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
|
||||||
if (!(newsig->r)) newsig->r=BN_new();
|
if (!(newsig->r)) newsig->r=BN_new();
|
||||||
BN_mod(newsig->r,tmp,dsa->q,ctx);
|
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 */
|
/* generate s = (xr + k(Hm)) mod q */
|
||||||
BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
|
BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
|
||||||
BN_mod_mul(tmp2,k,md,dsa->q,ctx);
|
BN_mod_mul(tmp2,k,md,dsa->q,ctx);
|
||||||
if (!newsig->s) newsig->s=BN_new();
|
if (!newsig->s) newsig->s=BN_new();
|
||||||
BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
|
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_free(md);
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
return newsig;
|
return newsig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -95,9 +101,8 @@ err:
|
|||||||
* and frees up DSA_SIG structure
|
* 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;
|
*siglen = 2*order;
|
||||||
memset(sig,0,*siglen);
|
memset(sig,0,*siglen);
|
||||||
store_bignum(s->r, sig,order);
|
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);
|
dump_signature("serialized",sig,*siglen);
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Packs signature according to Cryptopro rules
|
* Packs signature according to Cryptopro rules
|
||||||
* and frees up DSA_SIG structure
|
* 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;
|
*siglen = 2*order;
|
||||||
memset(sig,0,*siglen);
|
memset(sig,0,*siglen);
|
||||||
store_bignum(s->s, sig, order);
|
store_bignum(s->s, sig, order);
|
||||||
@ -120,10 +124,7 @@ int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen)
|
|||||||
dump_signature("serialized",sig,*siglen);
|
dump_signature("serialized",sig,*siglen);
|
||||||
DSA_SIG_free(s);
|
DSA_SIG_free(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Verifies signature passed as DSA_SIG structure
|
* Verifies signature passed as DSA_SIG structure
|
||||||
@ -132,7 +133,7 @@ int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, unsigned int *siglen)
|
|||||||
|
|
||||||
int gost_do_verify(const unsigned char *dgst, int dgst_len,
|
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 *md, *tmp=NULL;
|
||||||
BIGNUM *q2=NULL;
|
BIGNUM *q2=NULL;
|
||||||
BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
|
BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
|
||||||
@ -159,7 +160,8 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
|
|||||||
u = BN_CTX_get(ctx);
|
u = BN_CTX_get(ctx);
|
||||||
|
|
||||||
BN_mod(tmp,md,dsa->q,ctx);
|
BN_mod(tmp,md,dsa->q,ctx);
|
||||||
if (BN_is_zero(tmp)) {
|
if (BN_is_zero(tmp))
|
||||||
|
{
|
||||||
BN_one(md);
|
BN_one(md);
|
||||||
}
|
}
|
||||||
BN_copy(q2,dsa->q);
|
BN_copy(q2,dsa->q);
|
||||||
@ -177,21 +179,23 @@ int gost_do_verify(const unsigned char *dgst, int dgst_len,
|
|||||||
BN_free(md);
|
BN_free(md);
|
||||||
BN_CTX_end(ctx);
|
BN_CTX_end(ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
if (ok!=0) {
|
if (ok!=0)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
|
GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
|
||||||
}
|
}
|
||||||
return (ok==0);
|
return (ok==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Computes public keys for GOST R 34.10-94 algorithm
|
* Computes public keys for GOST R 34.10-94 algorithm
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int gost94_compute_public(DSA *dsa)
|
int gost94_compute_public(DSA *dsa)
|
||||||
{
|
{
|
||||||
/* Now fill algorithm parameters with correct values */
|
/* Now fill algorithm parameters with correct values */
|
||||||
BN_CTX *ctx = BN_CTX_new();
|
BN_CTX *ctx = BN_CTX_new();
|
||||||
if (!dsa->g) {
|
if (!dsa->g)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_GOST_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
|
GOSTerr(GOST_F_GOST_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -200,14 +204,15 @@ int gost94_compute_public(DSA *dsa)
|
|||||||
BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
|
BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
|
||||||
BN_CTX_free(ctx);
|
BN_CTX_free(ctx);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fill GOST 94 params, searching them in R3410_paramset array
|
* Fill GOST 94 params, searching them in R3410_paramset array
|
||||||
* by nid of paramset
|
* 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;
|
R3410_params *params=R3410_paramset;
|
||||||
while (params->nid!=NID_undef && params->nid !=nid) params++;
|
while (params->nid!=NID_undef && params->nid !=nid) params++;
|
||||||
if (params->nid == NID_undef)
|
if (params->nid == NID_undef)
|
||||||
@ -226,7 +231,7 @@ int fill_GOST94_params(DSA *dsa,int nid) {
|
|||||||
dsa->g=NULL;
|
dsa->g=NULL;
|
||||||
BN_dec2bn(&(dsa->g),params->a);
|
BN_dec2bn(&(dsa->g),params->a);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate GOST R 34.10-94 keypair
|
* Generate GOST R 34.10-94 keypair
|
||||||
@ -234,69 +239,82 @@ int fill_GOST94_params(DSA *dsa,int nid) {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int gost_sign_keygen(DSA *dsa)
|
int gost_sign_keygen(DSA *dsa)
|
||||||
{
|
{
|
||||||
dsa->priv_key = BN_new();
|
dsa->priv_key = BN_new();
|
||||||
BN_rand_range(dsa->priv_key,dsa->q);
|
BN_rand_range(dsa->priv_key,dsa->q);
|
||||||
return gost94_compute_public( dsa);
|
return gost94_compute_public( dsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack signature according to cryptocom rules */
|
/* 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;
|
DSA_SIG *s;
|
||||||
s = DSA_SIG_new();
|
s = DSA_SIG_new();
|
||||||
if (s == NULL) {
|
if (s == NULL)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
s->r = getbnfrombuf(sig, siglen/2);
|
s->r = getbnfrombuf(sig, siglen/2);
|
||||||
s->s = getbnfrombuf(sig + siglen/2, siglen/2);
|
s->s = getbnfrombuf(sig + siglen/2, siglen/2);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unpack signature according to cryptopro rules */
|
/* 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;
|
DSA_SIG *s;
|
||||||
|
|
||||||
s = DSA_SIG_new();
|
s = DSA_SIG_new();
|
||||||
if (s == NULL) {
|
if (s == NULL)
|
||||||
|
{
|
||||||
GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
|
GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
s->s = getbnfrombuf(sig , siglen/2);
|
s->s = getbnfrombuf(sig , siglen/2);
|
||||||
s->r = getbnfrombuf(sig + siglen/2, siglen/2);
|
s->r = getbnfrombuf(sig + siglen/2, siglen/2);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert little-endian byte array into bignum */
|
/* Convert little-endian byte array into bignum */
|
||||||
BIGNUM *hashsum2bn(const unsigned char *dgst)
|
BIGNUM *hashsum2bn(const unsigned char *dgst)
|
||||||
{ unsigned char buf[32];
|
{
|
||||||
|
unsigned char buf[32];
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<32;i++) {
|
for (i=0;i<32;i++)
|
||||||
|
{
|
||||||
buf[31-i]=dgst[i];
|
buf[31-i]=dgst[i];
|
||||||
}
|
}
|
||||||
return getbnfrombuf(buf,32);
|
return getbnfrombuf(buf,32);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert byte buffer to bignum, skipping leading zeros*/
|
/* Convert byte buffer to bignum, skipping leading zeros*/
|
||||||
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len) {
|
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
|
||||||
while (*buf==0&&len>0) {
|
{
|
||||||
|
while (*buf==0&&len>0)
|
||||||
|
{
|
||||||
buf++; len--;
|
buf++; len--;
|
||||||
}
|
}
|
||||||
if (len) {
|
if (len)
|
||||||
|
{
|
||||||
return BN_bin2bn(buf,len,NULL);
|
return BN_bin2bn(buf,len,NULL);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
BIGNUM *b=BN_new();
|
BIGNUM *b=BN_new();
|
||||||
BN_zero(b);
|
BN_zero(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pack bignum into byte buffer of given size, filling all leading bytes
|
/* Pack bignum into byte buffer of given size, filling all leading bytes
|
||||||
* by zeros */
|
* 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);
|
int bytes = BN_num_bytes(bn);
|
||||||
if (bytes>len) return 0;
|
if (bytes>len) return 0;
|
||||||
memset(buf,0,len);
|
memset(buf,0,len);
|
||||||
BN_bn2bin(bn,buf+len-bytes);
|
BN_bn2bin(bn,buf+len-bytes);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,37 +28,39 @@
|
|||||||
/* Following functions are various bit meshing routines used in
|
/* Following functions are various bit meshing routines used in
|
||||||
* GOST R 34.11-94 algorithms */
|
* GOST R 34.11-94 algorithms */
|
||||||
static void swap_bytes (byte *w, byte *k)
|
static void swap_bytes (byte *w, byte *k)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
for (i=0;i<4;i++)
|
for (i=0;i<4;i++)
|
||||||
for (j=0;j<8;j++)
|
for (j=0;j<8;j++)
|
||||||
k[i+4*j]=w[8*i+j];
|
k[i+4*j]=w[8*i+j];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* was A_A */
|
/* was A_A */
|
||||||
static void circle_xor8 (const byte *w, byte *k)
|
static void circle_xor8 (const byte *w, byte *k)
|
||||||
{
|
{
|
||||||
byte buf[8];
|
byte buf[8];
|
||||||
int i;
|
int i;
|
||||||
memcpy(buf,w,8);
|
memcpy(buf,w,8);
|
||||||
memcpy(k,w+8,24);
|
memcpy(k,w+8,24);
|
||||||
for(i=0;i<8;i++)
|
for(i=0;i<8;i++)
|
||||||
k[i+24]=buf[i]^k[i];
|
k[i+24]=buf[i]^k[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* was R_R */
|
/* was R_R */
|
||||||
static void transform_3 (byte *data)
|
static void transform_3 (byte *data)
|
||||||
{
|
{
|
||||||
unsigned short int acc;
|
unsigned short int acc;
|
||||||
acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
|
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);
|
((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
|
||||||
memmove(data,data+2,30);
|
memmove(data,data+2,30);
|
||||||
data[30]=acc&0xff;
|
data[30]=acc&0xff;
|
||||||
data[31]=acc>>8;
|
data[31]=acc>>8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
|
/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
|
||||||
static int add_blocks(int n,byte *left, const byte *right)
|
static int add_blocks(int n,byte *left, const byte *right)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int carry=0;
|
int carry=0;
|
||||||
int sum;
|
int sum;
|
||||||
@ -69,19 +71,21 @@ static int add_blocks(int n,byte *left, const byte *right)
|
|||||||
carry=sum>>8;
|
carry=sum>>8;
|
||||||
}
|
}
|
||||||
return carry;
|
return carry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Xor two sequences of bytes */
|
/* 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;
|
size_t i;
|
||||||
for (i=0;i<len;i++) result[i]=a[i]^b[i];
|
for (i=0;i<len;i++) result[i]=a[i]^b[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate H(i+1) = Hash(Hi,Mi)
|
* Calculate H(i+1) = Hash(Hi,Mi)
|
||||||
* Where H and M are 32 bytes long
|
* Where H and M are 32 bytes long
|
||||||
*/
|
*/
|
||||||
static int hash_step(gost_ctx *c,byte *H,const byte *M)
|
static int hash_step(gost_ctx *c,byte *H,const byte *M)
|
||||||
{
|
{
|
||||||
static byte U[32],W[32],V[32],S[32],Key[32];
|
static byte U[32],W[32],V[32],S[32],Key[32];
|
||||||
int i;
|
int i;
|
||||||
/* Compute first key */
|
/* Compute first key */
|
||||||
@ -126,20 +130,23 @@ static int hash_step(gost_ctx *c,byte *H,const byte *M)
|
|||||||
transform_3(S);
|
transform_3(S);
|
||||||
memcpy(H,S,32);
|
memcpy(H,S,32);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize gost_hash ctx - cleans up temporary structures and
|
/* Initialize gost_hash ctx - cleans up temporary structures and
|
||||||
* set up substitution blocks
|
* 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));
|
memset(ctx,0,sizeof(gost_hash_ctx));
|
||||||
ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
|
ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
|
||||||
if (!ctx->cipher_ctx) {
|
if (!ctx->cipher_ctx)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
gost_init(ctx->cipher_ctx,subst_block);
|
gost_init(ctx->cipher_ctx,subst_block);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free cipher CTX if it is dynamically allocated. Do not use
|
* Free cipher CTX if it is dynamically allocated. Do not use
|
||||||
* if cipher ctx is statically allocated as in OpenSSL implementation of
|
* 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)
|
void done_gost_hash_ctx(gost_hash_ctx *ctx)
|
||||||
{
|
{
|
||||||
/* No need to use gost_destroy, because cipher keys are not really
|
/* No need to use gost_destroy, because cipher keys are not really
|
||||||
* secret when hashing */
|
* secret when hashing */
|
||||||
MYFREE(ctx->cipher_ctx);
|
MYFREE(ctx->cipher_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reset state of hash context to begin hashing new message
|
* 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;
|
if (!ctx->cipher_ctx) return 0;
|
||||||
memset(&(ctx->H),0,32);
|
memset(&(ctx->H),0,32);
|
||||||
memset(&(ctx->S),0,32);
|
memset(&(ctx->S),0,32);
|
||||||
ctx->len = 0L;
|
ctx->len = 0L;
|
||||||
ctx->left=0;
|
ctx->left=0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hash block of arbitrary length
|
* 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 *curptr=block;
|
||||||
const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
|
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*/
|
/*There are some bytes from previous step*/
|
||||||
int add_bytes = 32-ctx->left;
|
int add_bytes = 32-ctx->left;
|
||||||
if (add_bytes>length) {
|
if (add_bytes>length)
|
||||||
|
{
|
||||||
add_bytes = length;
|
add_bytes = length;
|
||||||
}
|
}
|
||||||
memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
|
memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
|
||||||
ctx->left+=add_bytes;
|
ctx->left+=add_bytes;
|
||||||
if (ctx->left<32) {
|
if (ctx->left<32)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (ctx->left>32) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
curptr=block+add_bytes;
|
curptr=block+add_bytes;
|
||||||
hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
|
hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
|
||||||
if (save_c!=ctx->cipher_ctx) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
add_blocks(32,ctx->S,ctx->remainder);
|
add_blocks(32,ctx->S,ctx->remainder);
|
||||||
if (save_c!=ctx->cipher_ctx) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
ctx->len+=32;
|
ctx->len+=32;
|
||||||
ctx->left=0;
|
ctx->left=0;
|
||||||
}
|
}
|
||||||
while (curptr<=barrier)
|
while (curptr<=barrier)
|
||||||
{
|
{
|
||||||
hash_step(ctx->cipher_ctx,ctx->H,curptr);
|
hash_step(ctx->cipher_ctx,ctx->H,curptr);
|
||||||
if (save_c!=ctx->cipher_ctx) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
add_blocks(32,ctx->S,curptr);
|
add_blocks(32,ctx->S,curptr);
|
||||||
if (save_c!=ctx->cipher_ctx) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
ctx->len+=32;
|
ctx->len+=32;
|
||||||
curptr+=32;
|
curptr+=32;
|
||||||
}
|
}
|
||||||
if (curptr!=block+length) {
|
if (curptr!=block+length)
|
||||||
|
{
|
||||||
ctx->left=block+length-curptr;
|
ctx->left=block+length-curptr;
|
||||||
if (ctx->left>32) {
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
memcpy(ctx->remainder,curptr,ctx->left);
|
memcpy(ctx->remainder,curptr,ctx->left);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compute hash value from current state of ctx
|
* Compute hash value from current state of ctx
|
||||||
* state of hash ctx becomes invalid and cannot be used for further
|
* state of hash ctx becomes invalid and cannot be used for further
|
||||||
* hashing.
|
* hashing.
|
||||||
*/
|
*/
|
||||||
int finish_hash(gost_hash_ctx *ctx,byte *hashval) {
|
int finish_hash(gost_hash_ctx *ctx,byte *hashval)
|
||||||
|
{
|
||||||
byte buf[32];
|
byte buf[32];
|
||||||
byte H[32];
|
byte H[32];
|
||||||
byte S[32];
|
byte S[32];
|
||||||
@ -234,7 +232,8 @@ int finish_hash(gost_hash_ctx *ctx,byte *hashval) {
|
|||||||
byte *bptr;
|
byte *bptr;
|
||||||
memcpy(H,ctx->H,32);
|
memcpy(H,ctx->H,32);
|
||||||
memcpy(S,ctx->S,32);
|
memcpy(S,ctx->S,32);
|
||||||
if (ctx->left) {
|
if (ctx->left)
|
||||||
|
{
|
||||||
memset(buf,0,32);
|
memset(buf,0,32);
|
||||||
memcpy(buf,ctx->remainder,ctx->left);
|
memcpy(buf,ctx->remainder,ctx->left);
|
||||||
hash_step(ctx->cipher_ctx,H,buf);
|
hash_step(ctx->cipher_ctx,H,buf);
|
||||||
@ -244,7 +243,8 @@ int finish_hash(gost_hash_ctx *ctx,byte *hashval) {
|
|||||||
memset(buf,0,32);
|
memset(buf,0,32);
|
||||||
bptr=buf;
|
bptr=buf;
|
||||||
fin_len<<=3; /* Hash length in BITS!!*/
|
fin_len<<=3; /* Hash length in BITS!!*/
|
||||||
while(fin_len>0) {
|
while(fin_len>0)
|
||||||
|
{
|
||||||
*(bptr++)=fin_len&0xFF;
|
*(bptr++)=fin_len&0xFF;
|
||||||
fin_len>>=8;
|
fin_len>>=8;
|
||||||
};
|
};
|
||||||
@ -252,5 +252,5 @@ int finish_hash(gost_hash_ctx *ctx,byte *hashval) {
|
|||||||
hash_step(ctx->cipher_ctx,H,S);
|
hash_step(ctx->cipher_ctx,H,S);
|
||||||
memcpy(hashval,H,32);
|
memcpy(hashval,H,32);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* gosthash.c *
|
* gosthash.h *
|
||||||
* Copyright (c) 2005-2006 Cryptocom LTD *
|
* Copyright (c) 2005-2006 Cryptocom LTD *
|
||||||
* This file is distributed under the same license as OpenSSL *
|
* This file is distributed under the same license as OpenSSL *
|
||||||
* *
|
* *
|
||||||
|
@ -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
|
|
@ -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
|
|
||||||
|
|
@ -19,23 +19,23 @@ 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 hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
|
||||||
int get_line(FILE *f,char *hash,char *filename);
|
int get_line(FILE *f,char *hash,char *filename);
|
||||||
void help()
|
void help()
|
||||||
{
|
{
|
||||||
fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
|
fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
|
||||||
"\t-c check message digests (default is generate)\n"
|
"\t-c check message digests (default is generate)\n"
|
||||||
"\t-v verbose, print file names when checking\n"
|
"\t-v verbose, print file names when checking\n"
|
||||||
"\t-b read files in binary mode\n"
|
"\t-b read files in binary mode\n"
|
||||||
"\t-t use test GOST paramset (default is CryptoPro paramset)\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"
|
"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");
|
"that is printed on stdout by this program when it generates digests.\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
#define O_BINARY 0
|
#define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
int c,i;
|
int c,i;
|
||||||
int verbose=0;
|
int verbose=0;
|
||||||
int errors=0;
|
int errors=0;
|
||||||
@ -51,13 +51,18 @@ int main(int argc,char **argv)
|
|||||||
case 'v': verbose=1; break;
|
case 'v': verbose=1; break;
|
||||||
case 't': b= &GostR3411_94_TestParamSet; break;
|
case 't': b= &GostR3411_94_TestParamSet; break;
|
||||||
case 'b': open_mode |= O_BINARY; break;
|
case 'b': open_mode |= O_BINARY; break;
|
||||||
case 'c': if (optarg) {
|
case 'c':
|
||||||
|
if (optarg)
|
||||||
|
{
|
||||||
check_file = fopen(optarg,"r");
|
check_file = fopen(optarg,"r");
|
||||||
if (!check_file) {
|
if (!check_file)
|
||||||
|
{
|
||||||
perror(optarg);
|
perror(optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
check_file= stdin;
|
check_file= stdin;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -82,86 +87,106 @@ int main(int argc,char **argv)
|
|||||||
}
|
}
|
||||||
while (get_line(check_file,inhash,filename))
|
while (get_line(check_file,inhash,filename))
|
||||||
{
|
{
|
||||||
if (!hash_file(&ctx,filename,calcsum,open_mode)) {
|
if (!hash_file(&ctx,filename,calcsum,open_mode))
|
||||||
|
{
|
||||||
exit (2);
|
exit (2);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
if (!strncmp(calcsum,inhash,65))
|
if (!strncmp(calcsum,inhash,65))
|
||||||
{
|
{
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
fprintf(stderr,"%s\tOK\n",filename);
|
fprintf(stderr,"%s\tOK\n",filename);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (verbose) {
|
else
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
fprintf(stderr,"%s\tFAILED\n",filename);
|
fprintf(stderr,"%s\tFAILED\n",filename);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
|
fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
|
||||||
argv[0],filename);
|
argv[0],filename);
|
||||||
}
|
}
|
||||||
failcount++;
|
failcount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbose && failcount) {
|
if (verbose && failcount)
|
||||||
|
{
|
||||||
fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
|
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);
|
exit (failcount?1:0);
|
||||||
}
|
}
|
||||||
if (optind==argc) {
|
if (optind==argc)
|
||||||
|
{
|
||||||
char sum[65];
|
char sum[65];
|
||||||
if (!hash_stream(&ctx,fileno(stdin),sum)) {
|
if (!hash_stream(&ctx,fileno(stdin),sum))
|
||||||
|
{
|
||||||
perror("stdin");
|
perror("stdin");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("%s -\n",sum);
|
printf("%s -\n",sum);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
for (i=optind;i<argc;i++) {
|
for (i=optind;i<argc;i++)
|
||||||
|
{
|
||||||
char sum[65];
|
char sum[65];
|
||||||
if (!hash_file(&ctx,argv[i],sum,open_mode)) {
|
if (!hash_file(&ctx,argv[i],sum,open_mode))
|
||||||
|
{
|
||||||
errors++;
|
errors++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
printf("%s %s\n",sum,argv[i]);
|
printf("%s %s\n",sum,argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exit(errors?1:0);
|
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;
|
int fd;
|
||||||
if ((fd=open(filename,mode))<0) {
|
if ((fd=open(filename,mode))<0)
|
||||||
|
{
|
||||||
perror(filename);
|
perror(filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!hash_stream(ctx,fd,sum)) {
|
if (!hash_stream(ctx,fd,sum))
|
||||||
|
{
|
||||||
perror(filename);
|
perror(filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
return 1;
|
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];
|
unsigned char buffer[BUF_SIZE];
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
int i;
|
int i;
|
||||||
start_hash(ctx);
|
start_hash(ctx);
|
||||||
while ((bytes=read(fd,buffer,BUF_SIZE))>0) {
|
while ((bytes=read(fd,buffer,BUF_SIZE))>0)
|
||||||
|
{
|
||||||
hash_block(ctx,buffer,bytes);
|
hash_block(ctx,buffer,bytes);
|
||||||
}
|
}
|
||||||
if (bytes<0) {
|
if (bytes<0)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
finish_hash(ctx,buffer);
|
finish_hash(ctx,buffer);
|
||||||
for (i=0;i<32;i++) {
|
for (i=0;i<32;i++)
|
||||||
|
{
|
||||||
sprintf(sum+2*i,"%02x",buffer[31-i]);
|
sprintf(sum+2*i,"%02x",buffer[31-i]);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_line(FILE *f,char *hash,char *filename) {
|
int get_line(FILE *f,char *hash,char *filename)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
if (fread(hash,1,64,f)<64) return 0;
|
if (fread(hash,1,64,f)<64) return 0;
|
||||||
hash[64]=0;
|
hash[64]=0;
|
||||||
@ -174,11 +199,12 @@ int get_line(FILE *f,char *hash,char *filename) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fgetc(f)!=' ') {
|
if (fgetc(f)!=' ')
|
||||||
|
{
|
||||||
fprintf(stderr,"Malformed input line\n");
|
fprintf(stderr,"Malformed input line\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
i=strlen(fgets(filename,PATH_MAX,f));
|
i=strlen(fgets(filename,PATH_MAX,f));
|
||||||
while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
|
while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
Loading…
x
Reference in New Issue
Block a user