This commit is contained in:
Zhi Guan
2015-08-15 15:02:15 +08:00
parent 06df2fab54
commit 3bdc0ea895
2536 changed files with 417052 additions and 271997 deletions

View File

@@ -45,7 +45,10 @@ install:
set -e; \
echo installing $(LIBNAME); \
pfx=lib; \
if [ "$(PLATFORM)" != "Cygwin" ]; then \
if expr "$(PLATFORM)" : "Cygwin" >/dev/null; then \
sfx=".so"; \
cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
else \
case "$(CFLAGS)" in \
*DSO_BEOS*) sfx=".so";; \
*DSO_DLFCN*) sfx=`expr "$(SHLIB_EXT)" : '.*\(\.[a-z][a-z]*\)' \| ".so"`;; \
@@ -54,9 +57,6 @@ install:
*) sfx=".bad";; \
esac; \
cp $${pfx}$(LIBNAME)$$sfx $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
else \
sfx=".so"; \
cp cyg$(LIBNAME).dll $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
fi; \
chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new; \
mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines/$${pfx}$(LIBNAME)$$sfx; \
@@ -66,16 +66,16 @@ links:
tests:
depend:
@if [ -z "$(THIS)" ]; then \
$(MAKE) -f $(TOP)/Makefile reflect THIS=$@; \
else \
$(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC); \
fi
update: local_depend
@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
depend: local_depend
@if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
local_depend:
@[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
files:
$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
lint:
lint -DLINT $(INCLUDES) $(SRC)>fluff
@@ -142,13 +142,13 @@ 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/err.h ../../include/openssl/evp.h
gost_ameth.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_ameth.o: ../../include/openssl/objects.h
gost_ameth.o: ../../include/openssl/buffer.h ../../include/openssl/cms.h
gost_ameth.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
gost_ameth.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
gost_ameth.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
gost_ameth.o: ../../include/openssl/engine.h ../../include/openssl/err.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
@@ -262,8 +262,9 @@ 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/err.h ../../include/openssl/evp.h
gost_sign.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
gost_sign.o: ../../include/openssl/objects.h
gost_sign.o: ../../include/openssl/opensslconf.h
gost_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
gost_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h

View File

@@ -1,13 +1,13 @@
/* e_gost_err.c */
/* ====================================================================
* Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved.
* Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -53,7 +53,8 @@
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
/*
* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
@@ -65,148 +66,156 @@
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(0,func,0)
#define ERR_REASON(reason) ERR_PACK(0,0,reason)
# define ERR_FUNC(func) ERR_PACK(0,func,0)
# define ERR_REASON(reason) ERR_PACK(0,0,reason)
static ERR_STRING_DATA GOST_str_functs[]=
{
{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"},
{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"},
{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"},
{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), "GOST89_GET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "GOST89_SET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"},
{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"},
{ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"},
{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN), "PKEY_GOST01CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"},
{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_KEYGEN), "PKEY_GOST94CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"},
{ERR_FUNC(GOST_F_PKEY_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_MAC_CTRL), "PKEY_GOST_MAC_CTRL"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"},
{ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"},
{ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"},
{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"},
{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"},
{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
{0,NULL}
};
static ERR_STRING_DATA GOST_str_functs[] = {
{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"},
{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"},
{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"},
{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"},
{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS),
"GOST89_GET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS),
"GOST89_SET_ASN1_PARAMETERS"},
{ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"},
{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"},
{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"},
{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"},
{ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"},
{ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"},
{ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"},
{ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"},
{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"},
{ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN), "PKEY_GOST01CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"},
{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_KEYGEN), "PKEY_GOST94CP_KEYGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"},
{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"},
{ERR_FUNC(GOST_F_PKEY_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_MAC_CTRL), "PKEY_GOST_MAC_CTRL"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"},
{ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"},
{ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"},
{ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"},
{ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"},
{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"},
{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"},
{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
{0, NULL}
};
static ERR_STRING_DATA GOST_str_reasons[]=
{
{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"},
{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"},
{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"},
{ERR_REASON(GOST_R_CTRL_CALL_FAILED) ,"ctrl call failed"},
{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"},
{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"},
{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"},
{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"},
{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY),"incompatible peer key"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"},
{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"},
{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"},
{ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"},
{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH),"invalid mac key length"},
{ERR_REASON(GOST_R_INVALID_PARAMSET) ,"invalid paramset"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"},
{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"},
{ERR_REASON(GOST_R_MAC_KEY_NOT_SET) ,"mac key not set"},
{ERR_REASON(GOST_R_MALLOC_FAILURE) ,"malloc failure"},
{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"},
{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"},
{ERR_REASON(GOST_R_NO_PEER_KEY) ,"no peer key"},
{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),"no private part of non ephemeral keypair"},
{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"},
{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"},
{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"},
{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"},
{ERR_REASON(GOST_R_UKM_NOT_SET) ,"ukm not set"},
{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"},
{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"},
{0,NULL}
};
static ERR_STRING_DATA GOST_str_reasons[] = {
{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),
"bad key parameters format"},
{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),
"bad pkey parameters format"},
{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),
"cannot pack ephemeral key"},
{ERR_REASON(GOST_R_CTRL_CALL_FAILED), "ctrl call failed"},
{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),
"error computing shared key"},
{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),
"error packing key transport info"},
{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),
"error parsing key transport info"},
{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS), "incompatible algorithms"},
{ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY), "incompatible peer key"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS), "invalid cipher params"},
{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID), "invalid cipher param oid"},
{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE), "invalid digest type"},
{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET), "invalid gost94 parmset"},
{ERR_REASON(GOST_R_INVALID_IV_LENGTH), "invalid iv length"},
{ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"},
{ERR_REASON(GOST_R_INVALID_PARAMSET), "invalid paramset"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED), "key is not initalized"},
{ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED), "key is not initialized"},
{ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING), "key parameters missing"},
{ERR_REASON(GOST_R_MAC_KEY_NOT_SET), "mac key not set"},
{ERR_REASON(GOST_R_MALLOC_FAILURE), "malloc failure"},
{ERR_REASON(GOST_R_NO_MEMORY), "no memory"},
{ERR_REASON(GOST_R_NO_PARAMETERS_SET), "no parameters set"},
{ERR_REASON(GOST_R_NO_PEER_KEY), "no peer key"},
{ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),
"no private part of non ephemeral keypair"},
{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED), "public key undefined"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR), "random generator error"},
{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE), "random generator failure"},
{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),
"random number generator failed"},
{ERR_REASON(GOST_R_SIGNATURE_MISMATCH), "signature mismatch"},
{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),
"signature parts greater than q"},
{ERR_REASON(GOST_R_UKM_NOT_SET), "ukm not set"},
{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),
"unsupported cipher ctl command"},
{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),
"unsupported parameter set"},
{0, NULL}
};
#endif
#ifdef GOST_LIB_NAME
static ERR_STRING_DATA GOST_lib_name[]=
{
{0 ,GOST_LIB_NAME},
{0,NULL}
};
static ERR_STRING_DATA GOST_lib_name[] = {
{0, GOST_LIB_NAME},
{0, NULL}
};
#endif
static int GOST_lib_error_code=0;
static int GOST_error_init=1;
static int GOST_lib_error_code = 0;
static int GOST_error_init = 1;
void ERR_load_GOST_strings(void)
{
if (GOST_lib_error_code == 0)
GOST_lib_error_code=ERR_get_next_error_library();
{
if (GOST_lib_error_code == 0)
GOST_lib_error_code = ERR_get_next_error_library();
if (GOST_error_init)
{
GOST_error_init=0;
if (GOST_error_init) {
GOST_error_init = 0;
#ifndef OPENSSL_NO_ERR
ERR_load_strings(GOST_lib_error_code,GOST_str_functs);
ERR_load_strings(GOST_lib_error_code,GOST_str_reasons);
ERR_load_strings(GOST_lib_error_code, GOST_str_functs);
ERR_load_strings(GOST_lib_error_code, GOST_str_reasons);
#endif
#ifdef GOST_LIB_NAME
GOST_lib_name->error = ERR_PACK(GOST_lib_error_code,0,0);
ERR_load_strings(0,GOST_lib_name);
GOST_lib_name->error = ERR_PACK(GOST_lib_error_code, 0, 0);
ERR_load_strings(0, GOST_lib_name);
#endif
}
}
}
}
void ERR_unload_GOST_strings(void)
{
if (GOST_error_init == 0)
{
{
if (GOST_error_init == 0) {
#ifndef OPENSSL_NO_ERR
ERR_unload_strings(GOST_lib_error_code,GOST_str_functs);
ERR_unload_strings(GOST_lib_error_code,GOST_str_reasons);
ERR_unload_strings(GOST_lib_error_code, GOST_str_functs);
ERR_unload_strings(GOST_lib_error_code, GOST_str_reasons);
#endif
#ifdef GOST_LIB_NAME
ERR_unload_strings(0,GOST_lib_name);
ERR_unload_strings(0, GOST_lib_name);
#endif
GOST_error_init=1;
}
}
GOST_error_init = 1;
}
}
void ERR_GOST_error(int function, int reason, char *file, int line)
{
if (GOST_lib_error_code == 0)
GOST_lib_error_code=ERR_get_next_error_library();
ERR_PUT_error(GOST_lib_error_code,function,reason,file,line);
}
{
if (GOST_lib_error_code == 0)
GOST_lib_error_code = ERR_get_next_error_library();
ERR_PUT_error(GOST_lib_error_code, function, reason, file, line);
}

View File

@@ -6,7 +6,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -53,102 +53,104 @@
*/
#ifndef HEADER_GOST_ERR_H
#define HEADER_GOST_ERR_H
# define HEADER_GOST_ERR_H
#ifdef __cplusplus
extern "C" {
#endif
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script mkerr.pl. Any changes
/*
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
void ERR_load_GOST_strings(void);
void ERR_unload_GOST_strings(void);
void ERR_GOST_error(int function, int reason, char *file, int line);
#define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__)
# define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__)
/* Error codes for the GOST functions. */
/* Function codes. */
#define GOST_F_DECODE_GOST_ALGOR_PARAMS 99
#define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100
#define GOST_F_FILL_GOST2001_PARAMS 101
#define GOST_F_FILL_GOST94_PARAMS 102
#define GOST_F_GET_ENCRYPTION_PARAMS 103
#define GOST_F_GOST2001_COMPUTE_PUBLIC 104
#define GOST_F_GOST2001_DO_SIGN 105
#define GOST_F_GOST2001_DO_VERIFY 106
#define GOST_F_GOST2001_KEYGEN 107
#define GOST_F_GOST89_GET_ASN1_PARAMETERS 108
#define GOST_F_GOST89_SET_ASN1_PARAMETERS 109
#define GOST_F_GOST94_COMPUTE_PUBLIC 110
#define GOST_F_GOST_CIPHER_CTL 111
#define GOST_F_GOST_DO_SIGN 112
#define GOST_F_GOST_DO_VERIFY 113
#define GOST_F_GOST_IMIT_CTRL 114
#define GOST_F_GOST_IMIT_FINAL 140
#define GOST_F_GOST_IMIT_UPDATE 115
#define GOST_F_PARAM_COPY_GOST01 116
#define GOST_F_PARAM_COPY_GOST94 117
#define GOST_F_PKEY_GOST01CP_DECRYPT 118
#define GOST_F_PKEY_GOST01CP_ENCRYPT 119
#define GOST_F_PKEY_GOST01CP_KEYGEN 120
#define GOST_F_PKEY_GOST01_PARAMGEN 138
#define GOST_F_PKEY_GOST2001_DERIVE 121
#define GOST_F_PKEY_GOST94CP_DECRYPT 122
#define GOST_F_PKEY_GOST94CP_ENCRYPT 123
#define GOST_F_PKEY_GOST94CP_KEYGEN 124
#define GOST_F_PKEY_GOST94_PARAMGEN 139
#define GOST_F_PKEY_GOST_CTRL 125
#define GOST_F_PKEY_GOST_CTRL01_STR 126
#define GOST_F_PKEY_GOST_CTRL94_STR 127
#define GOST_F_PKEY_GOST_MAC_CTRL 128
#define GOST_F_PKEY_GOST_MAC_CTRL_STR 129
#define GOST_F_PKEY_GOST_MAC_KEYGEN 130
#define GOST_F_PRINT_GOST_01 131
#define GOST_F_PRIV_DECODE_GOST 132
#define GOST_F_PUB_DECODE_GOST01 133
#define GOST_F_PUB_DECODE_GOST94 134
#define GOST_F_PUB_ENCODE_GOST01 135
#define GOST_F_UNPACK_CC_SIGNATURE 136
#define GOST_F_UNPACK_CP_SIGNATURE 137
# define GOST_F_DECODE_GOST_ALGOR_PARAMS 99
# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100
# define GOST_F_FILL_GOST2001_PARAMS 101
# define GOST_F_FILL_GOST94_PARAMS 102
# define GOST_F_GET_ENCRYPTION_PARAMS 103
# define GOST_F_GOST2001_COMPUTE_PUBLIC 104
# define GOST_F_GOST2001_DO_SIGN 105
# define GOST_F_GOST2001_DO_VERIFY 106
# define GOST_F_GOST2001_KEYGEN 107
# define GOST_F_GOST89_GET_ASN1_PARAMETERS 108
# define GOST_F_GOST89_SET_ASN1_PARAMETERS 109
# define GOST_F_GOST94_COMPUTE_PUBLIC 110
# define GOST_F_GOST_CIPHER_CTL 111
# define GOST_F_GOST_DO_SIGN 112
# define GOST_F_GOST_DO_VERIFY 113
# define GOST_F_GOST_IMIT_CTRL 114
# define GOST_F_GOST_IMIT_FINAL 140
# define GOST_F_GOST_IMIT_UPDATE 115
# define GOST_F_GOST_SIGN_KEYGEN 142
# define GOST_F_PARAM_COPY_GOST01 116
# define GOST_F_PARAM_COPY_GOST94 117
# define GOST_F_PKEY_GOST01CP_DECRYPT 118
# define GOST_F_PKEY_GOST01CP_ENCRYPT 119
# define GOST_F_PKEY_GOST01CP_KEYGEN 120
# define GOST_F_PKEY_GOST01_PARAMGEN 138
# define GOST_F_PKEY_GOST2001_DERIVE 121
# define GOST_F_PKEY_GOST94CP_DECRYPT 122
# define GOST_F_PKEY_GOST94CP_ENCRYPT 123
# define GOST_F_PKEY_GOST94CP_KEYGEN 124
# define GOST_F_PKEY_GOST94_PARAMGEN 139
# define GOST_F_PKEY_GOST_CTRL 125
# define GOST_F_PKEY_GOST_CTRL01_STR 126
# define GOST_F_PKEY_GOST_CTRL94_STR 127
# define GOST_F_PKEY_GOST_MAC_CTRL 128
# define GOST_F_PKEY_GOST_MAC_CTRL_STR 129
# define GOST_F_PKEY_GOST_MAC_KEYGEN 130
# define GOST_F_PRINT_GOST_01 131
# define GOST_F_PRIV_DECODE_GOST 132
# define GOST_F_PUB_DECODE_GOST01 133
# define GOST_F_PUB_DECODE_GOST94 134
# define GOST_F_PUB_ENCODE_GOST01 135
# define GOST_F_UNPACK_CC_SIGNATURE 136
# define GOST_F_UNPACK_CP_SIGNATURE 137
/* Reason codes. */
#define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99
#define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100
#define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101
#define GOST_R_CTRL_CALL_FAILED 132
#define GOST_R_ERROR_COMPUTING_SHARED_KEY 102
#define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103
#define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104
#define GOST_R_INCOMPATIBLE_ALGORITHMS 105
#define GOST_R_INCOMPATIBLE_PEER_KEY 131
#define GOST_R_INVALID_CIPHER_PARAMS 106
#define GOST_R_INVALID_CIPHER_PARAM_OID 107
#define GOST_R_INVALID_DIGEST_TYPE 108
#define GOST_R_INVALID_GOST94_PARMSET 109
#define GOST_R_INVALID_IV_LENGTH 110
#define GOST_R_INVALID_MAC_KEY_LENGTH 111
#define GOST_R_INVALID_PARAMSET 112
#define GOST_R_KEY_IS_NOT_INITALIZED 113
#define GOST_R_KEY_IS_NOT_INITIALIZED 114
#define GOST_R_KEY_PARAMETERS_MISSING 115
#define GOST_R_MAC_KEY_NOT_SET 116
#define GOST_R_MALLOC_FAILURE 117
#define GOST_R_NO_MEMORY 118
#define GOST_R_NO_PARAMETERS_SET 119
#define GOST_R_NO_PEER_KEY 120
#define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121
#define GOST_R_PUBLIC_KEY_UNDEFINED 122
#define GOST_R_RANDOM_GENERATOR_ERROR 123
#define GOST_R_RANDOM_GENERATOR_FAILURE 124
#define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125
#define GOST_R_SIGNATURE_MISMATCH 126
#define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127
#define GOST_R_UKM_NOT_SET 128
#define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129
#define GOST_R_UNSUPPORTED_PARAMETER_SET 130
# define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99
# define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100
# define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101
# define GOST_R_CTRL_CALL_FAILED 132
# define GOST_R_ERROR_COMPUTING_SHARED_KEY 102
# define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103
# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104
# define GOST_R_INCOMPATIBLE_ALGORITHMS 105
# define GOST_R_INCOMPATIBLE_PEER_KEY 131
# define GOST_R_INVALID_CIPHER_PARAMS 106
# define GOST_R_INVALID_CIPHER_PARAM_OID 107
# define GOST_R_INVALID_DIGEST_TYPE 108
# define GOST_R_INVALID_GOST94_PARMSET 109
# define GOST_R_INVALID_IV_LENGTH 110
# define GOST_R_INVALID_MAC_KEY_LENGTH 111
# define GOST_R_INVALID_PARAMSET 112
# define GOST_R_KEY_IS_NOT_INITALIZED 113
# define GOST_R_KEY_IS_NOT_INITIALIZED 114
# define GOST_R_KEY_PARAMETERS_MISSING 115
# define GOST_R_MAC_KEY_NOT_SET 116
# define GOST_R_MALLOC_FAILURE 117
# define GOST_R_NO_MEMORY 118
# define GOST_R_NO_PARAMETERS_SET 119
# define GOST_R_NO_PEER_KEY 120
# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121
# define GOST_R_PUBLIC_KEY_UNDEFINED 122
# define GOST_R_RANDOM_GENERATOR_ERROR 123
# define GOST_R_RANDOM_GENERATOR_FAILURE 124
# define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125
# define GOST_R_SIGNATURE_MISMATCH 126
# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127
# define GOST_R_UKM_NOT_SET 128
# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129
# define GOST_R_UNSUPPORTED_PARAMETER_SET 130
#ifdef __cplusplus
}

Binary file not shown.

View File

@@ -3,7 +3,7 @@
* Copyright (c) 2005-2006 Cryptocom LTD *
* This file is distributed under the same license as OpenSSL *
* *
* Implementation of GOST R 34.10-2001 *
* Implementation of GOST R 34.10-2001 *
* Requires OpenSSL 0.9.9 for compilation *
**********************************************************************/
#include "gost_lcl.h"
@@ -14,13 +14,14 @@
#include <openssl/err.h>
#include "e_gost_err.h"
#ifdef DEBUG_SIGN
extern
void dump_signature(const char *message,const unsigned char *buffer,size_t len);
extern
void dump_signature(const char *message, const unsigned char *buffer,
size_t len);
void dump_dsa_sig(const char *message, DSA_SIG *sig);
#else
#define dump_signature(a,b,c)
#define dump_dsa_sig(a,b)
# define dump_signature(a,b,c)
# define dump_dsa_sig(a,b)
#endif
/*
@@ -30,314 +31,436 @@ void dump_dsa_sig(const char *message, DSA_SIG *sig);
*
* Also fils DSA->q field with copy of EC_GROUP order field to make
* DSA_size function work
*/
*/
int fill_GOST2001_params(EC_KEY *eckey, int nid)
{
R3410_2001_params *params = R3410_2001_paramset;
EC_GROUP *grp=NULL;
BIGNUM *p=NULL,*q=NULL,*a=NULL,*b=NULL,*x=NULL,*y=NULL;
EC_POINT *P=NULL;
BN_CTX *ctx=BN_CTX_new();
int ok=0;
BN_CTX_start(ctx);
p=BN_CTX_get(ctx);
a=BN_CTX_get(ctx);
b=BN_CTX_get(ctx);
x=BN_CTX_get(ctx);
y=BN_CTX_get(ctx);
q=BN_CTX_get(ctx);
while (params->nid!=NID_undef && params->nid != nid) params++;
if (params->nid == NID_undef)
{
GOSTerr(GOST_F_FILL_GOST2001_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
goto err;
}
BN_hex2bn(&p,params->p);
BN_hex2bn(&a,params->a);
BN_hex2bn(&b,params->b);
grp = EC_GROUP_new_curve_GFp(p,a,b,ctx);
{
R3410_2001_params *params = R3410_2001_paramset;
EC_GROUP *grp = NULL;
BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
EC_POINT *P = NULL;
BN_CTX *ctx = BN_CTX_new();
int ok = 0;
P = EC_POINT_new(grp);
if(!ctx) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_hex2bn(&x,params->x);
BN_hex2bn(&y,params->y);
EC_POINT_set_affine_coordinates_GFp(grp,P,x,y,ctx);
BN_hex2bn(&q,params->q);
BN_CTX_start(ctx);
p = BN_CTX_get(ctx);
a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
q = BN_CTX_get(ctx);
if(!p || !a || !b || !x || !y || !q) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
goto err;
}
while (params->nid != NID_undef && params->nid != nid)
params++;
if (params->nid == NID_undef) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
GOST_R_UNSUPPORTED_PARAMETER_SET);
goto err;
}
if(!BN_hex2bn(&p, params->p)
|| !BN_hex2bn(&a, params->a)
|| !BN_hex2bn(&b, params->b)) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS,
ERR_R_INTERNAL_ERROR);
goto err;
}
grp = EC_GROUP_new_curve_GFp(p, a, b, ctx);
if(!grp) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
goto err;
}
P = EC_POINT_new(grp);
if(!P) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE);
goto err;
}
if(!BN_hex2bn(&x, params->x)
|| !BN_hex2bn(&y, params->y)
|| !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx)
|| !BN_hex2bn(&q, params->q)) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifdef DEBUG_KEYS
fprintf(stderr,"Set params index %d oid %s\nq=",
(params-R3410_2001_paramset),OBJ_nid2sn(params->nid));
BN_print_fp(stderr,q);
fprintf(stderr,"\n");
#endif
EC_GROUP_set_generator(grp,P,q,NULL);
EC_GROUP_set_curve_name(grp,params->nid);
EC_KEY_set_group(eckey,grp);
ok=1;
err:
EC_POINT_free(P);
EC_GROUP_free(grp);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return ok;
}
fprintf(stderr, "Set params index %d oid %s\nq=",
(params - R3410_2001_paramset), OBJ_nid2sn(params->nid));
BN_print_fp(stderr, q);
fprintf(stderr, "\n");
#endif
if(!EC_GROUP_set_generator(grp, P, q, NULL)) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
goto err;
}
EC_GROUP_set_curve_name(grp, params->nid);
if(!EC_KEY_set_group(eckey, grp)) {
GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR);
goto err;
}
ok = 1;
err:
if (P) EC_POINT_free(P);
if (grp) EC_GROUP_free(grp);
if (ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
return ok;
}
/*
* Computes gost2001 signature as DSA_SIG structure
* Computes gost2001 signature as DSA_SIG structure
*
*
*/
DSA_SIG *gost2001_do_sign(const unsigned char *dgst,int dlen, EC_KEY *eckey)
{
DSA_SIG *newsig = NULL;
BIGNUM *md = hashsum2bn(dgst);
BIGNUM *order = NULL;
const EC_GROUP *group;
const BIGNUM *priv_key;
BIGNUM *r=NULL,*s=NULL,*X=NULL,*tmp=NULL,*tmp2=NULL, *k=NULL,*e=NULL;
EC_POINT *C=NULL;
BN_CTX *ctx = BN_CTX_new();
BN_CTX_start(ctx);
OPENSSL_assert(dlen==32);
newsig=DSA_SIG_new();
if (!newsig)
{
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_NO_MEMORY);
goto err;
}
group = EC_KEY_get0_group(eckey);
order=BN_CTX_get(ctx);
EC_GROUP_get_order(group,order,ctx);
priv_key = EC_KEY_get0_private_key(eckey);
e = BN_CTX_get(ctx);
BN_mod(e,md,order,ctx);
*/
DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
DSA_SIG *newsig = NULL, *ret = NULL;
BIGNUM *md = hashsum2bn(dgst);
BIGNUM *order = NULL;
const EC_GROUP *group;
const BIGNUM *priv_key;
BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k =
NULL, *e = NULL;
EC_POINT *C = NULL;
BN_CTX *ctx = BN_CTX_new();
if(!ctx || !md) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_CTX_start(ctx);
OPENSSL_assert(dlen == 32);
newsig = DSA_SIG_new();
if (!newsig) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, GOST_R_NO_MEMORY);
goto err;
}
group = EC_KEY_get0_group(eckey);
if(!group) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
order = BN_CTX_get(ctx);
if(!order || !EC_GROUP_get_order(group, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
priv_key = EC_KEY_get0_private_key(eckey);
if(!priv_key) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
e = BN_CTX_get(ctx);
if(!e || !BN_mod(e, md, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifdef DEBUG_SIGN
fprintf(stderr,"digest as bignum=");
BN_print_fp(stderr,md);
fprintf(stderr,"\ndigest mod q=");
BN_print_fp(stderr,e);
fprintf(stderr,"\n");
#endif
if (BN_is_zero(e))
{
BN_one(e);
}
k =BN_CTX_get(ctx);
C=EC_POINT_new(group);
do
{
do
{
if (!BN_rand_range(k,order))
{
GOSTerr(GOST_F_GOST2001_DO_SIGN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
DSA_SIG_free(newsig);
newsig = NULL;
goto err;
}
if (!EC_POINT_mul(group,C,k,NULL,NULL,ctx))
{
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
DSA_SIG_free(newsig);
newsig = NULL;
goto err;
}
if (!X) X=BN_CTX_get(ctx);
if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
{
GOSTerr(GOST_F_GOST2001_DO_SIGN,ERR_R_EC_LIB);
DSA_SIG_free(newsig);
newsig = NULL;
goto err;
}
if (!r) r=BN_CTX_get(ctx);
BN_nnmod(r,X,order,ctx);
}
while (BN_is_zero(r));
/* s = (r*priv_key+k*e) mod order */
if (!tmp) tmp = BN_CTX_get(ctx);
BN_mod_mul(tmp,priv_key,r,order,ctx);
if (!tmp2) tmp2 = BN_CTX_get(ctx);
BN_mod_mul(tmp2,k,e,order,ctx);
if (!s) s=BN_CTX_get(ctx);
BN_mod_add(s,tmp,tmp2,order,ctx);
}
while (BN_is_zero(s));
fprintf(stderr, "digest as bignum=");
BN_print_fp(stderr, md);
fprintf(stderr, "\ndigest mod q=");
BN_print_fp(stderr, e);
fprintf(stderr, "\n");
#endif
if (BN_is_zero(e)) {
BN_one(e);
}
k = BN_CTX_get(ctx);
C = EC_POINT_new(group);
if(!k || !C) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
do {
do {
if (!BN_rand_range(k, order)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN,
GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
goto err;
}
if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
if (!X)
X = BN_CTX_get(ctx);
if (!r)
r = BN_CTX_get(ctx);
if (!X || !r) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
if(!BN_nnmod(r, X, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
}
while (BN_is_zero(r));
/* s = (r*priv_key+k*e) mod order */
if (!tmp)
tmp = BN_CTX_get(ctx);
if (!tmp2)
tmp2 = BN_CTX_get(ctx);
if (!s)
s = BN_CTX_get(ctx);
if (!tmp || !tmp2 || !s) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
if(!BN_mod_mul(tmp, priv_key, r, order, ctx)
|| !BN_mod_mul(tmp2, k, e, order, ctx)
|| !BN_mod_add(s, tmp, tmp2, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR);
goto err;
}
}
while (BN_is_zero(s));
newsig->s = BN_dup(s);
newsig->r = BN_dup(r);
if(!newsig->s || !newsig->r) {
GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
ret = newsig;
err:
if(ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (C) EC_POINT_free(C);
if (md) BN_free(md);
if (!ret && newsig) {
DSA_SIG_free(newsig);
}
return ret;
}
newsig->s=BN_dup(s);
newsig->r=BN_dup(r);
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(C);
BN_free(md);
return newsig;
}
/*
* Verifies gost 2001 signature
*
*/
int gost2001_do_verify(const unsigned char *dgst,int dgst_len,
DSA_SIG *sig, EC_KEY *ec)
{
BN_CTX *ctx=BN_CTX_new();
const EC_GROUP *group = EC_KEY_get0_group(ec);
BIGNUM *order;
BIGNUM *md = NULL,*e=NULL,*R=NULL,*v=NULL,*z1=NULL,*z2=NULL;
BIGNUM *X=NULL,*tmp=NULL;
EC_POINT *C = NULL;
const EC_POINT *pub_key=NULL;
int ok=0;
*/
int gost2001_do_verify(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, EC_KEY *ec)
{
BN_CTX *ctx = BN_CTX_new();
const EC_GROUP *group = EC_KEY_get0_group(ec);
BIGNUM *order;
BIGNUM *md = NULL, *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 =
NULL;
BIGNUM *X = NULL, *tmp = NULL;
EC_POINT *C = NULL;
const EC_POINT *pub_key = NULL;
int ok = 0;
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
e = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
z2 = BN_CTX_get(ctx);
tmp = BN_CTX_get(ctx);
X= BN_CTX_get(ctx);
R=BN_CTX_get(ctx);
v=BN_CTX_get(ctx);
EC_GROUP_get_order(group,order,ctx);
pub_key = EC_KEY_get0_public_key(ec);
if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
(BN_cmp(sig->s,order)>=1) || (BN_cmp(sig->r,order)>=1))
{
GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
goto err;
if(!ctx || !group) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
}
md = hashsum2bn(dgst);
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
e = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
z2 = BN_CTX_get(ctx);
tmp = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
R = BN_CTX_get(ctx);
v = BN_CTX_get(ctx);
if(!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_mod(e,md,order,ctx);
pub_key = EC_KEY_get0_public_key(ec);
if(!pub_key || !EC_GROUP_get_order(group, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
if (BN_is_zero(sig->s) || BN_is_zero(sig->r) ||
(BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY,
GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
goto err;
}
md = hashsum2bn(dgst);
if(!md || !BN_mod(e, md, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifdef DEBUG_SIGN
fprintf(stderr,"digest as bignum: ");
BN_print_fp(stderr,md);
fprintf(stderr,"\ndigest mod q: ");
BN_print_fp(stderr,e);
#endif
if (BN_is_zero(e)) BN_one(e);
v=BN_mod_inverse(v,e,order,ctx);
BN_mod_mul(z1,sig->s,v,order,ctx);
BN_sub(tmp,order,sig->r);
BN_mod_mul(z2,tmp,v,order,ctx);
fprintf(stderr, "digest as bignum: ");
BN_print_fp(stderr, md);
fprintf(stderr, "\ndigest mod q: ");
BN_print_fp(stderr, e);
#endif
if (BN_is_zero(e) && !BN_one(e)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
v = BN_mod_inverse(v, e, order, ctx);
if(!v
|| !BN_mod_mul(z1, sig->s, v, order, ctx)
|| !BN_sub(tmp, order, sig->r)
|| !BN_mod_mul(z2, tmp, v, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifdef DEBUG_SIGN
fprintf(stderr,"\nInverted digest value: ");
BN_print_fp(stderr,v);
fprintf(stderr,"\nz1: ");
BN_print_fp(stderr,z1);
fprintf(stderr,"\nz2: ");
BN_print_fp(stderr,z2);
#endif
C = EC_POINT_new(group);
if (!EC_POINT_mul(group,C,z1,pub_key,z2,ctx))
{
GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group,C,X,NULL,ctx))
{
GOSTerr(GOST_F_GOST2001_DO_VERIFY,ERR_R_EC_LIB);
goto err;
}
BN_mod(R,X,order,ctx);
fprintf(stderr, "\nInverted digest value: ");
BN_print_fp(stderr, v);
fprintf(stderr, "\nz1: ");
BN_print_fp(stderr, z1);
fprintf(stderr, "\nz2: ");
BN_print_fp(stderr, z2);
#endif
C = EC_POINT_new(group);
if (!C) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB);
goto err;
}
if(!BN_mod(R, X, order, ctx)) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR);
goto err;
}
#ifdef DEBUG_SIGN
fprintf(stderr,"\nX=");
BN_print_fp(stderr,X);
fprintf(stderr,"\nX mod q=");
BN_print_fp(stderr,R);
fprintf(stderr,"\n");
#endif
if (BN_cmp(R,sig->r)!=0)
{
GOSTerr(GOST_F_GOST2001_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
}
else
{
ok = 1;
}
err:
EC_POINT_free(C);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
BN_free(md);
return ok;
}
fprintf(stderr, "\nX=");
BN_print_fp(stderr, X);
fprintf(stderr, "\nX mod q=");
BN_print_fp(stderr, R);
fprintf(stderr, "\n");
#endif
if (BN_cmp(R, sig->r) != 0) {
GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
} else {
ok = 1;
}
err:
if (C) EC_POINT_free(C);
if (ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if (md) BN_free(md);
return ok;
}
/*
* Computes GOST R 34.10-2001 public key
*
*
*/
int gost2001_compute_public(EC_KEY *ec)
{
const EC_GROUP *group = EC_KEY_get0_group(ec);
EC_POINT *pub_key=NULL;
const BIGNUM *priv_key=NULL;
BN_CTX *ctx=NULL;
int ok=0;
*/
int gost2001_compute_public(EC_KEY *ec)
{
const EC_GROUP *group = EC_KEY_get0_group(ec);
EC_POINT *pub_key = NULL;
const BIGNUM *priv_key = NULL;
BN_CTX *ctx = NULL;
int ok = 0;
if (!group)
{
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITIALIZED);
return 0;
}
ctx=BN_CTX_new();
BN_CTX_start(ctx);
if (!(priv_key=EC_KEY_get0_private_key(ec)))
{
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
goto err;
}
if (!group) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,
GOST_R_KEY_IS_NOT_INITIALIZED);
return 0;
}
ctx = BN_CTX_new();
if(!ctx) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_CTX_start(ctx);
if (!(priv_key = EC_KEY_get0_private_key(ec))) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
goto err;
}
pub_key = EC_POINT_new(group);
if(!pub_key) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
goto err;
}
if (!EC_KEY_set_public_key(ec, pub_key)) {
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB);
goto err;
}
ok = 256;
err:
if (pub_key) EC_POINT_free(pub_key);
if (ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
return ok;
}
pub_key = EC_POINT_new(group);
if (!EC_POINT_mul(group,pub_key,priv_key,NULL,NULL,ctx))
{
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
goto err;
}
if (!EC_KEY_set_public_key(ec,pub_key))
{
GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC,ERR_R_EC_LIB);
goto err;
}
ok = 256;
err:
BN_CTX_end(ctx);
EC_POINT_free(pub_key);
BN_CTX_free(ctx);
return ok;
}
/*
*
*
* Generates GOST R 34.10-2001 keypair
*
*
*/
*/
int gost2001_keygen(EC_KEY *ec)
{
BIGNUM *order = BN_new(),*d=BN_new();
const EC_GROUP *group = EC_KEY_get0_group(ec);
EC_GROUP_get_order(group,order,NULL);
do
{
if (!BN_rand_range(d,order))
{
GOSTerr(GOST_F_GOST2001_KEYGEN,GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
BN_free(d);
BN_free(order);
return 0;
}
}
while (BN_is_zero(d));
EC_KEY_set_private_key(ec,d);
BN_free(d);
BN_free(order);
return gost2001_compute_public(ec);
}
{
BIGNUM *order = BN_new(), *d = BN_new();
const EC_GROUP *group = EC_KEY_get0_group(ec);
if(!group || !EC_GROUP_get_order(group, order, NULL)) {
GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
BN_free(d);
BN_free(order);
return 0;
}
do {
if (!BN_rand_range(d, order)) {
GOSTerr(GOST_F_GOST2001_KEYGEN,
GOST_R_RANDOM_NUMBER_GENERATOR_FAILED);
BN_free(d);
BN_free(order);
return 0;
}
}
while (BN_is_zero(d));
if(!EC_KEY_set_private_key(ec, d)) {
GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR);
BN_free(d);
BN_free(order);
return 0;
}
BN_free(d);
BN_free(order);
return gost2001_compute_public(ec);
}

Binary file not shown.

View File

@@ -18,287 +18,275 @@
#include "gost_lcl.h"
#include "gost2001_keyx.h"
/* 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)
{
unsigned char ukm_be[8],databuf[64],hashbuf[64];
BIGNUM *UKM=NULL,*p=NULL,*order=NULL,*X=NULL,*Y=NULL;
const BIGNUM* key=EC_KEY_get0_private_key(priv_key);
EC_POINT *pnt=EC_POINT_new(EC_KEY_get0_group(priv_key));
int i;
gost_hash_ctx hash_ctx;
BN_CTX *ctx = BN_CTX_new();
for (i=0;i<8;i++)
{
ukm_be[7-i]=ukm[i];
}
BN_CTX_start(ctx);
UKM=getbnfrombuf(ukm_be,8);
p=BN_CTX_get(ctx);
order = BN_CTX_get(ctx);
X=BN_CTX_get(ctx);
Y=BN_CTX_get(ctx);
EC_GROUP_get_order(EC_KEY_get0_group(priv_key),order,ctx);
BN_mod_mul(p,key,UKM,order,ctx);
EC_POINT_mul(EC_KEY_get0_group(priv_key),pnt,NULL,pub_key,p,ctx);
EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key),
pnt,X,Y,ctx);
/*Serialize elliptic curve point same way as we do it when saving
* key */
store_bignum(Y,databuf,32);
store_bignum(X,databuf+32,32);
/* And reverse byte order of whole buffer */
for (i=0;i<64;i++)
{
hashbuf[63-i]=databuf[i];
}
init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
start_hash(&hash_ctx);
hash_block(&hash_ctx,hashbuf,64);
finish_hash(&hash_ctx,shared_key);
done_gost_hash_ctx(&hash_ctx);
BN_free(UKM);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(pnt);
return 32;
}
static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size,
const EC_POINT *pub_key, EC_KEY *priv_key,
const unsigned char *ukm)
{
unsigned char ukm_be[8], databuf[64], hashbuf[64];
BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL;
const BIGNUM *key = EC_KEY_get0_private_key(priv_key);
EC_POINT *pnt = EC_POINT_new(EC_KEY_get0_group(priv_key));
int i;
gost_hash_ctx hash_ctx;
BN_CTX *ctx = BN_CTX_new();
for (i = 0; i < 8; i++) {
ukm_be[7 - i] = ukm[i];
}
BN_CTX_start(ctx);
UKM = getbnfrombuf(ukm_be, 8);
p = BN_CTX_get(ctx);
order = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
Y = BN_CTX_get(ctx);
EC_GROUP_get_order(EC_KEY_get0_group(priv_key), order, ctx);
BN_mod_mul(p, key, UKM, order, ctx);
EC_POINT_mul(EC_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx);
EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key),
pnt, X, Y, ctx);
/*
* Serialize elliptic curve point same way as we do it when saving key
*/
store_bignum(Y, databuf, 32);
store_bignum(X, databuf + 32, 32);
/* And reverse byte order of whole buffer */
for (i = 0; i < 64; i++) {
hashbuf[63 - i] = databuf[i];
}
init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet);
start_hash(&hash_ctx);
hash_block(&hash_ctx, hashbuf, 64);
finish_hash(&hash_ctx, shared_key);
done_gost_hash_ctx(&hash_ctx);
BN_free(UKM);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
EC_POINT_free(pnt);
return 32;
}
/*
* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001
* algorithm
*/
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *keylen)
{
/* Public key of peer in the ctx field peerkey
* Our private key in the ctx pkey
* ukm is in the algorithm specific context data
*/
EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
if (!data->shared_ukm) {
GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
return 0;
}
/*
* Public key of peer in the ctx field peerkey Our private key in the ctx
* pkey ukm is in the algorithm specific context data
*/
EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx);
EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
if (key == NULL) {
*keylen = 32;
return 32;
}
*keylen=VKO_compute_key(key, 32, EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
(EC_KEY *)EVP_PKEY_get0(my_key),data->shared_ukm);
return 1;
if (!data->shared_ukm) {
GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET);
return 0;
}
if (key == NULL) {
*keylen = 32;
return 32;
}
*keylen =
VKO_compute_key(key, 32,
EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)),
(EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm);
return 1;
}
/*
* EVP_PKEY_METHOD callback encrypt
* Implementation of GOST2001 key transport, cryptocom variation
/*
* EVP_PKEY_METHOD callback encrypt
* Implementation of GOST2001 key transport, cryptocom variation
*/
/* Generates ephemeral key based on pubk algorithm
* computes shared key using VKO and returns filled up
* GOST_KEY_TRANSPORT structure
/*
* Generates ephemeral key based on pubk algorithm computes shared key using
* VKO and returns filled up GOST_KEY_TRANSPORT structure
*/
/*
* EVP_PKEY_METHOD callback encrypt
* Implementation of GOST2001 key transport, cryptopo variation
/*
* EVP_PKEY_METHOD callback encrypt
* Implementation of GOST2001 key transport, cryptopo variation
*/
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, size_t *out_len, const unsigned char *key,size_t key_len)
{
GOST_KEY_TRANSPORT *gkt=NULL;
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
const struct gost_cipher_info *param=get_encryption_params(NULL);
unsigned char ukm[8], shared_key[32], crypted_key[44];
int ret=0;
int key_is_ephemeral=1;
gost_ctx cctx;
EVP_PKEY *sec_key=EVP_PKEY_CTX_get0_peerkey(pctx);
if (data->shared_ukm)
{
memcpy(ukm, data->shared_ukm,8);
}
else if (out)
{
if (RAND_bytes(ukm,8)<=0)
{
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_RANDOM_GENERATOR_FAILURE);
return 0;
}
}
/* Check for private key in the peer_key of context */
if (sec_key)
{
key_is_ephemeral=0;
if (!gost_get0_priv_key(sec_key))
{
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
goto err;
}
}
else
{
key_is_ephemeral=1;
if (out)
{
sec_key = EVP_PKEY_new();
EVP_PKEY_assign(sec_key,EVP_PKEY_base_id(pubk),EC_KEY_new());
EVP_PKEY_copy_parameters(sec_key,pubk);
if (!gost2001_keygen(EVP_PKEY_get0(sec_key)))
{
goto err;
}
}
}
if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list)
{
param= gost_cipher_list+1;
}
if (out)
{
VKO_compute_key(shared_key,32,EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),EVP_PKEY_get0(sec_key),ukm);
gost_init(&cctx,param->sblock);
keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
}
gkt = GOST_KEY_TRANSPORT_new();
if (!gkt)
{
goto err;
}
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
ukm,8))
{
goto err;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
{
goto err;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
{
goto err;
}
if (key_is_ephemeral) {
if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?sec_key:pubk))
{
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
goto err;
}
}
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
if (!key_is_ephemeral)
{
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL))>0) ret =1;
GOST_KEY_TRANSPORT_free(gkt);
return ret;
err:
if (key_is_ephemeral && sec_key) EVP_PKEY_free(sec_key);
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}
/*
* EVP_PKEY_METHOD callback decrypt
* Implementation of GOST2001 key transport, cryptopo variation
int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out,
size_t *out_len, const unsigned char *key,
size_t key_len)
{
GOST_KEY_TRANSPORT *gkt = NULL;
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx);
const struct gost_cipher_info *param = get_encryption_params(NULL);
unsigned char ukm[8], shared_key[32], crypted_key[44];
int ret = 0;
int key_is_ephemeral = 1;
gost_ctx cctx;
EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx);
if (data->shared_ukm) {
memcpy(ukm, data->shared_ukm, 8);
} else if (out) {
if (RAND_bytes(ukm, 8) <= 0) {
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_RANDOM_GENERATOR_FAILURE);
return 0;
}
}
/* Check for private key in the peer_key of context */
if (sec_key) {
key_is_ephemeral = 0;
if (!gost_get0_priv_key(sec_key)) {
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
goto err;
}
} else {
key_is_ephemeral = 1;
if (out) {
sec_key = EVP_PKEY_new();
EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new());
EVP_PKEY_copy_parameters(sec_key, pubk);
if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) {
goto err;
}
}
}
if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS)
&& param == gost_cipher_list) {
param = gost_cipher_list + 1;
}
if (out) {
VKO_compute_key(shared_key, 32,
EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)),
EVP_PKEY_get0(sec_key), ukm);
gost_init(&cctx, param->sblock);
keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key);
}
gkt = GOST_KEY_TRANSPORT_new();
if (!gkt) {
goto err;
}
if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) {
goto err;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) {
goto err;
}
if (!ASN1_OCTET_STRING_set
(gkt->key_info->encrypted_key, crypted_key + 8, 32)) {
goto err;
}
if (key_is_ephemeral) {
if (!X509_PUBKEY_set
(&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) {
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT,
GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
goto err;
}
}
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
if (key_is_ephemeral && sec_key)
EVP_PKEY_free(sec_key);
if (!key_is_ephemeral) {
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL)
<= 0) {
GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0)
ret = 1;
GOST_KEY_TRANSPORT_free(gkt);
return ret;
err:
if (key_is_ephemeral && sec_key)
EVP_PKEY_free(sec_key);
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}
/*
* EVP_PKEY_METHOD callback decrypt
* Implementation of GOST2001 key transport, cryptopo variation
*/
int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, size_t * key_len, const unsigned char *in, size_t in_len)
{
const unsigned char *p = in;
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
GOST_KEY_TRANSPORT *gkt = NULL;
int ret=0;
unsigned char wrappedKey[44];
unsigned char sharedKey[32];
gost_ctx ctx;
const struct gost_cipher_info *param=NULL;
EVP_PKEY *eph_key=NULL, *peerkey=NULL;
int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key,
size_t *key_len, const unsigned char *in,
size_t in_len)
{
const unsigned char *p = in;
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx);
GOST_KEY_TRANSPORT *gkt = NULL;
int ret = 0;
unsigned char wrappedKey[44];
unsigned char sharedKey[32];
gost_ctx ctx;
const struct gost_cipher_info *param = NULL;
EVP_PKEY *eph_key = NULL, *peerkey = NULL;
if (!key)
{
*key_len = 32;
return 1;
}
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
in_len);
if (!gkt)
{
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
return -1;
}
if (!key) {
*key_len = 32;
return 1;
}
gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len);
if (!gkt) {
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
return -1;
}
/* If key transport structure contains public key, use it */
eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
if (eph_key)
{
if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_INCOMPATIBLE_PEER_KEY);
goto err;
}
}
else
{
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
if (!peerkey)
{
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_NO_PEER_KEY);
goto err;
}
param = get_encryption_params(gkt->key_agreement_info->cipher);
gost_init(&ctx,param->sblock);
OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
OPENSSL_assert(gkt->key_info->imit->length==4);
memcpy(wrappedKey+40,gkt->key_info->imit->data,4);
VKO_compute_key(sharedKey,32,EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
EVP_PKEY_get0(priv),wrappedKey);
if (!keyUnwrapCryptoPro(&ctx,sharedKey,wrappedKey,key))
{
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
}
ret=1;
err:
if (eph_key) EVP_PKEY_free(eph_key);
if (gkt) GOST_KEY_TRANSPORT_free(gkt);
return ret;
}
/* If key transport structure contains public key, use it */
eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
if (eph_key) {
if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) {
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_INCOMPATIBLE_PEER_KEY);
goto err;
}
} else {
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL)
<= 0) {
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
peerkey = EVP_PKEY_CTX_get0_peerkey(pctx);
if (!peerkey) {
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_NO_PEER_KEY);
goto err;
}
param = get_encryption_params(gkt->key_agreement_info->cipher);
if (!param) {
goto err;
}
gost_init(&ctx, param->sblock);
OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8);
memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8);
OPENSSL_assert(gkt->key_info->encrypted_key->length == 32);
memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
OPENSSL_assert(gkt->key_info->imit->length == 4);
memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
VKO_compute_key(sharedKey, 32,
EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)),
EVP_PKEY_get0(priv), wrappedKey);
if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) {
GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT,
GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
}
ret = 1;
err:
if (eph_key)
EVP_PKEY_free(eph_key);
if (gkt)
GOST_KEY_TRANSPORT_free(gkt);
return ret;
}

View File

@@ -1,10 +1,10 @@
GOST_KEY_TRANSPORT *
make_rfc4490_keytransport_2001(EVP_PKEY *pubk, BIGNUM *eph_key,
const unsigned char *key, size_t keylen,
unsigned char *ukm, size_t ukm_len);
GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk,
BIGNUM *eph_key,
const unsigned char *key,
size_t keylen,
unsigned char *ukm,
size_t ukm_len);
int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv,
GOST_KEY_TRANSPORT *gkt,
unsigned char *key_buf,
int key_buf_len) ;
GOST_KEY_TRANSPORT * gkt,
unsigned char *key_buf, int key_buf_len);

Binary file not shown.

View File

@@ -6,404 +6,571 @@
* Implementation of GOST 28147-89 encryption algorithm *
* No OpenSSL libraries required to compile and use *
* this code *
**********************************************************************/
**********************************************************************/
#include <string.h>
#include "gost89.h"
/* Substitution blocks from RFC 4357
Note: our implementation of gost 28147-89 algorithm
uses S-box matrix rotated 90 degrees counterclockwise, relative to
/*-
Substitution blocks from RFC 4357
Note: our implementation of gost 28147-89 algorithm
uses S-box matrix rotated 90 degrees counterclockwise, relative to
examples given in RFC.
*/
/* Substitution blocks from test examples for GOST R 34.11-94*/
gost_subst_block GostR3411_94_TestParamSet = {
{0X1,0XF,0XD,0X0,0X5,0X7,0XA,0X4,0X9,0X2,0X3,0XE,0X6,0XB,0X8,0XC},
{0XD,0XB,0X4,0X1,0X3,0XF,0X5,0X9,0X0,0XA,0XE,0X7,0X6,0X8,0X2,0XC},
{0X4,0XB,0XA,0X0,0X7,0X2,0X1,0XD,0X3,0X6,0X8,0X5,0X9,0XC,0XF,0XE},
{0X6,0XC,0X7,0X1,0X5,0XF,0XD,0X8,0X4,0XA,0X9,0XE,0X0,0X3,0XB,0X2},
{0X7,0XD,0XA,0X1,0X0,0X8,0X9,0XF,0XE,0X4,0X6,0XC,0XB,0X2,0X5,0X3},
{0X5,0X8,0X1,0XD,0XA,0X3,0X4,0X2,0XE,0XF,0XC,0X7,0X6,0X0,0X9,0XB},
{0XE,0XB,0X4,0XC,0X6,0XD,0XF,0XA,0X2,0X3,0X8,0X1,0X0,0X7,0X5,0X9},
{0X4,0XA,0X9,0X2,0XD,0X8,0X0,0XE,0X6,0XB,0X1,0XC,0X7,0XF,0X5,0X3}
};
{0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB,
0X8, 0XC}
,
{0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8,
0X2, 0XC}
,
{0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC,
0XF, 0XE}
,
{0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3,
0XB, 0X2}
,
{0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2,
0X5, 0X3}
,
{0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0,
0X9, 0XB}
,
{0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7,
0X5, 0X9}
,
{0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF,
0X5, 0X3}
};
/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */
gost_subst_block GostR3411_94_CryptoProParamSet= {
{0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC},
{0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB},
{0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3},
{0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5},
{0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3},
{0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD},
{0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8},
{0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF}
} ;
gost_subst_block GostR3411_94_CryptoProParamSet = {
{0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0,
0x2, 0xC}
,
{0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2,
0x9, 0xB}
,
{0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE,
0xC, 0x3}
,
{0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD,
0x3, 0x5}
,
{0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB,
0x9, 0x3}
,
{0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA,
0x8, 0xD}
,
{0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE,
0xA, 0x8}
,
{0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2,
0xB, 0xF}
};
/* Test paramset from GOST 28147 */
gost_subst_block Gost28147_TestParamSet =
{
{0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8},
{0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD},
{0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4},
{0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4},
{0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8},
{0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB},
{0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5},
{0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6}
};
gost_subst_block Gost28147_TestParamSet = {
{0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4,
0x1, 0x8}
,
{0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA,
0x2, 0xD}
,
{0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE,
0x2, 0x4}
,
{0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1,
0xF, 0x4}
,
{0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4,
0x3, 0x8}
,
{0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF,
0x0, 0xB}
,
{0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0,
0xB, 0x5}
,
{0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7,
0xA, 0x6}
};
/* 1.2.643.2.2.31.1 */
gost_subst_block Gost28147_CryptoProParamSetA= {
{0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4},
{0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE},
{0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6},
{0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6},
{0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6},
{0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9},
{0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1},
{0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5}
};
gost_subst_block Gost28147_CryptoProParamSetA = {
{0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7,
0xD, 0x4}
,
{0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3,
0xB, 0xE}
,
{0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF,
0xE, 0x6}
,
{0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7,
0xA, 0x6}
,
{0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8,
0x5, 0x6}
,
{0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7,
0x1, 0x9}
,
{0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4,
0xD, 0x1}
,
{0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0,
0xD, 0x5}
};
/* 1.2.643.2.2.31.2 */
gost_subst_block Gost28147_CryptoProParamSetB=
{
{0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC},
{0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE},
{0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5},
{0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3},
{0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8},
{0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4},
{0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE},
{0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF}
};
gost_subst_block Gost28147_CryptoProParamSetB = {
{0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD,
0x5, 0xC}
,
{0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF,
0x8, 0xE}
,
{0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0,
0x9, 0x5}
,
{0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8,
0xE, 0x3}
,
{0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE,
0x9, 0x8}
,
{0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6,
0x1, 0x4}
,
{0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8,
0x6, 0xE}
,
{0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6,
0x7, 0xF}
};
/* 1.2.643.2.2.31.3 */
gost_subst_block Gost28147_CryptoProParamSetC=
{
{0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8},
{0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7},
{0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD},
{0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7},
{0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4},
{0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB},
{0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3},
{0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3}
};
gost_subst_block Gost28147_CryptoProParamSetC = {
{0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9,
0x3, 0x8}
,
{0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1,
0xC, 0x7}
,
{0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0,
0xF, 0xD}
,
{0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF,
0xA, 0x7}
,
{0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF,
0xC, 0x4}
,
{0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE,
0x1, 0xB}
,
{0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA,
0x6, 0x3}
,
{0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7,
0x6, 0x3}
};
/* 1.2.643.2.2.31.4 */
gost_subst_block Gost28147_CryptoProParamSetD=
{
{0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE},
{0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7},
{0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6},
{0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1},
{0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8},
{0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2},
{0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1},
{0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3}
};
/* 1.2.643.2.2.31.4 */
gost_subst_block Gost28147_CryptoProParamSetD = {
{0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD,
0x2, 0xE}
,
{0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA,
0x5, 0x7}
,
{0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9,
0xD, 0x6}
,
{0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE,
0xF, 0x1}
,
{0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3,
0xF, 0x8}
,
{0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3,
0x7, 0x2}
,
{0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA,
0x9, 0x1}
,
{0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB,
0x8, 0x3}
};
const byte CryptoProKeyMeshingKey[] = {
0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
};
const byte CryptoProKeyMeshingKey[]={
0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23,
0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4,
0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12,
0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
};
/* Initialization of gost_ctx subst blocks*/
static void kboxinit(gost_ctx *c, const gost_subst_block *b)
{
int i;
for (i = 0; i < 256; i++)
{
c->k87[i] = (b->k8[i>>4] <<4 | b->k7 [i &15])<<24;
c->k65[i] = (b->k6[i>>4] << 4 | b->k5 [i &15])<<16;
c->k43[i] = (b->k4[i>>4] <<4 | b->k3 [i &15])<<8;
c->k21[i] = b->k2[i>>4] <<4 | b->k1 [i &15];
static void kboxinit(gost_ctx * c, const gost_subst_block * b)
{
int i;
}
}
for (i = 0; i < 256; i++) {
c->k87[i] = (word32) (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24;
c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16;
c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8;
c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15];
}
}
/* Part of GOST 28147 algorithm moved into separate function */
static word32 f(gost_ctx *c,word32 x)
{
x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255]|
c->k43[x>> 8 & 255] | c->k21[x & 255];
/* Rotate left 11 bits */
return x<<11 | x>>(32-11);
}
/* Low-level encryption routine - encrypts one 64 bit block*/
void gostcrypt(gost_ctx *c, const byte *in, byte *out)
{
register word32 n1, n2; /* As named in the GOST */
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
/* Instead of swapping halves, swap names each round */
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff);
out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff);
out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
}
/* Low-level decryption routine. Decrypts one 64-bit block */
void gostdecrypt(gost_ctx *c, const byte *in,byte *out)
{
register word32 n1, n2; /* As named in the GOST */
n1 = in[0]|(in[1]<<8)|(in[2]<<16)|(in[3]<<24);
n2 = in[4]|(in[5]<<8)|(in[6]<<16)|(in[7]<<24);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
static word32 f(gost_ctx * c, word32 x)
{
x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] |
c->k43[x >> 8 & 255] | c->k21[x & 255];
/* Rotate left 11 bits */
return x << 11 | x >> (32 - 11);
}
out[0] = (byte)(n2&0xff); out[1] = (byte)((n2>>8)&0xff);
out[2] = (byte)((n2>>16)&0xff); out[3]=(byte)(n2>>24);
out[4] = (byte)(n1&0xff); out[5] = (byte)((n1>>8)&0xff);
out[6] = (byte)((n1>>16)&0xff); out[7] = (byte)(n1>>24);
}
/* Low-level encryption routine - encrypts one 64 bit block*/
void gostcrypt(gost_ctx * c, const byte * in, byte * out)
{
register word32 n1, n2; /* As named in the GOST */
n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
/* Instead of swapping halves, swap names each round */
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
n2 ^= f(c, n1 + c->k[7]);
n1 ^= f(c, n2 + c->k[6]);
n2 ^= f(c, n1 + c->k[5]);
n1 ^= f(c, n2 + c->k[4]);
n2 ^= f(c, n1 + c->k[3]);
n1 ^= f(c, n2 + c->k[2]);
n2 ^= f(c, n1 + c->k[1]);
n1 ^= f(c, n2 + c->k[0]);
out[0] = (byte) (n2 & 0xff);
out[1] = (byte) ((n2 >> 8) & 0xff);
out[2] = (byte) ((n2 >> 16) & 0xff);
out[3] = (byte) (n2 >> 24);
out[4] = (byte) (n1 & 0xff);
out[5] = (byte) ((n1 >> 8) & 0xff);
out[6] = (byte) ((n1 >> 16) & 0xff);
out[7] = (byte) (n1 >> 24);
}
/* Low-level decryption routine. Decrypts one 64-bit block */
void gostdecrypt(gost_ctx * c, const byte * in, byte * out)
{
register word32 n1, n2; /* As named in the GOST */
n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24);
n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24);
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
n2 ^= f(c, n1 + c->k[7]);
n1 ^= f(c, n2 + c->k[6]);
n2 ^= f(c, n1 + c->k[5]);
n1 ^= f(c, n2 + c->k[4]);
n2 ^= f(c, n1 + c->k[3]);
n1 ^= f(c, n2 + c->k[2]);
n2 ^= f(c, n1 + c->k[1]);
n1 ^= f(c, n2 + c->k[0]);
n2 ^= f(c, n1 + c->k[7]);
n1 ^= f(c, n2 + c->k[6]);
n2 ^= f(c, n1 + c->k[5]);
n1 ^= f(c, n2 + c->k[4]);
n2 ^= f(c, n1 + c->k[3]);
n1 ^= f(c, n2 + c->k[2]);
n2 ^= f(c, n1 + c->k[1]);
n1 ^= f(c, n2 + c->k[0]);
n2 ^= f(c, n1 + c->k[7]);
n1 ^= f(c, n2 + c->k[6]);
n2 ^= f(c, n1 + c->k[5]);
n1 ^= f(c, n2 + c->k[4]);
n2 ^= f(c, n1 + c->k[3]);
n1 ^= f(c, n2 + c->k[2]);
n2 ^= f(c, n1 + c->k[1]);
n1 ^= f(c, n2 + c->k[0]);
out[0] = (byte) (n2 & 0xff);
out[1] = (byte) ((n2 >> 8) & 0xff);
out[2] = (byte) ((n2 >> 16) & 0xff);
out[3] = (byte) (n2 >> 24);
out[4] = (byte) (n1 & 0xff);
out[5] = (byte) ((n1 >> 8) & 0xff);
out[6] = (byte) ((n1 >> 16) & 0xff);
out[7] = (byte) (n1 >> 24);
}
/* Encrypts several blocks in ECB mode */
void gost_enc(gost_ctx *c,const byte *clear,byte *cipher, int blocks)
{
int i;
for(i=0;i<blocks;i++)
{
gostcrypt(c,clear,cipher);
clear+=8;
cipher+=8;
}
}
void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks)
{
int i;
for (i = 0; i < blocks; i++) {
gostcrypt(c, clear, cipher);
clear += 8;
cipher += 8;
}
}
/* Decrypts several blocks in ECB mode */
void gost_dec(gost_ctx *c, const byte *cipher,byte *clear, int blocks)
{
int i;
for(i=0;i<blocks;i++)
{
gostdecrypt(c,cipher,clear);
clear+=8;
cipher+=8;
}
}
void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks)
{
int i;
for (i = 0; i < blocks; i++) {
gostdecrypt(c, cipher, clear);
clear += 8;
cipher += 8;
}
}
/* Encrypts several full blocks in CFB mode using 8byte IV */
void gost_enc_cfb(gost_ctx *ctx,const byte *iv,const byte *clear,byte *cipher, int blocks)
{
byte cur_iv[8];
byte gamma[8];
int i,j;
const byte *in;
byte *out;
memcpy(cur_iv,iv,8);
for(i=0,in=clear,out=cipher;i<blocks;i++,in+=8,out+=8)
{
gostcrypt(ctx,cur_iv,gamma);
for (j=0;j<8;j++)
{
cur_iv[j]=out[j]=in[j]^gamma[j];
}
}
}
void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear,
byte * cipher, int blocks)
{
byte cur_iv[8];
byte gamma[8];
int i, j;
const byte *in;
byte *out;
memcpy(cur_iv, iv, 8);
for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) {
gostcrypt(ctx, cur_iv, gamma);
for (j = 0; j < 8; j++) {
cur_iv[j] = out[j] = in[j] ^ gamma[j];
}
}
}
/* Decrypts several full blocks in CFB mode using 8byte IV */
void gost_dec_cfb(gost_ctx *ctx,const byte *iv,const byte *cipher,byte *clear, int blocks)
{
byte cur_iv[8];
byte gamma[8];
int i,j;
const byte *in;
byte *out;
memcpy(cur_iv,iv,8);
for(i=0,in=cipher,out=clear;i<blocks;i++,in+=8,out+=8)
{
gostcrypt(ctx,cur_iv,gamma);
for (j=0;j<8;j++)
{
out[j]=(cur_iv[j]=in[j])^gamma[j];
}
}
}
void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher,
byte * clear, int blocks)
{
byte cur_iv[8];
byte gamma[8];
int i, j;
const byte *in;
byte *out;
memcpy(cur_iv, iv, 8);
for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) {
gostcrypt(ctx, cur_iv, gamma);
for (j = 0; j < 8; j++) {
out[j] = (cur_iv[j] = in[j]) ^ gamma[j];
}
}
}
/* Encrypts one block using specified key */
void gost_enc_with_key(gost_ctx *c,byte *key,byte *inblock,byte *outblock)
{
gost_key(c,key);
gostcrypt(c,inblock,outblock);
}
void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
byte * outblock)
{
gost_key(c, key);
gostcrypt(c, inblock, outblock);
}
/* Set 256 bit key into context */
void gost_key(gost_ctx *c, const byte *k)
{
int i,j;
for(i=0,j=0;i<8;i++,j+=4)
{
c->k[i]=k[j]|(k[j+1]<<8)|(k[j+2]<<16)|(k[j+3]<<24);
}
}
void gost_key(gost_ctx * c, const byte * k)
{
int i, j;
for (i = 0, j = 0; i < 8; i++, j += 4) {
c->k[i] =
k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] <<
24);
}
}
/* Retrieve 256-bit key from context */
void gost_get_key(gost_ctx *c, byte *k)
{
int i,j;
for(i=0,j=0;i<8;i++,j+=4)
{
k[j]=(byte)(c->k[i]& 0xFF);
k[j+1]=(byte)((c->k[i]>>8 )&0xFF);
k[j+2]=(byte)((c->k[i]>>16) &0xFF);
k[j+3]=(byte)((c->k[i]>>24) &0xFF);
}
}
void gost_get_key(gost_ctx * c, byte * k)
{
int i, j;
for (i = 0, j = 0; i < 8; i++, j += 4) {
k[j] = (byte) (c->k[i] & 0xFF);
k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF);
k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF);
k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF);
}
}
/* Initalize context. Provides default value for subst_block */
void gost_init(gost_ctx *c, const gost_subst_block *b)
{
if(!b)
{
b=&GostR3411_94_TestParamSet;
}
kboxinit(c,b);
}
void gost_init(gost_ctx * c, const gost_subst_block * b)
{
if (!b) {
b = &GostR3411_94_TestParamSet;
}
kboxinit(c, b);
}
/* Cleans up key from context */
void gost_destroy(gost_ctx *c)
{
int i; for(i=0;i<8;i++) c->k[i]=0;
}
void gost_destroy(gost_ctx * c)
{
int i;
for (i = 0; i < 8; i++)
c->k[i] = 0;
}
/* Compute GOST 28147 mac block
*
* Parameters
* gost_ctx *c - context initalized with substitution blocks and key
* buffer - 8-byte mac state buffer
* block 8-byte block to process.
* */
void mac_block(gost_ctx *c,byte *buffer,const byte *block)
{
register word32 n1, n2; /* As named in the GOST */
int i;
for (i=0; i<8; i++)
{
buffer[i]^=block[i];
}
n1 = buffer[0]|(buffer[1]<<8)|(buffer[2]<<16)|(buffer[3]<<24);
n2 = buffer[4]|(buffer[5]<<8)|(buffer[6]<<16)|(buffer[7]<<24);
/* Instead of swapping halves, swap names each round */
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
/*
* Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized
* with substitution blocks and key buffer - 8-byte mac state buffer block
* 8-byte block to process.
*/
void mac_block(gost_ctx * c, byte * buffer, const byte * block)
{
register word32 n1, n2; /* As named in the GOST */
int i;
for (i = 0; i < 8; i++) {
buffer[i] ^= block[i];
}
n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32)
buffer[3] << 24);
n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32)
buffer[7] << 24);
/* Instead of swapping halves, swap names each round */
buffer[0] = (byte)(n1&0xff); buffer[1] = (byte)((n1>>8)&0xff);
buffer[2] = (byte)((n1>>16)&0xff); buffer[3] = (byte)(n1>>24);
buffer[4] = (byte)(n2&0xff); buffer[5] = (byte)((n2>>8)&0xff);
buffer[6] = (byte)((n2>>16)&0xff); buffer[7] = (byte)(n2>>24);
}
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
n2 ^= f(c, n1 + c->k[0]);
n1 ^= f(c, n2 + c->k[1]);
n2 ^= f(c, n1 + c->k[2]);
n1 ^= f(c, n2 + c->k[3]);
n2 ^= f(c, n1 + c->k[4]);
n1 ^= f(c, n2 + c->k[5]);
n2 ^= f(c, n1 + c->k[6]);
n1 ^= f(c, n2 + c->k[7]);
buffer[0] = (byte) (n1 & 0xff);
buffer[1] = (byte) ((n1 >> 8) & 0xff);
buffer[2] = (byte) ((n1 >> 16) & 0xff);
buffer[3] = (byte) (n1 >> 24);
buffer[4] = (byte) (n2 & 0xff);
buffer[5] = (byte) ((n2 >> 8) & 0xff);
buffer[6] = (byte) ((n2 >> 16) & 0xff);
buffer[7] = (byte) (n2 >> 24);
}
/* Get mac with specified number of bits from MAC state buffer */
void get_mac(byte *buffer,int nbits,byte *out)
{
int nbytes= nbits >> 3;
int rembits = nbits & 7;
int mask =rembits?((1<rembits)-1):0;
int i;
for (i=0;i<nbytes;i++) out[i]=buffer[i];
if (rembits) out[i]=buffer[i]&mask;
}
void get_mac(byte * buffer, int nbits, byte * out)
{
int nbytes = nbits >> 3;
int rembits = nbits & 7;
int mask = rembits ? ((1 < rembits) - 1) : 0;
int i;
for (i = 0; i < nbytes; i++)
out[i] = buffer[i];
if (rembits)
out[i] = buffer[i] & mask;
}
/* Compute mac of specified length (in bits) from data.
* Context should be initialized with key and subst blocks */
int gost_mac(gost_ctx *ctx,int mac_len,const unsigned char *data,
unsigned int data_len,unsigned char *mac)
{
byte buffer[8]={0,0,0,0,0,0,0,0};
byte buf2[8];
unsigned int i;
for (i=0;i+8<=data_len;i+=8)
mac_block(ctx,buffer,data+i);
if (i<data_len)
{
memset(buf2,0,8);
memcpy(buf2,data+i,data_len-i);
mac_block(ctx,buffer,buf2);
}
get_mac(buffer,mac_len,mac);
return 1;
}
/*
* Compute mac of specified length (in bits) from data. Context should be
* initialized with key and subst blocks
*/
int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data,
unsigned int data_len, unsigned char *mac)
{
byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
byte buf2[8];
unsigned int i;
for (i = 0; i + 8 <= data_len; i += 8)
mac_block(ctx, buffer, data + i);
if (i < data_len) {
memset(buf2, 0, 8);
memcpy(buf2, data + i, data_len - i);
mac_block(ctx, buffer, buf2);
i += 8;
}
if (i == 8) {
memset(buf2, 0, 8);
mac_block(ctx, buffer, buf2);
}
get_mac(buffer, mac_len, mac);
return 1;
}
/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */
int gost_mac_iv(gost_ctx *ctx,int mac_len,const unsigned char *iv,const unsigned char *data,
unsigned int data_len,unsigned char *mac)
{
byte buffer[8];
byte buf2[8];
unsigned int i;
memcpy (buffer,iv,8);
for (i=0;i+8<=data_len;i+=8)
mac_block(ctx,buffer,data+i);
if (i<data_len)
{
memset(buf2,0,8);
memcpy(buf2,data+i,data_len-i);
mac_block(ctx,buffer,buf2);
}
get_mac(buffer,mac_len,mac);
return 1;
}
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)
{
byte buffer[8];
byte buf2[8];
unsigned int i;
memcpy(buffer, iv, 8);
for (i = 0; i + 8 <= data_len; i += 8)
mac_block(ctx, buffer, data + i);
if (i < data_len) {
memset(buf2, 0, 8);
memcpy(buf2, data + i, data_len - i);
mac_block(ctx, buffer, buf2);
i += 8;
}
if (i == 8) {
memset(buf2, 0, 8);
mac_block(ctx, buffer, buf2);
}
get_mac(buffer, mac_len, mac);
return 1;
}
/* Implements key meshing algorithm by modifing ctx and IV in place */
void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv)
{
unsigned char newkey[32],newiv[8];
/* Set static keymeshing key */
/* "Decrypt" key with keymeshing key */
gost_dec(ctx,CryptoProKeyMeshingKey,newkey,4);
/* set new key */
gost_key(ctx,newkey);
/* Encrypt iv with new key */
gostcrypt(ctx,iv,newiv);
memcpy(iv,newiv,8);
}
void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
{
unsigned char newkey[32], newiv[8];
/* Set static keymeshing key */
/* "Decrypt" key with keymeshing key */
gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4);
/* set new key */
gost_key(ctx, newkey);
/* Encrypt iv with new key */
gostcrypt(ctx, iv, newiv);
memcpy(iv, newiv, 8);
}

View File

@@ -6,78 +6,84 @@
* Declarations for GOST 28147-89 encryption algorithm *
* No OpenSSL libraries required to compile and use *
* this code *
**********************************************************************/
**********************************************************************/
#ifndef GOST89_H
#define GOST89_H
# define GOST89_H
/* Typedef for unsigned 32-bit integer */
#if __LONG_MAX__ > 2147483647L
typedef unsigned int u4;
#else
typedef unsigned long u4;
#endif
# if __LONG_MAX__ > 2147483647L
typedef unsigned int u4;
# else
typedef unsigned long u4;
# endif
/* Typedef for unsigned 8-bit integer */
typedef unsigned char byte;
typedef unsigned char byte;
/* Internal representation of GOST substitution blocks */
typedef struct {
byte k8[16];
byte k7[16];
byte k6[16];
byte k5[16];
byte k4[16];
byte k3[16];
byte k2[16];
byte k1[16];
} gost_subst_block;
byte k8[16];
byte k7[16];
byte k6[16];
byte k5[16];
byte k4[16];
byte k3[16];
byte k2[16];
byte k1[16];
} gost_subst_block;
/* Cipher context includes key and preprocessed substitution block */
typedef struct {
u4 k[8];
/* Constant s-boxes -- set up in gost_init(). */
u4 k87[256],k65[256],k43[256],k21[256];
} gost_ctx;
/* Note: encrypt and decrypt expect full blocks--padding blocks is
caller's responsibility. All bulk encryption is done in
ECB mode by these calls. Other modes may be added easily
enough. */
typedef struct {
u4 k[8];
/* Constant s-boxes -- set up in gost_init(). */
u4 k87[256], k65[256], k43[256], k21[256];
} gost_ctx;
/*
* Note: encrypt and decrypt expect full blocks--padding blocks is caller's
* responsibility. All bulk encryption is done in ECB mode by these calls.
* Other modes may be added easily enough.
*/
/* Encrypt several full blocks in ECB mode */
void gost_enc(gost_ctx *ctx, const byte *clear,byte *cipher, int blocks);
void gost_enc(gost_ctx * ctx, const byte * clear, byte * cipher, int blocks);
/* Decrypt several full blocks in ECB mode */
void gost_dec(gost_ctx *ctx, const byte *cipher,byte *clear, int blocks);
void gost_dec(gost_ctx * ctx, const byte * cipher, byte * clear, int blocks);
/* 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);
/* 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);
/* Encrypt one block */
void gostcrypt(gost_ctx *c, const byte *in, byte *out);
void gostcrypt(gost_ctx * c, const byte * in, byte * out);
/* Decrypt one block */
void gostdecrypt(gost_ctx *c, const byte *in,byte *out);
void gostdecrypt(gost_ctx * c, const byte * in, byte * out);
/* Set key into context */
void gost_key(gost_ctx *ctx, const byte *key);
void gost_key(gost_ctx * ctx, const byte * key);
/* Get key from context */
void gost_get_key(gost_ctx *ctx, byte *key);
void gost_get_key(gost_ctx * ctx, byte * key);
/* Set S-blocks into context */
void gost_init(gost_ctx *ctx, const gost_subst_block *subst_block);
void gost_init(gost_ctx * ctx, const gost_subst_block * subst_block);
/* Clean up context */
void gost_destroy(gost_ctx *ctx);
void gost_destroy(gost_ctx * ctx);
/* Intermediate function used for calculate hash */
void gost_enc_with_key(gost_ctx *,byte *key,byte *inblock,byte *outblock);
void gost_enc_with_key(gost_ctx *, byte * key, byte * inblock,
byte * outblock);
/* Compute MAC of given length in bits from data */
int gost_mac(gost_ctx *ctx,int hmac_len,const unsigned char *data,
unsigned int data_len,unsigned char *hmac) ;
/* Compute MAC of given length in bits from data, using non-zero 8-byte
* IV (non-standard, for use in CryptoPro key transport only */
int gost_mac_iv(gost_ctx *ctx,int hmac_len,const unsigned char *iv,const unsigned char *data,
unsigned int data_len,unsigned char *hmac) ;
int gost_mac(gost_ctx * ctx, int hmac_len, const unsigned char *data,
unsigned int data_len, unsigned char *hmac);
/*
* Compute MAC of given length in bits from data, using non-zero 8-byte IV
* (non-standard, for use in CryptoPro key transport only
*/
int gost_mac_iv(gost_ctx * ctx, int hmac_len, const unsigned char *iv,
const unsigned char *data, unsigned int data_len,
unsigned char *hmac);
/* Perform one step of MAC calculation like gostcrypt */
void mac_block(gost_ctx *c,byte *buffer,const byte *block);
void mac_block(gost_ctx * c, byte * buffer, const byte * block);
/* Extracts MAC value from mac state buffer */
void get_mac(byte *buffer,int nbits,byte *out);
void get_mac(byte * buffer, int nbits, byte * out);
/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/
void cryptopro_key_meshing(gost_ctx *ctx, unsigned char *iv);
void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv);
/* Parameter sets specified in RFC 4357 */
extern gost_subst_block GostR3411_94_TestParamSet;
extern gost_subst_block GostR3411_94_CryptoProParamSet;
@@ -86,11 +92,7 @@ extern gost_subst_block Gost28147_CryptoProParamSetA;
extern gost_subst_block Gost28147_CryptoProParamSetB;
extern gost_subst_block Gost28147_CryptoProParamSetC;
extern gost_subst_block Gost28147_CryptoProParamSetD;
extern const byte CryptoProKeyMeshingKey[];
#if __LONG_MAX__ > 2147483647L
typedef unsigned int word32;
#else
typedef unsigned long word32;
#endif
extern const byte CryptoProKeyMeshingKey[];
typedef unsigned int word32;
#endif

Binary file not shown.

View File

@@ -4,8 +4,8 @@
* This file is distributed under the same license as OpenSSL *
* *
* Implements generation and parsing of GOST_KEY_TRANSPORT for *
* GOST R 34.10-94 algorithms *
* *
* GOST R 34.10-94 algorithms *
* *
* Requires OpenSSL 0.9.9 for compilation *
**********************************************************************/
#include <string.h>
@@ -20,268 +20,261 @@
#include "gost_keywrap.h"
#include "gost_lcl.h"
/* Common functions for both 94 and 2001 key exchange schemes */
/* Implementation of the Diffi-Hellman key agreement scheme based on
* GOST-94 keys */
/* Computes Diffie-Hellman key and stores it into buffer in
* little-endian byte order as expected by both versions of GOST 94
* algorithm
/*
* Implementation of the Diffi-Hellman key agreement scheme based on GOST-94
* keys
*/
static int compute_pair_key_le(unsigned char *pair_key,BIGNUM *pub_key,DH *dh)
{
unsigned char be_key[128];
int i,key_size;
key_size=DH_compute_key(be_key,pub_key,dh);
if (!key_size) return 0;
memset(pair_key,0,128);
for (i=0;i<key_size;i++)
{
pair_key[i]=be_key[key_size-1-i];
}
return key_size;
}
/*
* Computes 256 bit Key exchange key as specified in RFC 4357
* Computes Diffie-Hellman key and stores it into buffer in little-endian
* byte order as expected by both versions of GOST 94 algorithm
*/
static int make_cp_exchange_key(BIGNUM *priv_key,EVP_PKEY *pubk, unsigned char *shared_key)
{
unsigned char dh_key [128];
int ret;
gost_hash_ctx hash_ctx;
DH *dh = DH_new();
if (!dh)
return 0;
memset(dh_key,0,128);
dh->g = BN_dup(pubk->pkey.dsa->g);
dh->p = BN_dup(pubk->pkey.dsa->p);
dh->priv_key = BN_dup(priv_key);
ret=compute_pair_key_le(dh_key,((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,dh) ;
DH_free(dh);
if (!ret) return 0;
init_gost_hash_ctx(&hash_ctx,&GostR3411_94_CryptoProParamSet);
start_hash(&hash_ctx);
hash_block(&hash_ctx,dh_key,128);
finish_hash(&hash_ctx,shared_key);
done_gost_hash_ctx(&hash_ctx);
return 1;
}
static int compute_pair_key_le(unsigned char *pair_key, BIGNUM *pub_key,
DH *dh)
{
unsigned char be_key[128];
int i, key_size;
key_size = DH_compute_key(be_key, pub_key, dh);
if (!key_size)
return 0;
memset(pair_key, 0, 128);
for (i = 0; i < key_size; i++) {
pair_key[i] = be_key[key_size - 1 - i];
}
return key_size;
}
/*
* Computes 256 bit Key exchange key as specified in RFC 4357
*/
static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk,
unsigned char *shared_key)
{
unsigned char dh_key[128];
int ret;
gost_hash_ctx hash_ctx;
DH *dh = DH_new();
if (!dh)
return 0;
memset(dh_key, 0, 128);
dh->g = BN_dup(pubk->pkey.dsa->g);
dh->p = BN_dup(pubk->pkey.dsa->p);
dh->priv_key = BN_dup(priv_key);
ret =
compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key,
dh);
DH_free(dh);
if (!ret)
return 0;
init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet);
start_hash(&hash_ctx);
hash_block(&hash_ctx, dh_key, 128);
finish_hash(&hash_ctx, shared_key);
done_gost_hash_ctx(&hash_ctx);
return 1;
}
/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */
int pkey_gost94_derive(EVP_PKEY_CTX *ctx,unsigned char *key,size_t *keylen)
{
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
*keylen = 32;
if (key == NULL) return 1;
int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
{
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx);
EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx);
*keylen = 32;
if (key == NULL)
return 1;
return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
}
return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key);
}
/* EVP_PKEY_METHOD callback encrypt for
* GOST R 34.10-94 cryptopro modification
/*
* EVP_PKEY_METHOD callback encrypt for GOST R 34.10-94 cryptopro
* modification
*/
int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
size_t *outlen, const unsigned char *key,
size_t key_len)
{
GOST_KEY_TRANSPORT *gkt = NULL;
unsigned char shared_key[32], ukm[8], crypted_key[44];
const struct gost_cipher_info *param = get_encryption_params(NULL);
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
gost_ctx cctx;
int key_is_ephemeral = 1;
int tmp_outlen;
EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
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;
unsigned char shared_key[32], ukm[8],crypted_key[44];
const struct gost_cipher_info *param=get_encryption_params(NULL);
EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx);
struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
gost_ctx cctx;
int key_is_ephemeral=1;
EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx);
/* Do not use vizir cipher parameters with cryptopro */
if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS)
&& param == gost_cipher_list) {
param = gost_cipher_list + 1;
}
/* Do not use vizir cipher parameters with cryptopro */
if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) && param == gost_cipher_list)
{
param= gost_cipher_list+1;
}
if (mykey) {
/* If key already set, it is not ephemeral */
key_is_ephemeral = 0;
if (!gost_get0_priv_key(mykey)) {
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
goto err;
}
} else {
/* Otherwise generate ephemeral key */
key_is_ephemeral = 1;
if (out) {
mykey = EVP_PKEY_new();
EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk), DSA_new());
EVP_PKEY_copy_parameters(mykey, pubk);
if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) {
goto err;
}
}
}
if (out)
make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, shared_key);
if (data->shared_ukm) {
memcpy(ukm, data->shared_ukm, 8);
} else if (out) {
if (RAND_bytes(ukm, 8) <= 0) {
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_RANDOM_GENERATOR_FAILURE);
goto err;
}
}
if (mykey)
{
/* If key already set, it is not ephemeral */
key_is_ephemeral=0;
if (!gost_get0_priv_key(mykey))
{
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR);
goto err;
}
}
else
{
/* Otherwise generate ephemeral key */
key_is_ephemeral = 1;
if (out)
{
mykey = EVP_PKEY_new();
EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk),DSA_new());
EVP_PKEY_copy_parameters(mykey,pubk);
if (!gost_sign_keygen(EVP_PKEY_get0(mykey)))
{
goto err;
}
}
}
if (out)
make_cp_exchange_key(gost_get0_priv_key(mykey),pubk,shared_key);
if (data->shared_ukm)
{
memcpy(ukm,data->shared_ukm,8);
}
else if (out)
{
if (RAND_bytes(ukm,8)<=0)
{
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_RANDOM_GENERATOR_FAILURE);
goto err;
}
}
if (out) {
gost_init(&cctx,param->sblock);
keyWrapCryptoPro(&cctx,shared_key,ukm,key,crypted_key);
}
gkt = GOST_KEY_TRANSPORT_new();
if (!gkt)
{
goto memerr;
}
if(!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv,
ukm,8))
{
goto memerr;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->imit,crypted_key+40,4))
{
goto memerr;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->encrypted_key,crypted_key+8,32))
{
goto memerr;
}
if (key_is_ephemeral) {
if (!X509_PUBKEY_set(&gkt->key_agreement_info->ephem_key,out?mykey:pubk))
{
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
goto err;
}
if (out) EVP_PKEY_free(mykey);
}
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
*outlen = i2d_GOST_KEY_TRANSPORT(gkt,out?&out:NULL);
if (*outlen <= 0)
{
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
goto err;
}
if (!key_is_ephemeral)
{
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
GOST_KEY_TRANSPORT_free(gkt);
return 1;
memerr:
if (key_is_ephemeral) {
EVP_PKEY_free(mykey);
}
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_MALLOC_FAILURE);
err:
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}
if (out) {
gost_init(&cctx, param->sblock);
keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key);
}
gkt = GOST_KEY_TRANSPORT_new();
if (!gkt) {
goto memerr;
}
if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) {
goto memerr;
}
if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) {
goto memerr;
}
if (!ASN1_OCTET_STRING_set
(gkt->key_info->encrypted_key, crypted_key + 8, 32)) {
goto memerr;
}
if (key_is_ephemeral) {
if (!X509_PUBKEY_set
(&gkt->key_agreement_info->ephem_key, out ? mykey : pubk)) {
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_CANNOT_PACK_EPHEMERAL_KEY);
goto err;
}
if (out)
EVP_PKEY_free(mykey);
}
ASN1_OBJECT_free(gkt->key_agreement_info->cipher);
gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid);
tmp_outlen = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL);
if (tmp_outlen <= 0) {
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT,
GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO);
goto err;
}
*outlen = tmp_outlen;
if (!key_is_ephemeral) {
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <=
0) {
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
GOST_KEY_TRANSPORT_free(gkt);
return 1;
memerr:
if (key_is_ephemeral) {
EVP_PKEY_free(mykey);
}
GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_MALLOC_FAILURE);
err:
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}
/* EVP_PLEY_METHOD callback decrypt for
* GOST R 34.10-94 cryptopro modification
/*
* EVP_PLEY_METHOD callback decrypt for GOST R 34.10-94 cryptopro
* modification
*/
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *key_len,const unsigned char *in, size_t in_len) {
const unsigned char *p = in;
GOST_KEY_TRANSPORT *gkt = NULL;
unsigned char wrappedKey[44];
unsigned char sharedKey[32];
gost_ctx cctx;
const struct gost_cipher_info *param=NULL;
EVP_PKEY *eph_key=NULL, *peerkey=NULL;
EVP_PKEY *priv= EVP_PKEY_CTX_get0_pkey(ctx);
if (!key)
{
*key_len = 32;
return 1;
}
gkt = d2i_GOST_KEY_TRANSPORT(NULL,(const unsigned char **)&p,
in_len);
if (!gkt)
{
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
return 0;
}
eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
if (eph_key)
{
if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_INCOMPATIBLE_PEER_KEY);
goto err;
}
}
else
{
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= 0)
{
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
if (!peerkey)
{
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_NO_PEER_KEY);
goto err;
}
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *key_len, const unsigned char *in,
size_t in_len)
{
const unsigned char *p = in;
GOST_KEY_TRANSPORT *gkt = NULL;
unsigned char wrappedKey[44];
unsigned char sharedKey[32];
gost_ctx cctx;
const struct gost_cipher_info *param = NULL;
EVP_PKEY *eph_key = NULL, *peerkey = NULL;
EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(ctx);
param = get_encryption_params(gkt->key_agreement_info->cipher);
gost_init(&cctx,param->sblock);
OPENSSL_assert(gkt->key_agreement_info->eph_iv->length==8);
memcpy(wrappedKey,gkt->key_agreement_info->eph_iv->data,8);
OPENSSL_assert(gkt->key_info->encrypted_key->length==32);
memcpy(wrappedKey+8,gkt->key_info->encrypted_key->data,32);
OPENSSL_assert(gkt->key_info->imit->length==4);
memcpy(wrappedKey+40,gkt->key_info->imit->data,4);
make_cp_exchange_key(gost_get0_priv_key(priv),peerkey,sharedKey);
if (!keyUnwrapCryptoPro(&cctx,sharedKey,wrappedKey,key))
{
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
}
EVP_PKEY_free(eph_key);
GOST_KEY_TRANSPORT_free(gkt);
return 1;
err:
EVP_PKEY_free(eph_key);
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}
if (!key) {
*key_len = 32;
return 1;
}
gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len);
if (!gkt) {
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO);
return 0;
}
eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key);
if (eph_key) {
if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0) {
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_INCOMPATIBLE_PEER_KEY);
goto err;
}
} else {
/* Set control "public key from client certificate used" */
if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <=
0) {
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_CTRL_CALL_FAILED);
goto err;
}
}
peerkey = EVP_PKEY_CTX_get0_peerkey(ctx);
if (!peerkey) {
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_NO_PEER_KEY);
goto err;
}
param = get_encryption_params(gkt->key_agreement_info->cipher);
if (!param) {
goto err;
}
gost_init(&cctx, param->sblock);
OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8);
memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8);
OPENSSL_assert(gkt->key_info->encrypted_key->length == 32);
memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32);
OPENSSL_assert(gkt->key_info->imit->length == 4);
memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4);
make_cp_exchange_key(gost_get0_priv_key(priv), peerkey, sharedKey);
if (!keyUnwrapCryptoPro(&cctx, sharedKey, wrappedKey, key)) {
GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT,
GOST_R_ERROR_COMPUTING_SHARED_KEY);
goto err;
}
EVP_PKEY_free(eph_key);
GOST_KEY_TRANSPORT_free(gkt);
return 1;
err:
EVP_PKEY_free(eph_key);
GOST_KEY_TRANSPORT_free(gkt);
return -1;
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -12,44 +12,45 @@
#include "gost_lcl.h"
ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = {
ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0)
ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO),
ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT)
IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT)
ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = {
ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING)
ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING),
ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO)
IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO)
ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = {
ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT),
ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0),
ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING)
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO)
IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO)
ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = {
ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT),
ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT),
ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT),
} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS)
IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS)
ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = {
ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING),
ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT),
} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS)
IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS)
ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /*FIXME incomplete*/
ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
} ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /* FIXME incomplete */
ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT)
}
ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -5,7 +5,7 @@
* *
* Implementation of control commands for GOST engine *
* OpenSSL 0.9.9 libraries required *
**********************************************************************/
**********************************************************************/
#include <stdlib.h>
#include <string.h>
#include <openssl/crypto.h>
@@ -14,76 +14,80 @@
#include <openssl/buffer.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}
};
static char *gost_params[GOST_PARAM_MAX + 1] = { NULL };
static const char *gost_envnames[] = { "CRYPT_PARAMS" };
void gost_param_free()
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}
};
void gost_param_free()
{
int i;
for (i=0;i<=GOST_PARAM_MAX;i++)
if (gost_params[i]!=NULL)
{
OPENSSL_free(gost_params[i]);
gost_params[i]=NULL;
}
int i;
for (i = 0; i <= GOST_PARAM_MAX; i++)
if (gost_params[i] != NULL) {
OPENSSL_free(gost_params[i]);
gost_params[i] = NULL;
}
}
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;
}
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)
{
if (gost_params[param]) OPENSSL_free(gost_params[param]);
gost_params[param] = BUF_strdup(tmp);
return gost_params[param];
}
return NULL;
}
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) {
if (gost_params[param])
OPENSSL_free(gost_params[param]);
gost_params[param] = BUF_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]) OPENSSL_free(gost_params[param]);
gost_params[param] = BUF_strdup(tmp);
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])
OPENSSL_free(gost_params[param]);
gost_params[param] = BUF_strdup(tmp);
return 1;
}
return 1;
}

Binary file not shown.

View File

@@ -16,258 +16,266 @@
#include "e_gost_err.h"
#include "gost_lcl.h"
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";
/* Symmetric cipher and digest function registrar */
static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid);
const int **nids, int nid);
static int gost_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int ind);
const int **nids, int ind);
static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid);
static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid);
static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
const int **nids, int nid);
static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
const int **nids, int nid);
static int gost_cipher_nids[] =
{NID_id_Gost28147_89, NID_gost89_cnt,0};
static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 };
static int gost_digest_nids[] =
{NID_id_GostR3411_94,NID_id_Gost28147_89_MAC, 0};
{ NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 };
static int gost_pkey_meth_nids[] =
{NID_id_GostR3410_94,
NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0};
static int gost_pkey_meth_nids[] = { NID_id_GostR3410_94,
NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0
};
static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL,
*pmeth_GostR3410_2001 = NULL,
*pmeth_Gost28147_MAC = NULL;
*pmeth_GostR3410_2001 = NULL, *pmeth_Gost28147_MAC = NULL;
static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL,
*ameth_GostR3410_2001 = NULL,
*ameth_Gost28147_MAC = NULL;
*ameth_GostR3410_2001 = NULL, *ameth_Gost28147_MAC = NULL;
static int gost_engine_init(ENGINE *e)
{
return 1;
}
{
return 1;
}
static int gost_engine_finish(ENGINE *e)
{
return 1;
}
{
return 1;
}
static int gost_engine_destroy(ENGINE *e)
{
gost_param_free();
return 1;
}
{
gost_param_free();
static int bind_gost (ENGINE *e,const char *id)
{
int ret = 0;
if (id && strcmp(id, engine_gost_id)) return 0;
pmeth_GostR3410_94 = NULL;
pmeth_GostR3410_2001 = NULL;
pmeth_Gost28147_MAC = NULL;
ameth_GostR3410_94 = NULL;
ameth_GostR3410_2001 = NULL;
ameth_Gost28147_MAC = NULL;
return 1;
}
if (!ENGINE_set_id(e, engine_gost_id))
{
printf("ENGINE_set_id failed\n");
goto end;
}
if (!ENGINE_set_name(e, engine_gost_name))
{
printf("ENGINE_set_name failed\n");
goto end;
}
if (!ENGINE_set_digests(e, gost_digests))
{
printf("ENGINE_set_digests failed\n");
goto end;
}
if (! ENGINE_set_ciphers(e, gost_ciphers))
{
printf("ENGINE_set_ciphers failed\n");
goto end;
}
if (! ENGINE_set_pkey_meths(e, gost_pkey_meths))
{
printf("ENGINE_set_pkey_meths failed\n");
goto end;
}
if (! ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths))
{
printf("ENGINE_set_pkey_asn1_meths failed\n");
goto end;
}
/* Control function and commands */
if (!ENGINE_set_cmd_defns(e,gost_cmds))
{
fprintf(stderr,"ENGINE_set_cmd_defns failed\n");
goto end;
}
if (!ENGINE_set_ctrl_function(e,gost_control_func))
{
fprintf(stderr,"ENGINE_set_ctrl_func failed\n");
goto end;
}
if ( ! ENGINE_set_destroy_function(e, gost_engine_destroy)
|| ! ENGINE_set_init_function(e,gost_engine_init)
|| ! ENGINE_set_finish_function(e,gost_engine_finish))
{
goto end;
}
static int bind_gost(ENGINE *e, const char *id)
{
int ret = 0;
if (id && strcmp(id, engine_gost_id))
return 0;
if (ameth_GostR3410_94) {
printf("GOST engine already loaded\n");
goto end;
}
if (!register_ameth_gost(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", "GOST R 34.10-94")) goto end;
if (!register_ameth_gost(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", "GOST R 34.10-2001")) goto end;
if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
"GOST-MAC", "GOST 28147-89 MAC")) goto end;
if (!ENGINE_set_id(e, engine_gost_id)) {
printf("ENGINE_set_id failed\n");
goto end;
}
if (!ENGINE_set_name(e, engine_gost_name)) {
printf("ENGINE_set_name failed\n");
goto end;
}
if (!ENGINE_set_digests(e, gost_digests)) {
printf("ENGINE_set_digests failed\n");
goto end;
}
if (!ENGINE_set_ciphers(e, gost_ciphers)) {
printf("ENGINE_set_ciphers failed\n");
goto end;
}
if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) {
printf("ENGINE_set_pkey_meths failed\n");
goto end;
}
if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) {
printf("ENGINE_set_pkey_asn1_meths failed\n");
goto end;
}
/* Control function and commands */
if (!ENGINE_set_cmd_defns(e, gost_cmds)) {
fprintf(stderr, "ENGINE_set_cmd_defns failed\n");
goto end;
}
if (!ENGINE_set_ctrl_function(e, gost_control_func)) {
fprintf(stderr, "ENGINE_set_ctrl_func failed\n");
goto end;
}
if (!ENGINE_set_destroy_function(e, gost_engine_destroy)
|| !ENGINE_set_init_function(e, gost_engine_init)
|| !ENGINE_set_finish_function(e, gost_engine_finish)) {
goto end;
}
if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end;
if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) goto end;
if (!register_pmeth_gost(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
goto end;
if ( ! ENGINE_register_ciphers(e)
|| ! ENGINE_register_digests(e)
|| ! ENGINE_register_pkey_meths(e)
/* These two actually should go in LIST_ADD command */
|| ! EVP_add_cipher(&cipher_gost)
|| ! EVP_add_cipher(&cipher_gost_cpacnt)
|| ! EVP_add_digest(&digest_gost)
|| ! EVP_add_digest(&imit_gost_cpa)
)
{
goto end;
}
if (!register_ameth_gost
(NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94",
"GOST R 34.10-94"))
goto end;
if (!register_ameth_gost
(NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001",
"GOST R 34.10-2001"))
goto end;
if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC,
"GOST-MAC", "GOST 28147-89 MAC"))
goto end;
ERR_load_GOST_strings();
ret = 1;
end:
return ret;
}
if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0))
goto end;
if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0))
goto end;
if (!register_pmeth_gost
(NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0))
goto end;
if (!ENGINE_register_ciphers(e)
|| !ENGINE_register_digests(e)
|| !ENGINE_register_pkey_meths(e)
/* These two actually should go in LIST_ADD command */
|| !EVP_add_cipher(&cipher_gost)
|| !EVP_add_cipher(&cipher_gost_cpacnt)
|| !EVP_add_digest(&digest_gost)
|| !EVP_add_digest(&imit_gost_cpa)
) {
goto end;
}
ERR_load_GOST_strings();
ret = 1;
end:
return ret;
}
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
IMPLEMENT_DYNAMIC_BIND_FN(bind_gost)
IMPLEMENT_DYNAMIC_CHECK_FN()
#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
IMPLEMENT_DYNAMIC_CHECK_FN()
#endif /* ndef OPENSSL_NO_DYNAMIC_ENGINE */
static int gost_digests(ENGINE *e, const EVP_MD **digest,
const int **nids, int nid)
{
int ok =1 ;
if (!digest)
{
*nids = gost_digest_nids;
return 2;
}
/*printf("Digest no %d requested\n",nid);*/
if(nid == NID_id_GostR3411_94)
{
*digest = &digest_gost;
}
else if (nid == NID_id_Gost28147_89_MAC)
{
*digest = &imit_gost_cpa;
}
else
{
ok =0;
*digest = NULL;
}
return ok;
}
static int gost_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
const int **nids, int nid)
{
int ok = 1;
if (!cipher)
{
*nids = gost_cipher_nids;
return 2; /* two ciphers are supported */
}
const int **nids, int nid)
{
int ok = 1;
if (!digest) {
*nids = gost_digest_nids;
return 2;
}
/*
* printf("Digest no %d requested\n",nid);
*/
if (nid == NID_id_GostR3411_94) {
*digest = &digest_gost;
} else if (nid == NID_id_Gost28147_89_MAC) {
*digest = &imit_gost_cpa;
} else {
ok = 0;
*digest = NULL;
}
return ok;
}
if(nid == NID_id_Gost28147_89)
{
*cipher = &cipher_gost;
}
else if (nid == NID_gost89_cnt)
{
*cipher = &cipher_gost_cpacnt;
}
else
{
ok = 0;
*cipher = NULL;
}
return ok;
}
static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
const int **nids, int nid)
{
int ok = 1;
if (!cipher) {
*nids = gost_cipher_nids;
return 2; /* two ciphers are supported */
}
static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid)
{
if (!pmeth)
{
*nids = gost_pkey_meth_nids;
return 3;
}
if (nid == NID_id_Gost28147_89) {
*cipher = &cipher_gost;
} else if (nid == NID_gost89_cnt) {
*cipher = &cipher_gost_cpacnt;
} else {
ok = 0;
*cipher = NULL;
}
return ok;
}
switch (nid)
{
case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1;
case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1;
case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1;
default:;
}
*pmeth = NULL;
return 0;
}
static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth,
const int **nids, int nid)
{
if (!pmeth) {
*nids = gost_pkey_meth_nids;
return 3;
}
static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
const int **nids, int nid)
{
if (!ameth)
{
*nids = gost_pkey_meth_nids;
return 3;
}
switch (nid)
{
case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1;
case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1;
case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1;
default:;
}
*ameth = NULL;
return 0;
}
switch (nid) {
case NID_id_GostR3410_94:
*pmeth = pmeth_GostR3410_94;
return 1;
case NID_id_GostR3410_2001:
*pmeth = pmeth_GostR3410_2001;
return 1;
case NID_id_Gost28147_89_MAC:
*pmeth = pmeth_Gost28147_MAC;
return 1;
default:;
}
*pmeth = NULL;
return 0;
}
static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth,
const int **nids, int nid)
{
if (!ameth) {
*nids = gost_pkey_meth_nids;
return 3;
}
switch (nid) {
case NID_id_GostR3410_94:
*ameth = ameth_GostR3410_94;
return 1;
case NID_id_GostR3410_2001:
*ameth = ameth_GostR3410_2001;
return 1;
case NID_id_Gost28147_89_MAC:
*ameth = ameth_Gost28147_MAC;
return 1;
default:;
}
*ameth = NULL;
return 0;
}
#ifdef OPENSSL_NO_DYNAMIC_ENGINE
static ENGINE *engine_gost(void)
{
ENGINE *ret = ENGINE_new();
if (!ret)
return NULL;
if (!bind_gost(ret,engine_gost_id))
{
ENGINE_free(ret);
return NULL;
}
return ret;
}
void ENGINE_load_gost(void)
{
ENGINE *toadd =engine_gost();
if (!toadd) return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
#endif
{
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;
if (pmeth_GostR3410_94)
return;
toadd = engine_gost();
if (!toadd)
return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
#endif

Binary file not shown.

View File

@@ -11,99 +11,96 @@
#include "gost89.h"
#include "gost_keywrap.h"
/* Diversifies key using random UserKey Material
* Implements RFC 4357 p 6.5 key diversification algorithm
*
/*-
* Diversifies key using random UserKey Material
* Implements RFC 4357 p 6.5 key diversification algorithm
*
* inputKey - 32byte key to be diversified
* ukm - 8byte user key material
* outputKey - 32byte buffer to store diversified key
* outputKey - 32byte buffer to store diversified key
*
*/
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;
int i,j,mask;
unsigned char S[8];
memcpy(outputKey,inputKey,32);
for (i=0;i<8;i++)
{
/* Make array of integers from key */
/* Compute IV S*/
s1=0,s2=0;
for (j=0,mask=1;j<8;j++,mask<<=1)
{
k=((u4)outputKey[4*j])|(outputKey[4*j+1]<<8)|
(outputKey[4*j+2]<<16)|(outputKey[4*j+3]<<24);
if (mask & ukm[i])
{
s1+=k;
}
else
{
s2+=k;
}
}
S[0]=(unsigned char)(s1&0xff);
S[1]=(unsigned char)((s1>>8)&0xff);
S[2]=(unsigned char)((s1>>16)&0xff);
S[3]=(unsigned char)((s1>>24)&0xff);
S[4]=(unsigned char)(s2&0xff);
S[5]=(unsigned char)((s2>>8)&0xff);
S[6]=(unsigned char)((s2>>16)&0xff);
S[7]=(unsigned char)((s2>>24)&0xff);
gost_key(ctx,outputKey);
gost_enc_cfb(ctx,S,outputKey,outputKey,4);
}
}
u4 k, s1, s2;
int i, j, mask;
unsigned char S[8];
memcpy(outputKey, inputKey, 32);
for (i = 0; i < 8; i++) {
/* Make array of integers from key */
/* Compute IV S */
s1 = 0, s2 = 0;
for (j = 0, mask = 1; j < 8; j++, mask <<= 1) {
k = ((u4) outputKey[4 * j]) | (outputKey[4 * j + 1] << 8) |
(outputKey[4 * j + 2] << 16) | (outputKey[4 * j + 3] << 24);
if (mask & ukm[i]) {
s1 += k;
} else {
s2 += k;
}
}
S[0] = (unsigned char)(s1 & 0xff);
S[1] = (unsigned char)((s1 >> 8) & 0xff);
S[2] = (unsigned char)((s1 >> 16) & 0xff);
S[3] = (unsigned char)((s1 >> 24) & 0xff);
S[4] = (unsigned char)(s2 & 0xff);
S[5] = (unsigned char)((s2 >> 8) & 0xff);
S[6] = (unsigned char)((s2 >> 16) & 0xff);
S[7] = (unsigned char)((s2 >> 24) & 0xff);
gost_key(ctx, outputKey);
gost_enc_cfb(ctx, S, outputKey, outputKey, 4);
}
}
/*
/*-
* Wraps key using RFC 4357 6.3
* ctx - gost encryption context, initialized with some S-boxes
* ctx - gost encryption context, initialized with some S-boxes
* keyExchangeKey (KEK) 32-byte (256-bit) shared key
* ukm - 8 byte (64 bit) user key material,
* ukm - 8 byte (64 bit) user key material,
* sessionKey - 32-byte (256-bit) key to be wrapped
* wrappedKey - 44-byte buffer to store wrapped key
*/
*/
int keyWrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey, const unsigned char *ukm,
const unsigned char *sessionKey, unsigned char *wrappedKey)
{
unsigned char kek_ukm[32];
keyDiversifyCryptoPro(ctx,keyExchangeKey,ukm,kek_ukm);
gost_key(ctx,kek_ukm);
memcpy(wrappedKey,ukm,8);
gost_enc(ctx,sessionKey,wrappedKey+8,4);
gost_mac_iv(ctx,32,ukm,sessionKey,32,wrappedKey+40);
return 1;
}
/*
int keyWrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey,
const unsigned char *ukm,
const unsigned char *sessionKey,
unsigned char *wrappedKey)
{
unsigned char kek_ukm[32];
keyDiversifyCryptoPro(ctx, keyExchangeKey, ukm, kek_ukm);
gost_key(ctx, kek_ukm);
memcpy(wrappedKey, ukm, 8);
gost_enc(ctx, sessionKey, wrappedKey + 8, 4);
gost_mac_iv(ctx, 32, ukm, sessionKey, 32, wrappedKey + 40);
return 1;
}
/*-
* Unwraps key using RFC 4357 6.4
* ctx - gost encryption context, initialized with some S-boxes
* ctx - gost encryption context, initialized with some S-boxes
* keyExchangeKey 32-byte shared key
* wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM,
* 32 byte encrypted key and 4 byte MAC
*
* 32 byte encrypted key and 4 byte MAC
*
* sessionKEy - 32byte buffer to store sessionKey in
* Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
*/
int keyUnwrapCryptoPro(gost_ctx *ctx,const unsigned char *keyExchangeKey,
const unsigned char *wrappedKey, unsigned char *sessionKey)
{
unsigned char kek_ukm[32],cek_mac[4];
keyDiversifyCryptoPro(ctx,keyExchangeKey,wrappedKey
/* First 8 bytes of wrapped Key is ukm */
,kek_ukm);
gost_key(ctx,kek_ukm);
gost_dec(ctx,wrappedKey+8,sessionKey,4);
gost_mac_iv(ctx,32,wrappedKey,sessionKey,32,cek_mac);
if (memcmp(cek_mac,wrappedKey+40,4))
{
return 0;
}
return 1;
}
*/
int keyUnwrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey,
const unsigned char *wrappedKey,
unsigned char *sessionKey)
{
unsigned char kek_ukm[32], cek_mac[4];
keyDiversifyCryptoPro(ctx, keyExchangeKey, wrappedKey
/* First 8 bytes of wrapped Key is ukm */
, kek_ukm);
gost_key(ctx, kek_ukm);
gost_dec(ctx, wrappedKey + 8, sessionKey, 4);
gost_mac_iv(ctx, 32, wrappedKey, sessionKey, 32, cek_mac);
if (memcmp(cek_mac, wrappedKey + 40, 4)) {
return 0;
}
return 1;
}

View File

@@ -8,49 +8,49 @@
* Doesn't need OpenSSL *
**********************************************************************/
#ifndef GOST_KEYWRAP_H
#define GOST_KEYWRAP_H
#include <string.h>
#include "gost89.h"
/* Diversifies key using random UserKey Material
* Implements RFC 4357 p 6.5 key diversification algorithm
*
# define GOST_KEYWRAP_H
# include <string.h>
# include "gost89.h"
/*-
* Diversifies key using random UserKey Material
* Implements RFC 4357 p 6.5 key diversification algorithm
*
* inputKey - 32byte key to be diversified
* ukm - 8byte user key material
* outputKey - 32byte buffer to store diversified key
* outputKey - 32byte buffer to store diversified key
*
*/
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);
/*-
* Wraps key using RFC 4357 6.3
* ctx - gost encryption context, initialized with some S-boxes
* ctx - gost encryption context, initialized with some S-boxes
* keyExchangeKey (KEK) 32-byte (256-bit) shared key
* ukm - 8 byte (64 bit) user key material,
* ukm - 8 byte (64 bit) user key material,
* sessionKey - 32-byte (256-bit) key to be wrapped
* wrappedKey - 44-byte buffer to store wrapped key
*/
*/
int keyWrapCryptoPro(gost_ctx *ctx,
const unsigned char *keyExchangeKey,
const unsigned char *ukm,
const unsigned char *sessionKey,
unsigned char *wrappedKey) ;
/*
int keyWrapCryptoPro(gost_ctx * ctx,
const unsigned char *keyExchangeKey,
const unsigned char *ukm,
const unsigned char *sessionKey,
unsigned char *wrappedKey);
/*-
* 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
* keyExchangeKey 32-byte shared key
* wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM,
* 32 byte encrypted key and 4 byte MAC
*
* 32 byte encrypted key and 4 byte MAC
*
* sessionKEy - 32byte buffer to store sessionKey in
* Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match
*/
*/
int keyUnwrapCryptoPro(gost_ctx *ctx,
const unsigned char *keyExchangeKey,
const unsigned char *wrappedKey,
unsigned char *sessionKey) ;
int keyUnwrapCryptoPro(gost_ctx * ctx,
const unsigned char *keyExchangeKey,
const unsigned char *wrappedKey,
unsigned char *sessionKey);
#endif

Binary file not shown.

View File

@@ -1,5 +1,5 @@
#ifndef GOST_TOOLS_H
#define GOST_TOOLS_H
# define GOST_TOOLS_H
/**********************************************************************
* gost_lcl.h *
* Copyright (c) 2006 Cryptocom LTD *
@@ -8,154 +8,155 @@
* 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 "gost89.h"
#include "gosthash.h"
**********************************************************************/
# 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 "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)
# 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);
void gost_param_free(void);
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);
void gost_param_free(void);
/* 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);
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 */
/* For GOST R34.10 parameters */
#define param_ctrl_string "paramset"
#define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1)
# define param_ctrl_string "paramset"
# define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1)
/* For GOST 28147 MAC */
#define key_ctrl_string "key"
#define hexkey_ctrl_string "hexkey"
#define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3)
# define key_ctrl_string "key"
# define hexkey_ctrl_string "hexkey"
# define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3)
/* Pmeth internal representation */
struct gost_pmeth_data {
int sign_param_nid; /* Should be set whenever parameters are filled */
EVP_MD *md;
unsigned char *shared_ukm;
int peer_key_used;
};
struct gost_pmeth_data {
int sign_param_nid; /* Should be set whenever parameters are
* filled */
EVP_MD *md;
unsigned char *shared_ukm;
int peer_key_used;
};
struct gost_mac_pmeth_data {
int key_set;
EVP_MD *md;
unsigned char key[32];
} ;
struct gost_mac_pmeth_data {
int key_set;
EVP_MD *md;
unsigned char key[32];
};
/* GOST-specific ASN1 structures */
typedef struct {
ASN1_OCTET_STRING *encrypted_key;
ASN1_OCTET_STRING *imit;
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;
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_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;
typedef struct { /* FIXME incomplete */
GOST_KEY_TRANSPORT *gkt;
} GOST_CLIENT_KEY_EXCHANGE_PARAMS;
/* Hacks to shorten symbols to 31 characters or less, or OpenVMS.
This mimics what's done in symhacks.h, but since this is a very
local header file, I prefered to put this hack directly here.
-- Richard Levitte */
#ifdef OPENSSL_SYS_VMS
#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it
#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it
#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new
#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new
#undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free
#define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free
#undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS
#define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS
#undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS
#define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS
#endif /* End of hack */
/*
* Hacks to shorten symbols to 31 characters or less, or OpenVMS. This mimics
* what's done in symhacks.h, but since this is a very local header file, I
* prefered to put this hack directly here. -- Richard Levitte
*/
# ifdef OPENSSL_SYS_VMS
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new
# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free
# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free
# undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS
# define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS
# undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS
# define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS
# endif /* End of hack */
DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS)
typedef struct {
ASN1_OBJECT *key_params;
ASN1_OBJECT *hash_params;
ASN1_OBJECT *cipher_params;
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;
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.
* */
/*
* 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;
};
gost_hash_ctx dctx;
gost_ctx cctx;
};
/* EVP_MD structure for GOST R 34.11 */
extern EVP_MD digest_gost;
/* EVP_MD structure for GOST 28147 in MAC mode */
extern EVP_MD imit_gost_cpa;
/* Cipher context used for EVP_CIPHER operation */
struct ossl_gost_cipher_ctx {
int paramNID;
off_t count;
int key_meshing;
gost_ctx cctx;
};
int paramNID;
unsigned int 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;
int nid;
gost_subst_block *sblock;
int key_meshing;
};
/* 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;
};
gost_ctx cctx;
unsigned char buffer[8];
unsigned char partial_block[8];
unsigned int count;
int key_meshing;
int bytes_left;
int key_set;
};
/* Table which maps parameter NID to S-blocks */
extern struct gost_cipher_info gost_cipher_list[];
/* Find encryption params from ASN1_OBJECT */
@@ -163,56 +164,66 @@ 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;
extern EVP_CIPHER cipher_gost_cpacnt;
#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3)
#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4)
# define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3)
# define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4)
/* EVP_PKEY_METHOD key encryption callbacks */
/* From gost94_keyx.c */
int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, 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);
int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, const unsigned char* in, size_t in_len );
int pkey_GOST94cp_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_GOST01cp_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_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out,
size_t *outlen, const unsigned char *in,
size_t in_len);
/* derive functions */
/* From gost2001_keyx.c */
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
size_t *keylen);
/* From gost94_keyx.c */
int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
/* Internal functions for signature algorithms */
int fill_GOST94_params(DSA *dsa,int nid);
int fill_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) ;
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);
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) ;
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);
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 CryptoPro rules */
int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen);
int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen);
/* Unpack GOST R 34.10 signature according to CryptoPro rules */
DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen) ;
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*/
/* Returns pointer into EVP_PKEY structure */
BIGNUM* gost_get0_priv_key(const EVP_PKEY *pkey) ;
BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey);
/* Find NID by GOST 94 parameters */
int gost94_nid_by_params(DSA *p) ;
int gost94_nid_by_params(DSA *p);
#endif

View File

@@ -13,63 +13,64 @@
/* implementation of GOST 34.11 hash function See gost_md.c*/
static int gost_digest_init(EVP_MD_CTX *ctx);
static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count);
static int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md);
static int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from);
static int gost_digest_update(EVP_MD_CTX *ctx, const void *data,
size_t count);
static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
static int gost_digest_cleanup(EVP_MD_CTX *ctx);
EVP_MD digest_gost=
{
NID_id_GostR3411_94,
NID_undef,
32,
EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
gost_digest_init,
gost_digest_update,
gost_digest_final,
gost_digest_copy,
gost_digest_cleanup,
NULL,
NULL,
{NID_undef,NID_undef,0,0,0},
32,
sizeof(struct ossl_gost_digest_ctx ),
NULL
};
EVP_MD digest_gost = {
NID_id_GostR3411_94,
NID_undef,
32,
EVP_MD_FLAG_PKEY_METHOD_SIGNATURE,
gost_digest_init,
gost_digest_update,
gost_digest_final,
gost_digest_copy,
gost_digest_cleanup,
NULL,
NULL,
{NID_undef, NID_undef, 0, 0, 0},
32,
sizeof(struct ossl_gost_digest_ctx),
NULL
};
int gost_digest_init(EVP_MD_CTX *ctx)
{
struct ossl_gost_digest_ctx *c = ctx->md_data;
memset(&(c->dctx),0,sizeof(gost_hash_ctx));
gost_init(&(c->cctx),&GostR3411_94_CryptoProParamSet);
c->dctx.cipher_ctx= &(c->cctx);
return 1;
}
int gost_digest_init(EVP_MD_CTX *ctx)
{
struct ossl_gost_digest_ctx *c = ctx->md_data;
memset(&(c->dctx), 0, sizeof(gost_hash_ctx));
gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet);
c->dctx.cipher_ctx = &(c->cctx);
return 1;
}
int gost_digest_update(EVP_MD_CTX *ctx,const void *data,size_t count)
{
return hash_block((gost_hash_ctx *)ctx->md_data,data,count);
}
int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
{
return hash_block((gost_hash_ctx *) ctx->md_data, data, count);
}
int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md)
{
return finish_hash((gost_hash_ctx *)ctx->md_data,md);
}
int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
{
return finish_hash((gost_hash_ctx *) ctx->md_data, md);
int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from)
{
struct ossl_gost_digest_ctx *md_ctx=to->md_data;
if (to->md_data && from->md_data) {
memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
md_ctx->dctx.cipher_ctx=&(md_ctx->cctx);
}
return 1;
}
}
int gost_digest_cleanup(EVP_MD_CTX *ctx)
{
if (ctx->md_data)
memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
return 1;
}
int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
{
struct ossl_gost_digest_ctx *md_ctx = to->md_data;
if (to->md_data && from->md_data) {
memcpy(to->md_data, from->md_data,
sizeof(struct ossl_gost_digest_ctx));
md_ctx->dctx.cipher_ctx = &(md_ctx->cctx);
}
return 1;
}
int gost_digest_cleanup(EVP_MD_CTX *ctx)
{
if (ctx->md_data)
memset(ctx->md_data, 0, sizeof(struct ossl_gost_digest_ctx));
return 1;
}

Binary file not shown.

View File

@@ -6,193 +6,202 @@
* Definitions of GOST R 34.10 parameter sets, defined in RFC 4357 *
* OpenSSL 0.9.9 libraries required to compile and use *
* this code *
**********************************************************************/
**********************************************************************/
#include "gost_params.h"
#include <openssl/objects.h>
/* Parameters of GOST 34.10 */
R3410_params R3410_paramset[]={
R3410_params R3410_paramset[] = {
/* Paramset A */
{NID_id_GostR3410_94_CryptoPro_A_ParamSet,
"100997906755055304772081815535925224869"
"8410825720534578748235158755771479905292727772441528526992987964833"
"5669968284202797289605274717317548059048560713474685214192868091256"
"1502802222185647539190902656116367847270145019066794290930185446216"
"3997308722217328898303231940973554032134009725883228768509467406639"
"62",
"127021248288932417465907042777176443525"
"7876535089165358128175072657050312609850984974231883334834011809259"
"9999512098893413065920561499672425412104927434935707492031276956145"
"1689224110579311248812610229678534638401693520013288995000362260684"
"2227508135323070045173416336850045410625869714168836867788425378203"
"83",
"683631961449557007844441656118272528951"
"02170888761442055095051287550314083023"},
{NID_id_GostR3410_94_CryptoPro_B_ParamSet,
"429418261486158041438734477379555023926"
"7234596860714306679811299408947123142002706038521669956384871995765"
"7284814898909770759462613437669456364882730370838934791080835932647"
"9767786019153434744009610342313166725786869204821949328786333602033"
"8479709268434224762105576023501613261478065276102850944540333865234"
"1",
"139454871199115825601409655107690713107"
"0417070599280317977580014543757653577229840941243685222882398330391"
"1468164807668823692122073732267216074074777170091113455043205380464"
"7694904686120113087816240740184800477047157336662926249423571248823"
"9685422217536601433914856808405203368594584948031873412885804895251"
"63",
"79885141663410976897627118935756323747307951916507639758300472692338873533959"
},
{NID_id_GostR3410_94_CryptoPro_C_ParamSet,
"816552717970881016017893191415300348226"
"2544051353358162468249467681876621283478212884286545844013955142622"
"2087723485023722868022275009502224827866201744494021697716482008353"
"6398202298024892620480898699335508064332313529725332208819456895108"
"5155178100221003459370588291073071186553005962149936840737128710832"
"3",
"110624679233511963040518952417017040248"
"5862954819831383774196396298584395948970608956170224210628525560327"
"8638246716655439297654402921844747893079518669992827880792192992701"
"1428546551433875806377110443534293554066712653034996277099320715774"
"3542287621283671843703709141350171945045805050291770503634517804938"
"01",
"113468861199819350564868233378875198043"
"267947776488510997961231672532899549103"
},
{NID_id_GostR3410_94_CryptoPro_D_ParamSet,
"756976611021707301782128757801610628085"
"5283803109571158829574281419208532589041660017017859858216341400371"
"4687551412794400562878935266630754392677014598582103365983119173924"
"4732511225464712252386803315902707727668715343476086350472025298282"
"7271461690125050616858238384366331089777463541013033926723743254833"
"7",
"905457649621929965904290958774625315611"
"3056083907389766971404812524422262512556054474620855996091570786713"
"5849550236741915584185990627801066465809510095784713989819413820871"
"5964648914493053407920737078890520482730623038837767710173664838239"
"8574828787891286471201460474326612697849693665518073864436497893214"
"9",
"108988435796353506912374591498972192620"
"190487557619582334771735390599299211593"
},
{NID_id_GostR3410_94_CryptoPro_A_ParamSet,
"100997906755055304772081815535925224869"
"8410825720534578748235158755771479905292727772441528526992987964833"
"5669968284202797289605274717317548059048560713474685214192868091256"
"1502802222185647539190902656116367847270145019066794290930185446216"
"3997308722217328898303231940973554032134009725883228768509467406639"
"62",
"127021248288932417465907042777176443525"
"7876535089165358128175072657050312609850984974231883334834011809259"
"9999512098893413065920561499672425412104927434935707492031276956145"
"1689224110579311248812610229678534638401693520013288995000362260684"
"2227508135323070045173416336850045410625869714168836867788425378203"
"83",
"683631961449557007844441656118272528951"
"02170888761442055095051287550314083023"}
,
{NID_id_GostR3410_94_CryptoPro_B_ParamSet,
"429418261486158041438734477379555023926"
"7234596860714306679811299408947123142002706038521669956384871995765"
"7284814898909770759462613437669456364882730370838934791080835932647"
"9767786019153434744009610342313166725786869204821949328786333602033"
"8479709268434224762105576023501613261478065276102850944540333865234"
"1",
"139454871199115825601409655107690713107"
"0417070599280317977580014543757653577229840941243685222882398330391"
"1468164807668823692122073732267216074074777170091113455043205380464"
"7694904686120113087816240740184800477047157336662926249423571248823"
"9685422217536601433914856808405203368594584948031873412885804895251"
"63",
"79885141663410976897627118935756323747307951916507639758300472692338873533959"}
,
{NID_id_GostR3410_94_CryptoPro_C_ParamSet,
"816552717970881016017893191415300348226"
"2544051353358162468249467681876621283478212884286545844013955142622"
"2087723485023722868022275009502224827866201744494021697716482008353"
"6398202298024892620480898699335508064332313529725332208819456895108"
"5155178100221003459370588291073071186553005962149936840737128710832"
"3",
"110624679233511963040518952417017040248"
"5862954819831383774196396298584395948970608956170224210628525560327"
"8638246716655439297654402921844747893079518669992827880792192992701"
"1428546551433875806377110443534293554066712653034996277099320715774"
"3542287621283671843703709141350171945045805050291770503634517804938"
"01",
"113468861199819350564868233378875198043"
"267947776488510997961231672532899549103"}
,
{NID_id_GostR3410_94_CryptoPro_D_ParamSet,
"756976611021707301782128757801610628085"
"5283803109571158829574281419208532589041660017017859858216341400371"
"4687551412794400562878935266630754392677014598582103365983119173924"
"4732511225464712252386803315902707727668715343476086350472025298282"
"7271461690125050616858238384366331089777463541013033926723743254833"
"7",
"905457649621929965904290958774625315611"
"3056083907389766971404812524422262512556054474620855996091570786713"
"5849550236741915584185990627801066465809510095784713989819413820871"
"5964648914493053407920737078890520482730623038837767710173664838239"
"8574828787891286471201460474326612697849693665518073864436497893214"
"9",
"108988435796353506912374591498972192620"
"190487557619582334771735390599299211593"}
,
{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
"1335318132727206734338595199483190012179423759678474868994823595993"
"6964252873471246159040332773182141032801252925387191478859899310331"
"0567744136196364803064721377826656898686468463277710150809401182608"
"7702016153249904683329312949209127762411378780302243557466062839716"
"59376426832674269780880061631528163475887",
"14201174159756348119636828602231808974327613839524373876287257344192"
"74593935127189736311660784676003608489466235676257952827747192122419"
"29071046134208380636394084512691828894000571524625445295769349356752"
"72895683154177544176313938445719175509684710784659566254794231229333"
"8483924514339614727760681880609734239",
"91771529896554605945588149018382750217296858393520724172743325725474"
"374979801"
},
{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
"8890864727828423151699995801875757891031463338652579140051973659"
"3048131440685857067369829407947744496306656291505503608252399443"
"7900272386749145996230867832228661977543992816745254823298629859"
"8753575466286051738837854736167685769017780335804511440773337196"
"2538423532919394477873664752824509986617878992443177",
"1028946126624994859676552074360530315217970499989304888248413244"
"8474923022758470167998871003604670704877377286176171227694098633"
"1539089568784129110109512690503345393869871295783467257264868341"
"7200196629860561193666752429682367397084815179752036423595736533"
"68957392061769855284593965042530895046088067160269433",
"9109671391802626916582318050603555673628769498182593088388796888"
"5281641595199"
},
{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
"4430618464297584182473135030809859326863990650118941756995270074"
"8609973181426950235239623239110557450826919295792878938752101867"
"7047181623251027516953100431855964837602657827828194249605561893"
"6965865325513137194483136247773653468410118796740709840825496997"
"9375560722345106704721086025979309968763193072908334",
"1246996366993477513607147265794064436203408861395055989217248455"
"7299870737698999651480662364723992859320868822848751165438350943"
"3276647222625940615560580450040947211826027729977563540237169063"
"0448079715771649447778447000597419032457722226253269698374446528"
"35352729304393746106576383349151001715930924115499549",
"6787876137336591234380295020065682527118129468050147943114675429"
"4748422492761"
},
{NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,
"1335318132727206734338595199483190012179423759678474868994823595993"
"6964252873471246159040332773182141032801252925387191478859899310331"
"0567744136196364803064721377826656898686468463277710150809401182608"
"7702016153249904683329312949209127762411378780302243557466062839716"
"59376426832674269780880061631528163475887",
"14201174159756348119636828602231808974327613839524373876287257344192"
"74593935127189736311660784676003608489466235676257952827747192122419"
"29071046134208380636394084512691828894000571524625445295769349356752"
"72895683154177544176313938445719175509684710784659566254794231229333"
"8483924514339614727760681880609734239",
"91771529896554605945588149018382750217296858393520724172743325725474"
"374979801"}
,
{NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,
"8890864727828423151699995801875757891031463338652579140051973659"
"3048131440685857067369829407947744496306656291505503608252399443"
"7900272386749145996230867832228661977543992816745254823298629859"
"8753575466286051738837854736167685769017780335804511440773337196"
"2538423532919394477873664752824509986617878992443177",
"1028946126624994859676552074360530315217970499989304888248413244"
"8474923022758470167998871003604670704877377286176171227694098633"
"1539089568784129110109512690503345393869871295783467257264868341"
"7200196629860561193666752429682367397084815179752036423595736533"
"68957392061769855284593965042530895046088067160269433",
"9109671391802626916582318050603555673628769498182593088388796888"
"5281641595199"}
,
{NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,
"4430618464297584182473135030809859326863990650118941756995270074"
"8609973181426950235239623239110557450826919295792878938752101867"
"7047181623251027516953100431855964837602657827828194249605561893"
"6965865325513137194483136247773653468410118796740709840825496997"
"9375560722345106704721086025979309968763193072908334",
"1246996366993477513607147265794064436203408861395055989217248455"
"7299870737698999651480662364723992859320868822848751165438350943"
"3276647222625940615560580450040947211826027729977563540237169063"
"0448079715771649447778447000597419032457722226253269698374446528"
"35352729304393746106576383349151001715930924115499549",
"6787876137336591234380295020065682527118129468050147943114675429"
"4748422492761"}
,
{NID_undef,NULL, NULL, NULL}
{NID_undef, NULL, NULL, NULL}
};
R3410_2001_params R3410_2001_paramset[]={
/* default_cc_sign01_param 1.2.643.2.9.1.8.1 */
{NID_id_GostR3410_2001_ParamSet_cc,
/* A */
"C0000000000000000000000000000000000000000000000000000000000003c4",
/* B */
"2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c",
/* P */
"C0000000000000000000000000000000000000000000000000000000000003C7",
/* Q */
"5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85",
/* X */
"2",
/* Y */
"a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"
},
/* 1.2.643.2.2.35.0 */
{NID_id_GostR3410_2001_TestParamSet,
"7",
"5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E",
"8000000000000000000000000000000000000000000000000000000000000431",
"8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
"2",
"08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"
},
/*1.2.643.2.2.35.1*/
{NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
"a6",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
"1",
"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
},
/*1.2.643.2.2.35.2*/
{NID_id_GostR3410_2001_CryptoPro_B_ParamSet,
"8000000000000000000000000000000000000000000000000000000000000C96",
"3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B",
"8000000000000000000000000000000000000000000000000000000000000C99",
"800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
"1",
"3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"
},
/*1.2.643.2.2.35.3*/
{NID_id_GostR3410_2001_CryptoPro_C_ParamSet,
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
"805a",
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
"0",
"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
},
/*1.2.643.2.2.36.0*/
{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
"a6",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
"1",
"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"
},
/*1.2.643.2.2.36.1*/
{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
"805a",
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
"0",
"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"
},
{ 0,NULL,NULL,NULL,NULL,NULL,NULL
}
R3410_2001_params R3410_2001_paramset[] = {
/* default_cc_sign01_param 1.2.643.2.9.1.8.1 */
{NID_id_GostR3410_2001_ParamSet_cc,
/* A */
"C0000000000000000000000000000000000000000000000000000000000003c4",
/* B */
"2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c",
/* P */
"C0000000000000000000000000000000000000000000000000000000000003C7",
/* Q */
"5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85",
/* X */
"2",
/* Y */
"a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"}
,
/* 1.2.643.2.2.35.0 */
{NID_id_GostR3410_2001_TestParamSet,
"7",
"5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E",
"8000000000000000000000000000000000000000000000000000000000000431",
"8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3",
"2",
"08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"}
,
/*
* 1.2.643.2.2.35.1
*/
{NID_id_GostR3410_2001_CryptoPro_A_ParamSet,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
"a6",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
"1",
"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"}
,
/*
* 1.2.643.2.2.35.2
*/
{NID_id_GostR3410_2001_CryptoPro_B_ParamSet,
"8000000000000000000000000000000000000000000000000000000000000C96",
"3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B",
"8000000000000000000000000000000000000000000000000000000000000C99",
"800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F",
"1",
"3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"}
,
/*
* 1.2.643.2.2.35.3
*/
{NID_id_GostR3410_2001_CryptoPro_C_ParamSet,
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
"805a",
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
"0",
"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"}
,
/*
* 1.2.643.2.2.36.0
*/
{NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
"a6",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
"1",
"8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"}
,
/*
* 1.2.643.2.2.36.1
*/
{NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598",
"805a",
"9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B",
"9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9",
"0",
"41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"}
,
{0, NULL, NULL, NULL, NULL, NULL, NULL}
};

View File

@@ -4,29 +4,29 @@
* This file is distributed under the same license as OpenSSL *
* *
* Declaration of structures used to represent GOST R 34.10 *
* parameter sets, defined in RFC 4357 *
* parameter sets, defined in RFC 4357 *
* OpenSSL 0.9.9 libraries required to compile and use *
* this code *
**********************************************************************/
**********************************************************************/
#ifndef GOST_PARAMSET_H
#define GOST_PARAMSET_H
# define GOST_PARAMSET_H
typedef struct R3410 {
int nid;
char *a;
char *p;
char *q;
int nid;
char *a;
char *p;
char *q;
} R3410_params;
extern R3410_params R3410_paramset[];
typedef struct R3410_2001 {
int nid;
char *a;
char *b;
char *p;
char *q;
char *x;
char *y;
int nid;
char *a;
char *b;
char *p;
char *q;
char *x;
char *y;
} R3410_2001_params;
extern R3410_2001_params R3410_2001_paramset[];

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -12,120 +12,147 @@
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "gost_params.h"
#include "gost_lcl.h"
#include "e_gost_err.h"
#ifdef DEBUG_SIGN
void dump_signature(const char *message,const unsigned char *buffer,size_t len)
{
size_t i;
fprintf(stderr,"signature %s Length=%d",message,len);
for (i=0; i<len; i++)
{
if (i% 16 ==0) fputc('\n',stderr);
fprintf (stderr," %02x",buffer[i]);
}
fprintf(stderr,"\nEnd of signature\n");
}
void dump_signature(const char *message, const unsigned char *buffer,
size_t len)
{
size_t i;
fprintf(stderr, "signature %s Length=%d", message, len);
for (i = 0; i < len; i++) {
if (i % 16 == 0)
fputc('\n', stderr);
fprintf(stderr, " %02x", buffer[i]);
}
fprintf(stderr, "\nEnd of signature\n");
}
void dump_dsa_sig(const char *message, DSA_SIG *sig)
{
fprintf(stderr,"%s\nR=",message);
BN_print_fp(stderr,sig->r);
fprintf(stderr,"\nS=");
BN_print_fp(stderr,sig->s);
fprintf(stderr,"\n");
}
{
fprintf(stderr, "%s\nR=", message);
BN_print_fp(stderr, sig->r);
fprintf(stderr, "\nS=");
BN_print_fp(stderr, sig->s);
fprintf(stderr, "\n");
}
#else
#define dump_signature(a,b,c)
#define dump_dsa_sig(a,b)
# define dump_signature(a,b,c)
# define dump_dsa_sig(a,b)
#endif
/*
* Computes signature and returns it as DSA_SIG structure
*/
DSA_SIG *gost_do_sign(const unsigned char *dgst,int dlen, DSA *dsa)
{
BIGNUM *k=NULL,*tmp=NULL,*tmp2=NULL;
DSA_SIG *newsig = DSA_SIG_new();
BIGNUM *md = hashsum2bn(dgst);
/* check if H(M) mod q is zero */
BN_CTX *ctx=BN_CTX_new();
BN_CTX_start(ctx);
if (!newsig)
{
GOSTerr(GOST_F_GOST_DO_SIGN,GOST_R_NO_MEMORY);
goto err;
}
tmp=BN_CTX_get(ctx);
k = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
BN_mod(tmp,md,dsa->q,ctx);
if (BN_is_zero(tmp))
{
BN_one(md);
}
do
{
do
{
/*Generate random number k less than q*/
BN_rand_range(k,dsa->q);
/* generate r = (a^x mod p) mod q */
BN_mod_exp(tmp,dsa->g, k, dsa->p,ctx);
if (!(newsig->r)) newsig->r=BN_new();
BN_mod(newsig->r,tmp,dsa->q,ctx);
}
while (BN_is_zero(newsig->r));
/* generate s = (xr + k(Hm)) mod q */
BN_mod_mul(tmp,dsa->priv_key,newsig->r,dsa->q,ctx);
BN_mod_mul(tmp2,k,md,dsa->q,ctx);
if (!newsig->s) newsig->s=BN_new();
BN_mod_add(newsig->s,tmp,tmp2,dsa->q,ctx);
}
while (BN_is_zero(newsig->s));
err:
BN_free(md);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return newsig;
}
DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
{
BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL;
DSA_SIG *newsig = NULL, *ret = NULL;
BIGNUM *md = hashsum2bn(dgst);
/* check if H(M) mod q is zero */
BN_CTX *ctx = BN_CTX_new();
if(!ctx) {
GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_CTX_start(ctx);
newsig = DSA_SIG_new();
if (!newsig) {
GOSTerr(GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY);
goto err;
}
tmp = BN_CTX_get(ctx);
k = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
if(!tmp || !k || !tmp2) {
GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_mod(tmp, md, dsa->q, ctx);
if (BN_is_zero(tmp)) {
BN_one(md);
}
do {
do {
/*
* Generate random number k less than q
*/
BN_rand_range(k, dsa->q);
/* generate r = (a^x mod p) mod q */
BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx);
if (!(newsig->r)) {
newsig->r = BN_new();
if(!newsig->r) {
GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
}
BN_mod(newsig->r, tmp, dsa->q, ctx);
}
while (BN_is_zero(newsig->r));
/* generate s = (xr + k(Hm)) mod q */
BN_mod_mul(tmp, dsa->priv_key, newsig->r, dsa->q, ctx);
BN_mod_mul(tmp2, k, md, dsa->q, ctx);
if (!newsig->s) {
newsig->s = BN_new();
if(!newsig->s) {
GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE);
goto err;
}
}
BN_mod_add(newsig->s, tmp, tmp2, dsa->q, ctx);
}
while (BN_is_zero(newsig->s));
ret = newsig;
err:
BN_free(md);
if(ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
if(!ret && newsig) {
DSA_SIG_free(newsig);
}
return ret;
}
/*
* Packs signature according to Cryptocom rules
* and frees up DSA_SIG structure
*/
/*
/*-
int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
{
*siglen = 2*order;
memset(sig,0,*siglen);
store_bignum(s->r, sig,order);
store_bignum(s->s, sig + order,order);
dump_signature("serialized",sig,*siglen);
DSA_SIG_free(s);
return 1;
}
{
*siglen = 2*order;
memset(sig,0,*siglen);
store_bignum(s->r, sig,order);
store_bignum(s->s, sig + order,order);
dump_signature("serialized",sig,*siglen);
DSA_SIG_free(s);
return 1;
}
*/
/*
* Packs signature according to Cryptopro rules
* and frees up DSA_SIG structure
*/
int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
{
*siglen = 2*order;
memset(sig,0,*siglen);
store_bignum(s->s, sig, order);
store_bignum(s->r, sig+order,order);
dump_signature("serialized",sig,*siglen);
DSA_SIG_free(s);
return 1;
}
int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen)
{
*siglen = 2 * order;
memset(sig, 0, *siglen);
store_bignum(s->s, sig, order);
store_bignum(s->r, sig + order, order);
dump_signature("serialized", sig, *siglen);
DSA_SIG_free(s);
return 1;
}
/*
* Verifies signature passed as DSA_SIG structure
@@ -133,106 +160,129 @@ int pack_sign_cp(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen)
*/
int gost_do_verify(const unsigned char *dgst, int dgst_len,
DSA_SIG *sig, DSA *dsa)
{
BIGNUM *md, *tmp=NULL;
BIGNUM *q2=NULL;
BIGNUM *u=NULL,*v=NULL,*z1=NULL,*z2=NULL;
BIGNUM *tmp2=NULL,*tmp3=NULL;
int ok;
BN_CTX *ctx = BN_CTX_new();
DSA_SIG *sig, DSA *dsa)
{
BIGNUM *md = NULL, *tmp = NULL;
BIGNUM *q2 = NULL;
BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL;
BIGNUM *tmp2 = NULL, *tmp3 = NULL;
int ok = 0;
BN_CTX *ctx = BN_CTX_new();
if(!ctx) {
GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_CTX_start(ctx);
if (BN_cmp(sig->s,dsa->q)>=1||
BN_cmp(sig->r,dsa->q)>=1)
{
GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
return 0;
}
md=hashsum2bn(dgst);
tmp=BN_CTX_get(ctx);
v=BN_CTX_get(ctx);
q2=BN_CTX_get(ctx);
z1=BN_CTX_get(ctx);
z2=BN_CTX_get(ctx);
tmp2=BN_CTX_get(ctx);
tmp3=BN_CTX_get(ctx);
u = BN_CTX_get(ctx);
BN_mod(tmp,md,dsa->q,ctx);
if (BN_is_zero(tmp))
{
BN_one(md);
}
BN_copy(q2,dsa->q);
BN_sub_word(q2,2);
BN_mod_exp(v,md,q2,dsa->q,ctx);
BN_mod_mul(z1,sig->s,v,dsa->q,ctx);
BN_sub(tmp,dsa->q,sig->r);
BN_mod_mul(z2,tmp,v,dsa->p,ctx);
BN_mod_exp(tmp,dsa->g,z1,dsa->p,ctx);
BN_mod_exp(tmp2,dsa->pub_key,z2,dsa->p,ctx);
BN_mod_mul(tmp3,tmp,tmp2,dsa->p,ctx);
BN_mod(u,tmp3,dsa->q,ctx);
ok= BN_cmp(u,sig->r);
BN_free(md);
BN_CTX_end(ctx);
BN_CTX_free(ctx);
if (ok!=0)
{
GOSTerr(GOST_F_GOST_DO_VERIFY,GOST_R_SIGNATURE_MISMATCH);
}
return (ok==0);
}
BN_CTX_start(ctx);
if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) {
GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q);
goto err;
}
md = hashsum2bn(dgst);
tmp = BN_CTX_get(ctx);
v = BN_CTX_get(ctx);
q2 = BN_CTX_get(ctx);
z1 = BN_CTX_get(ctx);
z2 = BN_CTX_get(ctx);
tmp2 = BN_CTX_get(ctx);
tmp3 = BN_CTX_get(ctx);
u = BN_CTX_get(ctx);
if(!tmp || !v || !q2 || !z1 || !z2 || !tmp2 || !tmp3 || !u) {
GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE);
goto err;
}
BN_mod(tmp, md, dsa->q, ctx);
if (BN_is_zero(tmp)) {
BN_one(md);
}
BN_copy(q2, dsa->q);
BN_sub_word(q2, 2);
BN_mod_exp(v, md, q2, dsa->q, ctx);
BN_mod_mul(z1, sig->s, v, dsa->q, ctx);
BN_sub(tmp, dsa->q, sig->r);
BN_mod_mul(z2, tmp, v, dsa->p, ctx);
BN_mod_exp(tmp, dsa->g, z1, dsa->p, ctx);
BN_mod_exp(tmp2, dsa->pub_key, z2, dsa->p, ctx);
BN_mod_mul(tmp3, tmp, tmp2, dsa->p, ctx);
BN_mod(u, tmp3, dsa->q, ctx);
ok = (BN_cmp(u, sig->r) == 0);
if (!ok) {
GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH);
}
err:
if(md) BN_free(md);
if(ctx) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
return ok;
}
/*
* Computes public keys for GOST R 34.10-94 algorithm
*
*/
int gost94_compute_public(DSA *dsa)
{
/* Now fill algorithm parameters with correct values */
BN_CTX *ctx = BN_CTX_new();
if (!dsa->g)
{
GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC,GOST_R_KEY_IS_NOT_INITALIZED);
return 0;
}
/* Compute public key y = a^x mod p */
dsa->pub_key=BN_new();
BN_mod_exp(dsa->pub_key, dsa->g,dsa->priv_key,dsa->p,ctx);
BN_CTX_free(ctx);
return 1;
}
{
/* Now fill algorithm parameters with correct values */
BN_CTX *ctx;
if (!dsa->g) {
GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED);
return 0;
}
ctx = BN_CTX_new();
if(!ctx) {
GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
return 0;
}
dsa->pub_key = BN_new();
if(!dsa->pub_key) {
GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE);
BN_CTX_free(ctx);
return 0;
}
/* Compute public key y = a^x mod p */
BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx);
BN_CTX_free(ctx);
return 1;
}
/*
* Fill GOST 94 params, searching them in R3410_paramset array
* by nid of paramset
*
*/
int fill_GOST94_params(DSA *dsa,int nid)
{
R3410_params *params=R3410_paramset;
while (params->nid!=NID_undef && params->nid !=nid) params++;
if (params->nid == NID_undef)
{
GOSTerr(GOST_F_FILL_GOST94_PARAMS,GOST_R_UNSUPPORTED_PARAMETER_SET);
return 0;
}
int fill_GOST94_params(DSA *dsa, int nid)
{
R3410_params *params = R3410_paramset;
while (params->nid != NID_undef && params->nid != nid)
params++;
if (params->nid == NID_undef) {
GOSTerr(GOST_F_FILL_GOST94_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET);
return 0;
}
#define dump_signature(a,b,c)
if (dsa->p) { BN_free(dsa->p); }
dsa->p=NULL;
BN_dec2bn(&(dsa->p),params->p);
if (dsa->q) { BN_free(dsa->q); }
dsa->q=NULL;
BN_dec2bn(&(dsa->q),params->q);
if (dsa->g) { BN_free(dsa->g); }
dsa->g=NULL;
BN_dec2bn(&(dsa->g),params->a);
return 1;
}
if (dsa->p) {
BN_free(dsa->p);
}
dsa->p = NULL;
BN_dec2bn(&(dsa->p), params->p);
if (dsa->q) {
BN_free(dsa->q);
}
dsa->q = NULL;
BN_dec2bn(&(dsa->q), params->q);
if (dsa->g) {
BN_free(dsa->g);
}
dsa->g = NULL;
BN_dec2bn(&(dsa->g), params->a);
return 1;
}
/*
* Generate GOST R 34.10-94 keypair
@@ -240,82 +290,84 @@ int fill_GOST94_params(DSA *dsa,int nid)
*
*/
int gost_sign_keygen(DSA *dsa)
{
dsa->priv_key = BN_new();
BN_rand_range(dsa->priv_key,dsa->q);
return gost94_compute_public( dsa);
}
{
dsa->priv_key = BN_new();
if(!dsa->priv_key) {
GOSTerr(GOST_F_GOST_SIGN_KEYGEN, ERR_R_MALLOC_FAILURE);
return 0;
}
BN_rand_range(dsa->priv_key, dsa->q);
return gost94_compute_public(dsa);
}
/* Unpack signature according to cryptocom rules */
/*
/*-
DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen)
{
DSA_SIG *s;
s = DSA_SIG_new();
if (s == NULL)
{
GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
return(NULL);
}
s->r = getbnfrombuf(sig, siglen/2);
s->s = getbnfrombuf(sig + siglen/2, siglen/2);
return s;
}
{
DSA_SIG *s;
s = DSA_SIG_new();
if (s == NULL)
{
GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY);
return(NULL);
}
s->r = getbnfrombuf(sig, siglen/2);
s->s = getbnfrombuf(sig + siglen/2, siglen/2);
return s;
}
*/
/* Unpack signature according to cryptopro rules */
DSA_SIG *unpack_cp_signature(const unsigned char *sig,size_t siglen)
{
DSA_SIG *s;
DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen)
{
DSA_SIG *s;
s = DSA_SIG_new();
if (s == NULL)
{
GOSTerr(GOST_F_UNPACK_CP_SIGNATURE,GOST_R_NO_MEMORY);
return NULL;
}
s->s = getbnfrombuf(sig , siglen/2);
s->r = getbnfrombuf(sig + siglen/2, siglen/2);
return s;
}
s = DSA_SIG_new();
if (s == NULL) {
GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, GOST_R_NO_MEMORY);
return NULL;
}
s->s = getbnfrombuf(sig, siglen / 2);
s->r = getbnfrombuf(sig + siglen / 2, siglen / 2);
return s;
}
/* Convert little-endian byte array into bignum */
BIGNUM *hashsum2bn(const unsigned char *dgst)
{
unsigned char buf[32];
int i;
for (i=0;i<32;i++)
{
buf[31-i]=dgst[i];
}
return getbnfrombuf(buf,32);
}
{
unsigned char buf[32];
int i;
for (i = 0; i < 32; i++) {
buf[31 - i] = dgst[i];
}
return getbnfrombuf(buf, 32);
}
/* Convert byte buffer to bignum, skipping leading zeros*/
BIGNUM *getbnfrombuf(const unsigned char *buf,size_t len)
{
while (*buf==0&&len>0)
{
buf++; len--;
}
if (len)
{
return BN_bin2bn(buf,len,NULL);
}
else
{
BIGNUM *b=BN_new();
BN_zero(b);
return b;
}
}
BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len)
{
while (*buf == 0 && len > 0) {
buf++;
len--;
}
if (len) {
return BN_bin2bn(buf, len, NULL);
} else {
BIGNUM *b = BN_new();
BN_zero(b);
return b;
}
}
/* Pack bignum into byte buffer of given size, filling all leading bytes
* by zeros */
int store_bignum(BIGNUM *bn, unsigned char *buf,int len)
{
int bytes = BN_num_bytes(bn);
if (bytes>len) return 0;
memset(buf,0,len);
BN_bn2bin(bn,buf+len-bytes);
return 1;
}
/*
* Pack bignum into byte buffer of given size, filling all leading bytes by
* zeros
*/
int store_bignum(BIGNUM *bn, unsigned char *buf, int len)
{
int bytes = BN_num_bytes(bn);
if (bytes > len)
return 0;
memset(buf, 0, len);
BN_bn2bin(bn, buf + len - bytes);
return 1;
}

Binary file not shown.

View File

@@ -11,8 +11,8 @@
#include "gost89.h"
#include "gosthash.h"
/* Use OPENSSL_malloc for memory allocation if compiled with
/*
* Use OPENSSL_malloc for memory allocation if compiled with
* -DOPENSSL_BUILD, and libc malloc otherwise
*/
#ifndef MYALLOC
@@ -25,231 +25,244 @@
# define MYFREE(ptr) free(ptr)
# endif
#endif
/* Following functions are various bit meshing routines used in
* GOST R 34.11-94 algorithms */
static void swap_bytes (byte *w, byte *k)
{
int i,j;
for (i=0;i<4;i++)
for (j=0;j<8;j++)
k[i+4*j]=w[8*i+j];
/*
* Following functions are various bit meshing routines used in GOST R
* 34.11-94 algorithms
*/
static void swap_bytes(byte * w, byte * k)
{
int i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 8; j++)
k[i + 4 * j] = w[8 * i + j];
}
}
/* was A_A */
static void circle_xor8 (const byte *w, byte *k)
{
byte buf[8];
int i;
memcpy(buf,w,8);
memcpy(k,w+8,24);
for(i=0;i<8;i++)
k[i+24]=buf[i]^k[i];
}
static void circle_xor8(const byte * w, byte * k)
{
byte buf[8];
int i;
memcpy(buf, w, 8);
memmove(k, w + 8, 24);
for (i = 0; i < 8; i++)
k[i + 24] = buf[i] ^ k[i];
}
/* was R_R */
static void transform_3 (byte *data)
{
unsigned short int acc;
acc=(data[0]^data[2]^data[4]^data[6]^data[24]^data[30])|
((data[1]^data[3]^data[5]^data[7]^data[25]^data[31])<<8);
memmove(data,data+2,30);
data[30]=acc&0xff;
data[31]=acc>>8;
}
static void transform_3(byte * data)
{
unsigned short int acc;
acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) |
((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8);
memmove(data, data + 2, 30);
data[30] = acc & 0xff;
data[31] = acc >> 8;
}
/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/
static int add_blocks(int n,byte *left, const byte *right)
{
int i;
int carry=0;
int sum;
for (i=0;i<n;i++)
{
sum=(int)left[i]+(int)right[i]+carry;
left[i]=sum & 0xff;
carry=sum>>8;
}
return carry;
}
static int add_blocks(int n, byte * left, const byte * right)
{
int i;
int carry = 0;
int sum;
for (i = 0; i < n; i++) {
sum = (int)left[i] + (int)right[i] + carry;
left[i] = sum & 0xff;
carry = sum >> 8;
}
return carry;
}
/* Xor two sequences of bytes */
static void xor_blocks (byte *result,const byte *a,const byte *b,size_t len)
{
size_t i;
for (i=0;i<len;i++) result[i]=a[i]^b[i];
}
static void xor_blocks(byte * result, const byte * a, const byte * b,
size_t len)
{
size_t i;
for (i = 0; i < len; i++)
result[i] = a[i] ^ b[i];
}
/*
* Calculate H(i+1) = Hash(Hi,Mi)
* Where H and M are 32 bytes long
/*
* Calculate H(i+1) = Hash(Hi,Mi)
* Where H and M are 32 bytes long
*/
static int hash_step(gost_ctx *c,byte *H,const byte *M)
{
byte U[32],W[32],V[32],S[32],Key[32];
int i;
/* Compute first key */
xor_blocks(W,H,M,32);
swap_bytes(W,Key);
/* Encrypt first 8 bytes of H with first key*/
gost_enc_with_key(c,Key,H,S);
/* Compute second key*/
circle_xor8(H,U);
circle_xor8(M,V);
circle_xor8(V,V);
xor_blocks(W,U,V,32);
swap_bytes(W,Key);
/* encrypt second 8 bytes of H with second key*/
gost_enc_with_key(c,Key,H+8,S+8);
/* compute third key */
circle_xor8(U,U);
U[31]=~U[31]; U[29]=~U[29]; U[28]=~U[28]; U[24]=~U[24];
U[23]=~U[23]; U[20]=~U[20]; U[18]=~U[18]; U[17]=~U[17];
U[14]=~U[14]; U[12]=~U[12]; U[10]=~U[10]; U[ 8]=~U[ 8];
U[ 7]=~U[ 7]; U[ 5]=~U[ 5]; U[ 3]=~U[ 3]; U[ 1]=~U[ 1];
circle_xor8(V,V);
circle_xor8(V,V);
xor_blocks(W,U,V,32);
swap_bytes(W,Key);
/* encrypt third 8 bytes of H with third key*/
gost_enc_with_key(c,Key,H+16,S+16);
/* Compute fourth key */
circle_xor8(U,U);
circle_xor8(V,V);
circle_xor8(V,V);
xor_blocks(W,U,V,32);
swap_bytes(W,Key);
/* Encrypt last 8 bytes with fourth key */
gost_enc_with_key(c,Key,H+24,S+24);
for (i=0;i<12;i++)
transform_3(S);
xor_blocks(S,S,M,32);
transform_3(S);
xor_blocks(S,S,H,32);
for (i=0;i<61;i++)
transform_3(S);
memcpy(H,S,32);
return 1;
}
static int hash_step(gost_ctx * c, byte * H, const byte * M)
{
byte U[32], W[32], V[32], S[32], Key[32];
int i;
/* Compute first key */
xor_blocks(W, H, M, 32);
swap_bytes(W, Key);
/* Encrypt first 8 bytes of H with first key */
gost_enc_with_key(c, Key, H, S);
/* Compute second key */
circle_xor8(H, U);
circle_xor8(M, V);
circle_xor8(V, V);
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* encrypt second 8 bytes of H with second key */
gost_enc_with_key(c, Key, H + 8, S + 8);
/* compute third key */
circle_xor8(U, U);
U[31] = ~U[31];
U[29] = ~U[29];
U[28] = ~U[28];
U[24] = ~U[24];
U[23] = ~U[23];
U[20] = ~U[20];
U[18] = ~U[18];
U[17] = ~U[17];
U[14] = ~U[14];
U[12] = ~U[12];
U[10] = ~U[10];
U[8] = ~U[8];
U[7] = ~U[7];
U[5] = ~U[5];
U[3] = ~U[3];
U[1] = ~U[1];
circle_xor8(V, V);
circle_xor8(V, V);
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* encrypt third 8 bytes of H with third key */
gost_enc_with_key(c, Key, H + 16, S + 16);
/* Compute fourth key */
circle_xor8(U, U);
circle_xor8(V, V);
circle_xor8(V, V);
xor_blocks(W, U, V, 32);
swap_bytes(W, Key);
/* Encrypt last 8 bytes with fourth key */
gost_enc_with_key(c, Key, H + 24, S + 24);
for (i = 0; i < 12; i++)
transform_3(S);
xor_blocks(S, S, M, 32);
transform_3(S);
xor_blocks(S, S, H, 32);
for (i = 0; i < 61; i++)
transform_3(S);
memcpy(H, S, 32);
return 1;
}
/* Initialize gost_hash ctx - cleans up temporary structures and
* set up substitution blocks
/*
* Initialize gost_hash ctx - cleans up temporary structures and set up
* substitution blocks
*/
int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block)
{
memset(ctx,0,sizeof(gost_hash_ctx));
ctx->cipher_ctx = (gost_ctx *)MYALLOC(sizeof(gost_ctx));
if (!ctx->cipher_ctx)
{
return 0;
}
gost_init(ctx->cipher_ctx,subst_block);
return 1;
}
int init_gost_hash_ctx(gost_hash_ctx * ctx,
const gost_subst_block * subst_block)
{
memset(ctx, 0, sizeof(gost_hash_ctx));
ctx->cipher_ctx = (gost_ctx *) MYALLOC(sizeof(gost_ctx));
if (!ctx->cipher_ctx) {
return 0;
}
gost_init(ctx->cipher_ctx, subst_block);
return 1;
}
/*
* Free cipher CTX if it is dynamically allocated. Do not use
* if cipher ctx is statically allocated as in OpenSSL implementation of
* GOST hash algroritm
*
*/
void done_gost_hash_ctx(gost_hash_ctx *ctx)
{
/* No need to use gost_destroy, because cipher keys are not really
* secret when hashing */
MYFREE(ctx->cipher_ctx);
}
*/
void done_gost_hash_ctx(gost_hash_ctx * ctx)
{
/*
* No need to use gost_destroy, because cipher keys are not really secret
* when hashing
*/
MYFREE(ctx->cipher_ctx);
}
/*
* reset state of hash context to begin hashing new message
*/
int start_hash(gost_hash_ctx *ctx)
{
if (!ctx->cipher_ctx) return 0;
memset(&(ctx->H),0,32);
memset(&(ctx->S),0,32);
ctx->len = 0L;
ctx->left=0;
return 1;
}
int start_hash(gost_hash_ctx * ctx)
{
if (!ctx->cipher_ctx)
return 0;
memset(&(ctx->H), 0, 32);
memset(&(ctx->S), 0, 32);
ctx->len = 0L;
ctx->left = 0;
return 1;
}
/*
* Hash block of arbitrary length
*
*
*/
int hash_block(gost_hash_ctx *ctx,const byte *block, size_t length)
{
const byte *curptr=block;
const byte *barrier=block+(length-32);/* Last byte we can safely hash*/
if (ctx->left)
{
/*There are some bytes from previous step*/
unsigned int add_bytes = 32-ctx->left;
if (add_bytes>length)
{
add_bytes = length;
}
memcpy(&(ctx->remainder[ctx->left]),block,add_bytes);
ctx->left+=add_bytes;
if (ctx->left<32)
{
return 1;
}
curptr=block+add_bytes;
hash_step(ctx->cipher_ctx,ctx->H,ctx->remainder);
add_blocks(32,ctx->S,ctx->remainder);
ctx->len+=32;
ctx->left=0;
}
while (curptr<=barrier)
{
hash_step(ctx->cipher_ctx,ctx->H,curptr);
add_blocks(32,ctx->S,curptr);
ctx->len+=32;
curptr+=32;
}
if (curptr!=block+length)
{
ctx->left=block+length-curptr;
memcpy(ctx->remainder,curptr,ctx->left);
}
return 1;
}
int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length)
{
if (ctx->left) {
/*
* There are some bytes from previous step
*/
unsigned int add_bytes = 32 - ctx->left;
if (add_bytes > length) {
add_bytes = length;
}
memcpy(&(ctx->remainder[ctx->left]), block, add_bytes);
ctx->left += add_bytes;
if (ctx->left < 32) {
return 1;
}
block += add_bytes;
length -= add_bytes;
hash_step(ctx->cipher_ctx, ctx->H, ctx->remainder);
add_blocks(32, ctx->S, ctx->remainder);
ctx->len += 32;
ctx->left = 0;
}
while (length >= 32) {
hash_step(ctx->cipher_ctx, ctx->H, block);
add_blocks(32, ctx->S, block);
ctx->len += 32;
block += 32;
length -= 32;
}
if (length) {
memcpy(ctx->remainder, block, ctx->left = length);
}
return 1;
}
/*
* Compute hash value from current state of ctx
* state of hash ctx becomes invalid and cannot be used for further
* hashing.
*/
int finish_hash(gost_hash_ctx *ctx,byte *hashval)
{
byte buf[32];
byte H[32];
byte S[32];
ghosthash_len fin_len=ctx->len;
byte *bptr;
memcpy(H,ctx->H,32);
memcpy(S,ctx->S,32);
if (ctx->left)
{
memset(buf,0,32);
memcpy(buf,ctx->remainder,ctx->left);
hash_step(ctx->cipher_ctx,H,buf);
add_blocks(32,S,buf);
fin_len+=ctx->left;
}
memset(buf,0,32);
bptr=buf;
fin_len<<=3; /* Hash length in BITS!!*/
while(fin_len>0)
{
*(bptr++)=(byte)(fin_len&0xFF);
fin_len>>=8;
};
hash_step(ctx->cipher_ctx,H,buf);
hash_step(ctx->cipher_ctx,H,S);
memcpy(hashval,H,32);
return 1;
}
*/
int finish_hash(gost_hash_ctx * ctx, byte * hashval)
{
byte buf[32];
byte H[32];
byte S[32];
ghosthash_len fin_len = ctx->len;
byte *bptr;
memcpy(H, ctx->H, 32);
memcpy(S, ctx->S, 32);
if (ctx->left) {
memset(buf, 0, 32);
memcpy(buf, ctx->remainder, ctx->left);
hash_step(ctx->cipher_ctx, H, buf);
add_blocks(32, S, buf);
fin_len += ctx->left;
}
memset(buf, 0, 32);
bptr = buf;
fin_len <<= 3; /* Hash length in BITS!! */
while (fin_len > 0) {
*(bptr++) = (byte) (fin_len & 0xFF);
fin_len >>= 8;
};
hash_step(ctx->cipher_ctx, H, buf);
hash_step(ctx->cipher_ctx, H, S);
memcpy(hashval, H, 32);
return 1;
}

View File

@@ -7,42 +7,46 @@
* uses and gost89.h Doesn't need OpenSSL *
**********************************************************************/
#ifndef GOSTHASH_H
#define GOSTHASH_H
#include "gost89.h"
#include <stdlib.h>
# define GOSTHASH_H
# include "gost89.h"
# include <stdlib.h>
#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
typedef __int64 ghosthash_len;
#elif defined(__arch64__)
# elif defined(__arch64__)
typedef long ghosthash_len;
#else
# else
typedef long long ghosthash_len;
#endif
# endif
typedef struct gost_hash_ctx {
ghosthash_len len;
gost_ctx *cipher_ctx;
int left;
byte H[32];
byte S[32];
byte remainder[32];
} gost_hash_ctx;
ghosthash_len len;
gost_ctx *cipher_ctx;
int left;
byte H[32];
byte S[32];
byte remainder[32];
} gost_hash_ctx;
/* Initalizes gost hash ctx, including creation of gost cipher ctx */
int init_gost_hash_ctx(gost_hash_ctx *ctx, const gost_subst_block *subst_block);
void done_gost_hash_ctx(gost_hash_ctx *ctx);
int init_gost_hash_ctx(gost_hash_ctx * ctx,
const gost_subst_block * subst_block);
void done_gost_hash_ctx(gost_hash_ctx * ctx);
/* Cleans up all fields, except cipher ctx preparing ctx for computing
* of new hash value */
int start_hash(gost_hash_ctx *ctx);
/*
* Cleans up all fields, except cipher ctx preparing ctx for computing of new
* hash value
*/
int start_hash(gost_hash_ctx * ctx);
/* Hashes block of data */
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);
/* Finalizes computation of hash and fills buffer (which should be at
* least 32 bytes long) with value of computed hash. */
int finish_hash(gost_hash_ctx *ctx, byte *hashval);
/*
* Finalizes computation of hash and fills buffer (which should be at least
* 32 bytes long) with value of computed hash.
*/
int finish_hash(gost_hash_ctx * ctx, byte * hashval);
#endif
#endif

Binary file not shown.

View File

@@ -15,196 +15,173 @@
#include <string.h>
#include "gosthash.h"
#define BUF_SIZE 262144
int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode);
int hash_stream(gost_hash_ctx *ctx,int fd, char *sum);
int get_line(FILE *f,char *hash,char *filename);
int hash_file(gost_hash_ctx * ctx, char *filename, char *sum, int mode);
int hash_stream(gost_hash_ctx * ctx, int fd, char *sum);
int get_line(FILE *f, char *hash, char *filename);
void help()
{
fprintf(stderr,"gostsum [-bvt] [-c [file]]| [files]\n"
"\t-c check message digests (default is generate)\n"
"\t-v verbose, print file names when checking\n"
"\t-b read files in binary mode\n"
"\t-t use test GOST paramset (default is CryptoPro paramset)\n"
"The input for -c should be the list of message digests and file names\n"
"that is printed on stdout by this program when it generates digests.\n");
exit(3);
}
{
fprintf(stderr, "gostsum [-bvt] [-c [file]]| [files]\n"
"\t-c check message digests (default is generate)\n"
"\t-v verbose, print file names when checking\n"
"\t-b read files in binary mode\n"
"\t-t use test GOST paramset (default is CryptoPro paramset)\n"
"The input for -c should be the list of message digests and file names\n"
"that is printed on stdout by this program when it generates digests.\n");
exit(3);
}
#ifndef O_BINARY
#define O_BINARY 0
# define O_BINARY 0
#endif
int main(int argc,char **argv)
{
int c,i;
int verbose=0;
int errors=0;
int open_mode = O_RDONLY;
gost_subst_block *b= &GostR3411_94_CryptoProParamSet;
FILE *check_file = NULL;
gost_hash_ctx ctx;
while( (c=getopt(argc,argv,"bc::tv"))!=-1)
{
switch (c)
{
case 'v': verbose=1; break;
case 't': b= &GostR3411_94_TestParamSet; break;
case 'b': open_mode |= O_BINARY; break;
case 'c':
if (optarg)
{
check_file = fopen(optarg,"r");
if (!check_file)
{
perror(optarg);
exit(2);
}
}
else
{
check_file= stdin;
}
break;
default:
fprintf(stderr,"invalid option %c",optopt);
help();
}
}
init_gost_hash_ctx(&ctx,b);
if (check_file)
{
char inhash[65],calcsum[65],filename[PATH_MAX];
int failcount=0,count=0;;
if (check_file==stdin && optind<argc)
{
check_file=fopen(argv[optind],"r");
if (!check_file)
{
perror(argv[optind]);
exit(2);
}
}
while (get_line(check_file,inhash,filename))
{
if (!hash_file(&ctx,filename,calcsum,open_mode))
{
exit (2);
}
count++;
if (!strncmp(calcsum,inhash,65))
{
if (verbose)
{
fprintf(stderr,"%s\tOK\n",filename);
}
}
else
{
if (verbose)
{
fprintf(stderr,"%s\tFAILED\n",filename);
}
else
{
fprintf(stderr,"%s: GOST hash sum check failed for '%s'\n",
argv[0],filename);
}
failcount++;
}
}
if (verbose && failcount)
{
fprintf(stderr,"%s: %d of %d file(f) failed GOST hash sum check\n",
argv[0],failcount,count);
}
exit (failcount?1:0);
}
if (optind==argc)
{
char sum[65];
if (!hash_stream(&ctx,fileno(stdin),sum))
{
perror("stdin");
exit(1);
}
printf("%s -\n",sum);
exit(0);
}
for (i=optind;i<argc;i++)
{
char sum[65];
if (!hash_file(&ctx,argv[i],sum,open_mode))
{
errors++;
}
else
{
printf("%s %s\n",sum,argv[i]);
}
}
exit(errors?1:0);
}
int main(int argc, char **argv)
{
int c, i;
int verbose = 0;
int errors = 0;
int open_mode = O_RDONLY;
gost_subst_block *b = &GostR3411_94_CryptoProParamSet;
FILE *check_file = NULL;
gost_hash_ctx ctx;
int hash_file(gost_hash_ctx *ctx,char *filename,char *sum,int mode)
{
int fd;
if ((fd=open(filename,mode))<0)
{
perror(filename);
return 0;
}
if (!hash_stream(ctx,fd,sum))
{
perror(filename);
return 0;
}
close(fd);
return 1;
}
while ((c = getopt(argc, argv, "bc::tv")) != -1) {
switch (c) {
case 'v':
verbose = 1;
break;
case 't':
b = &GostR3411_94_TestParamSet;
break;
case 'b':
open_mode |= O_BINARY;
break;
case 'c':
if (optarg) {
check_file = fopen(optarg, "r");
if (!check_file) {
perror(optarg);
exit(2);
}
} else {
check_file = stdin;
}
break;
default:
fprintf(stderr, "invalid option %c", optopt);
help();
}
}
init_gost_hash_ctx(&ctx, b);
if (check_file) {
char inhash[65], calcsum[65], filename[PATH_MAX];
int failcount = 0, count = 0;;
if (check_file == stdin && optind < argc) {
check_file = fopen(argv[optind], "r");
if (!check_file) {
perror(argv[optind]);
exit(2);
}
}
while (get_line(check_file, inhash, filename)) {
if (!hash_file(&ctx, filename, calcsum, open_mode)) {
exit(2);
}
count++;
if (!strncmp(calcsum, inhash, 65)) {
if (verbose) {
fprintf(stderr, "%s\tOK\n", filename);
}
} else {
if (verbose) {
fprintf(stderr, "%s\tFAILED\n", filename);
} else {
fprintf(stderr,
"%s: GOST hash sum check failed for '%s'\n",
argv[0], filename);
}
failcount++;
}
}
if (verbose && failcount) {
fprintf(stderr,
"%s: %d of %d file(f) failed GOST hash sum check\n",
argv[0], failcount, count);
}
exit(failcount ? 1 : 0);
}
if (optind == argc) {
char sum[65];
if (!hash_stream(&ctx, fileno(stdin), sum)) {
perror("stdin");
exit(1);
}
printf("%s -\n", sum);
exit(0);
}
for (i = optind; i < argc; i++) {
char sum[65];
if (!hash_file(&ctx, argv[i], sum, open_mode)) {
errors++;
} else {
printf("%s %s\n", sum, argv[i]);
}
}
exit(errors ? 1 : 0);
}
int hash_stream(gost_hash_ctx *ctx,int fd, char *sum)
{
unsigned char buffer[BUF_SIZE];
ssize_t bytes;
int i;
start_hash(ctx);
while ((bytes=read(fd,buffer,BUF_SIZE))>0)
{
hash_block(ctx,buffer,bytes);
}
if (bytes<0)
{
return 0;
}
finish_hash(ctx,buffer);
for (i=0;i<32;i++)
{
sprintf(sum+2*i,"%02x",buffer[31-i]);
}
return 1;
}
int get_line(FILE *f,char *hash,char *filename)
{
int i;
if (fread(hash,1,64,f)<64) return 0;
hash[64]=0;
for (i=0;i<64;i++)
{
if (hash[i]<'0' || (hash[i]>'9' && hash[i]<'A') || (hash[i]>'F'
&& hash[i]<'a')||hash[i]>'f')
{
fprintf(stderr,"Not a hash value '%s'\n",hash);
return 0;
}
}
if (fgetc(f)!=' ')
{
fprintf(stderr,"Malformed input line\n");
return 0;
}
i=strlen(fgets(filename,PATH_MAX,f));
while (filename[--i]=='\n'||filename[i]=='\r') filename[i]=0;
return 1;
}
int hash_file(gost_hash_ctx * ctx, char *filename, char *sum, int mode)
{
int fd;
if ((fd = open(filename, mode)) < 0) {
perror(filename);
return 0;
}
if (!hash_stream(ctx, fd, sum)) {
perror(filename);
return 0;
}
close(fd);
return 1;
}
int hash_stream(gost_hash_ctx * ctx, int fd, char *sum)
{
unsigned char buffer[BUF_SIZE];
ssize_t bytes;
int i;
start_hash(ctx);
while ((bytes = read(fd, buffer, BUF_SIZE)) > 0) {
hash_block(ctx, buffer, bytes);
}
if (bytes < 0) {
return 0;
}
finish_hash(ctx, buffer);
for (i = 0; i < 32; i++) {
sprintf(sum + 2 * i, "%02x", buffer[31 - i]);
}
return 1;
}
int get_line(FILE *f, char *hash, char *filename)
{
int i;
if (fread(hash, 1, 64, f) < 64)
return 0;
hash[64] = 0;
for (i = 0; i < 64; i++) {
if (hash[i] < '0' || (hash[i] > '9' && hash[i] < 'A')
|| (hash[i] > 'F' && hash[i] < 'a') || hash[i] > 'f') {
fprintf(stderr, "Not a hash value '%s'\n", hash);
return 0;
}
}
if (fgetc(f) != ' ') {
fprintf(stderr, "Malformed input line\n");
return 0;
}
i = strlen(fgets(filename, PATH_MAX, f));
while (filename[--i] == '\n' || filename[i] == '\r')
filename[i] = 0;
return 1;
}

View File