From a4346646f12f83f8058abd9d013824fb90abfe73 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 17 May 2007 17:44:09 +0000 Subject: [PATCH] Initial GOST MAC support. Not fully working yet... --- engines/Makefile | 1 + engines/ccgost/e_gost_err.c | 167 +++++++++++++++++---------------- engines/ccgost/e_gost_err.h | 7 ++ engines/ccgost/gost_ameth.c | 80 ++++++++++++++++ engines/ccgost/gost_crypt.c | 4 +- engines/ccgost/gost_eng.c | 19 +++- engines/ccgost/gost_lcl.h | 13 +++ engines/ccgost/gost_md.c | 3 + engines/ccgost/gost_pmeth.c | 178 ++++++++++++++++++++++++++++++++++++ 9 files changed, 386 insertions(+), 86 deletions(-) diff --git a/engines/Makefile b/engines/Makefile index 2454f3ba5e..7796cb5351 100644 --- a/engines/Makefile +++ b/engines/Makefile @@ -131,6 +131,7 @@ errors: $(PERL) ../util/mkerr.pl -conf e_$$l.ec \ -nostatic -staticloader -write e_$$l.c; \ done + (cd ccgost; $(MAKE) PERL=$(PERL) errors) tests: diff --git a/engines/ccgost/e_gost_err.c b/engines/ccgost/e_gost_err.c index 3dad4f4fc3..62c8bacbe4 100644 --- a/engines/ccgost/e_gost_err.c +++ b/engines/ccgost/e_gost_err.c @@ -1,6 +1,6 @@ /* e_gost_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2007 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 @@ -70,95 +70,102 @@ static ERR_STRING_DATA GOST_str_functs[]= { - {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, - {ERR_FUNC(GOST_F_DECRYPT_CRYPTOCOM_KEY), "decrypt_cryptocom_key"}, - {ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, - {ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "get_encryption_params"}, - {ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, - {ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, - {ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), "gost89_get_asn1_parameters"}, - {ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "gost89_set_asn1_parameters"}, - {ERR_FUNC(GOST_F_GOST94_COPY_PARAMETERS), "GOST94_COPY_PARAMETERS"}, - {ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "gost_cipher_ctl"}, - {ERR_FUNC(GOST_F_GOST_COMPUTE_PUBLIC), "GOST_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, - {ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, - {ERR_FUNC(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001), "MAKE_RFC4490_KEYTRANSPORT_2001"}, - {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, - {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, - {ERR_FUNC(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT"}, - {ERR_FUNC(GOST_F_PKCS7_GOST94_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94_KEY_TRANSPORT_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CC_DECRYPT), "pkey_GOST01cc_decrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CC_ENCRYPT), "pkey_GOST01cc_encrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "pkey_GOST01cp_encrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST01_KEYGEN), "PKEY_GOST01_KEYGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CC_DECRYPT), "pkey_GOST94cc_decrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CC_ENCRYPT), "pkey_GOST94cc_encrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "pkey_GOST94cp_decrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "pkey_GOST94cp_encrypt"}, - {ERR_FUNC(GOST_F_PKEY_GOST94_KEYGEN), "PKEY_GOST94_KEYGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, - {ERR_FUNC(GOST_F_PRIV_DECODE_GOST_94), "PRIV_DECODE_GOST_94"}, - {ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, - {ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, - {ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, - {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, - {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, - {0,NULL} +{ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, +{ERR_FUNC(GOST_F_DECRYPT_CRYPTOCOM_KEY), "decrypt_cryptocom_key"}, +{ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, +{ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, +{ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, +{ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "get_encryption_params"}, +{ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, +{ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, +{ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, +{ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), "gost89_get_asn1_parameters"}, +{ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), "gost89_set_asn1_parameters"}, +{ERR_FUNC(GOST_F_GOST94_COPY_PARAMETERS), "GOST94_COPY_PARAMETERS"}, +{ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "gost_cipher_ctl"}, +{ERR_FUNC(GOST_F_GOST_COMPUTE_PUBLIC), "GOST_COMPUTE_PUBLIC"}, +{ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, +{ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, +{ERR_FUNC(GOST_F_MAKE_RFC4490_KEYTRANSPORT_2001), "MAKE_RFC4490_KEYTRANSPORT_2001"}, +{ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, +{ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, +{ERR_FUNC(GOST_F_PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94CP_KEY_TRANSPORT_DECRYPT"}, +{ERR_FUNC(GOST_F_PKCS7_GOST94_KEY_TRANSPORT_DECRYPT), "PKCS7_GOST94_KEY_TRANSPORT_DECRYPT"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CC_DECRYPT), "pkey_GOST01cc_decrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CC_ENCRYPT), "pkey_GOST01cc_encrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "pkey_GOST01cp_encrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST01_KEYGEN), "PKEY_GOST01_KEYGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CC_DECRYPT), "pkey_GOST94cc_decrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CC_ENCRYPT), "pkey_GOST94cc_encrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "pkey_GOST94cp_decrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "pkey_GOST94cp_encrypt"}, +{ERR_FUNC(GOST_F_PKEY_GOST94_KEYGEN), "PKEY_GOST94_KEYGEN"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, +{ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, +{ERR_FUNC(GOST_F_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_PRIV_DECODE_GOST_94), "PRIV_DECODE_GOST_94"}, +{ERR_FUNC(GOST_F_PRIV_DECODE_MAC), "PRIV_DECODE_MAC"}, +{ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, +{ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, +{ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, +{ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, +{ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, +{0,NULL} }; static ERR_STRING_DATA GOST_str_reasons[]= { - {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, - {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, - {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, - {ERR_REASON(GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT),"ctx not initialized for encrypt"}, - {ERR_REASON(GOST_R_ERROR_COMPUTING_MAC) ,"error computing mac"}, - {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"}, - {ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"}, - {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"}, - {ERR_REASON(GOST_R_ERROR_STORING_ENCRYPTED_KEY),"error storing encrypted key"}, - {ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"}, - {ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"}, - {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, - {ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"}, - {ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"}, - {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, - {ERR_REASON(GOST_R_INVALID_ENCRYPTED_KEY_SIZE),"invalid encrypted key size"}, - {ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"}, - {ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"}, - {ERR_REASON(GOST_R_INVALID_PARAMSET) ,"invalid paramset"}, - {ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED),"key is not initalized"}, - {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED),"key is not initialized"}, - {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING),"key parameters missing"}, - {ERR_REASON(GOST_R_MALLOC_FAILURE) ,"malloc failure"}, - {ERR_REASON(GOST_R_NOT_ENOUGH_SPACE_FOR_KEY),"not enough space for key"}, - {ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"}, - {ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, - {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, - {ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"}, - {ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"}, - {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, - {ERR_REASON(GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH),"session key mac does not match"}, - {ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, - {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, - {ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"}, - {ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"}, - {0,NULL} +{ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT),"bad key parameters format"}, +{ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT),"bad pkey parameters format"}, +{ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY),"cannot pack ephemeral key"}, +{ERR_REASON(GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT),"ctx not initialized for encrypt"}, +{ERR_REASON(GOST_R_DECODE_ERROR) ,"decode error"}, +{ERR_REASON(GOST_R_ERROR_COMPUTING_MAC) ,"error computing mac"}, +{ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY),"error computing shared key"}, +{ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO),"error packing key transport info"}, +{ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),"error parsing key transport info"}, +{ERR_REASON(GOST_R_ERROR_STORING_ENCRYPTED_KEY),"error storing encrypted key"}, +{ERR_REASON(GOST_R_ERROR_STORING_IV) ,"error storing iv"}, +{ERR_REASON(GOST_R_ERROR_STORING_MAC) ,"error storing mac"}, +{ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS),"incompatible algorithms"}, +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS),"invalid cipher params"}, +{ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID),"invalid cipher param oid"}, +{ERR_REASON(GOST_R_INVALID_DIGEST_TYPE) ,"invalid digest type"}, +{ERR_REASON(GOST_R_INVALID_ENCRYPTED_KEY_SIZE),"invalid encrypted key size"}, +{ERR_REASON(GOST_R_INVALID_GOST94_PARMSET),"invalid gost94 parmset"}, +{ERR_REASON(GOST_R_INVALID_IV_LENGTH) ,"invalid iv length"}, +{ERR_REASON(GOST_R_INVALID_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_NOT_ENOUGH_SPACE_FOR_KEY),"not enough space for key"}, +{ERR_REASON(GOST_R_NO_MEMORY) ,"no memory"}, +{ERR_REASON(GOST_R_NO_PARAMETERS_SET) ,"no parameters set"}, +{ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED) ,"public key undefined"}, +{ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR),"random generator error"}, +{ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE),"random generator failure"}, +{ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED),"random number generator failed"}, +{ERR_REASON(GOST_R_SESSION_KEY_MAC_DOES_NOT_MATCH),"session key mac does not match"}, +{ERR_REASON(GOST_R_SIGNATURE_MISMATCH) ,"signature mismatch"}, +{ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),"signature parts greater than q"}, +{ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),"unsupported cipher ctl command"}, +{ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET),"unsupported parameter set"}, +{0,NULL} }; #endif #ifdef GOST_LIB_NAME static ERR_STRING_DATA GOST_lib_name[]= - { - {0 ,GOST_LIB_NAME}, - {0,NULL} + { +{0 ,GOST_LIB_NAME}, +{0,NULL} }; #endif diff --git a/engines/ccgost/e_gost_err.h b/engines/ccgost/e_gost_err.h index 49f4cd5766..0818a681cf 100644 --- a/engines/ccgost/e_gost_err.h +++ b/engines/ccgost/e_gost_err.h @@ -100,7 +100,11 @@ void ERR_GOST_error(int function, int reason, char *file, int line); #define GOST_F_PKEY_GOST_CTRL 114 #define GOST_F_PKEY_GOST_CTRL01_STR 115 #define GOST_F_PKEY_GOST_CTRL94_STR 116 +#define GOST_F_PKEY_GOST_MAC_CTRL 138 +#define GOST_F_PKEY_GOST_MAC_CTRL_STR 139 +#define GOST_F_PKEY_GOST_MAC_KEYGEN 140 #define GOST_F_PRIV_DECODE_GOST_94 117 +#define GOST_F_PRIV_DECODE_MAC 141 #define GOST_F_PUB_DECODE_GOST01 136 #define GOST_F_PUB_DECODE_GOST94 134 #define GOST_F_PUB_ENCODE_GOST01 135 @@ -112,6 +116,7 @@ void ERR_GOST_error(int function, int reason, char *file, int line); #define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 129 #define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 114 #define GOST_R_CTX_NOT_INITIALIZED_FOR_ENCRYPT 115 +#define GOST_R_DECODE_ERROR 134 #define GOST_R_ERROR_COMPUTING_MAC 116 #define GOST_R_ERROR_COMPUTING_SHARED_KEY 117 #define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 118 @@ -126,10 +131,12 @@ void ERR_GOST_error(int function, int reason, char *file, int line); #define GOST_R_INVALID_ENCRYPTED_KEY_SIZE 123 #define GOST_R_INVALID_GOST94_PARMSET 127 #define GOST_R_INVALID_IV_LENGTH 102 +#define GOST_R_INVALID_MAC_KEY_LENGTH 135 #define GOST_R_INVALID_PARAMSET 103 #define GOST_R_KEY_IS_NOT_INITALIZED 104 #define GOST_R_KEY_IS_NOT_INITIALIZED 105 #define GOST_R_KEY_PARAMETERS_MISSING 131 +#define GOST_R_MAC_KEY_NOT_SET 136 #define GOST_R_MALLOC_FAILURE 124 #define GOST_R_NOT_ENOUGH_SPACE_FOR_KEY 125 #define GOST_R_NO_MEMORY 106 diff --git a/engines/ccgost/gost_ameth.c b/engines/ccgost/gost_ameth.c index 807aff6bbd..f5ac9c2d80 100644 --- a/engines/ccgost/gost_ameth.c +++ b/engines/ccgost/gost_ameth.c @@ -9,6 +9,7 @@ **********************************************************************/ #include #include +#include #include #include "gost_params.h" #include "gost_lcl.h" @@ -706,7 +707,80 @@ static int pkey_bits_gost(const EVP_PKEY *pk) { return 256; } +/*------------------------ ASN1 METHOD for GOST MAC -------------------*/ +static void mackey_free_gost(EVP_PKEY *pk) + { + if (pk->pkey.ptr) { + OPENSSL_free(pk->pkey.ptr); + } + } +static int priv_decode_mac(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) + { + X509_ALGOR *palg = NULL; + int priv_len = 0; + ASN1_OBJECT *palg_obj = NULL; + ASN1_OCTET_STRING *s=NULL; + const unsigned char *pkey_buf = NULL, *p = NULL; + unsigned char *keybuf=NULL; + if (!PKCS8_pkey_get0(&palg_obj,&pkey_buf,&priv_len,&palg,p8inf)) + { + return 0; + } + p = pkey_buf; + if (V_ASN1_OCTET_STRING != *p) + { + GOSTerr(GOST_F_PRIV_DECODE_MAC, + GOST_R_DECODE_ERROR); + return 0; + } + s = d2i_ASN1_OCTET_STRING(NULL,&p,priv_len); + if (!s || s->length!=32) + { + GOSTerr(GOST_F_PRIV_DECODE_MAC, + GOST_R_DECODE_ERROR); + return 0; + } + keybuf = OPENSSL_malloc(32); + memcpy(keybuf,s->data,32); + EVP_PKEY_assign(pk,EVP_PKEY_base_id(pk),keybuf); + ASN1_STRING_free(s); + return 1; + } + +static int priv_encode_mac(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) + { + ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + ASN1_STRING *key = ASN1_STRING_new(); + unsigned char *priv_buf=NULL, *data = EVP_PKEY_get0((EVP_PKEY *)pk); + int priv_len; + + ASN1_STRING_set(key, data, 32); + priv_len = i2d_ASN1_OCTET_STRING(key,&priv_buf); + ASN1_STRING_free(key); + return PKCS8_pkey_set0(p8,algobj,0,V_ASN1_NULL,NULL,priv_buf,priv_len); + } +static int priv_print_mac(BIO *out,const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) + { + unsigned char *data = EVP_PKEY_get0((EVP_PKEY *)pkey); + int i; + if (!BIO_indent(out, indent,128)) return 0; + for (i=0; i<32;i++) { + BIO_printf(out,"%02x",data[i]); + } + return 1; + } +static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) + { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_Gost28147_89_MAC; + return 2; + } + return -2; +} /* ----------------------------------------------------------------------*/ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pemstr, const char* info) { @@ -749,6 +823,12 @@ int register_ameth_gost (int nid, EVP_PKEY_ASN1_METHOD **ameth, const char* pems EVP_PKEY_asn1_set_ctrl (*ameth, pkey_ctrl_gost); break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); + EVP_PKEY_asn1_set_private(*ameth, priv_decode_mac, + priv_encode_mac, priv_print_mac); + EVP_PKEY_asn1_set_ctrl(*ameth,mac_ctrl_gost); + break; } return 1; } diff --git a/engines/ccgost/gost_crypt.c b/engines/ccgost/gost_crypt.c index 04b1e555c2..e6645c2e8c 100644 --- a/engines/ccgost/gost_crypt.c +++ b/engines/ccgost/gost_crypt.c @@ -551,7 +551,9 @@ int gost_imit_init_vizir(EVP_MD_CTX *ctx) int gost_imit_init_cpa(EVP_MD_CTX *ctx) { struct ossl_gost_imit_ctx *c = ctx->md_data; - memset(c,0,sizeof(struct ossl_gost_imit_ctx)); + memset(c->buffer,0,16); + c->count = 0; + c->bytes_left=0; c->key_meshing=1; gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA); return 1; diff --git a/engines/ccgost/gost_eng.c b/engines/ccgost/gost_eng.c index 1c5a493df6..fd474dc1a5 100644 --- a/engines/ccgost/gost_eng.c +++ b/engines/ccgost/gost_eng.c @@ -38,13 +38,15 @@ static int gost_digest_nids[] = static int gost_pkey_meth_nids[] = {NID_id_GostR3410_94_cc, NID_id_GostR3410_94, NID_id_GostR3410_2001_cc, - NID_id_GostR3410_2001, 0}; + NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0}; static EVP_PKEY_METHOD *pmeth_GostR3410_94_cc = NULL, *pmeth_GostR3410_94 = NULL, - *pmeth_GostR3410_2001_cc = NULL, *pmeth_GostR3410_2001 = NULL; + *pmeth_GostR3410_2001_cc = NULL, *pmeth_GostR3410_2001 = NULL, + *pmeth_Gost28147_MAC = NULL; static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94_cc = NULL, *ameth_GostR3410_94 = NULL, - *ameth_GostR3410_2001_cc = NULL, *ameth_GostR3410_2001 = NULL; + *ameth_GostR3410_2001_cc = NULL, *ameth_GostR3410_2001 = NULL, + *ameth_Gost28147_MAC = NULL; static int gost_engine_init(ENGINE *e) @@ -119,11 +121,15 @@ static int bind_gost (ENGINE *e,const char *id) 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_cc, &ameth_GostR3410_2001_cc, "GOST2001CC", "GOST R 34.10-2001, Cryptocom LTD implementation")) 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 (!register_pmeth_gost(NID_id_GostR3410_94_cc, &pmeth_GostR3410_94_cc, 0)) goto end; if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) goto end; if (!register_pmeth_gost(NID_id_GostR3410_2001_cc, &pmeth_GostR3410_2001_cc, 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) @@ -201,7 +207,7 @@ static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, if (!pmeth) { *nids = gost_pkey_meth_nids; - return 4; + return 5; } switch (nid) @@ -210,6 +216,7 @@ static int gost_pkey_meths (ENGINE *e, EVP_PKEY_METHOD **pmeth, case NID_id_GostR3410_94: *pmeth = pmeth_GostR3410_94; return 1; case NID_id_GostR3410_2001_cc: *pmeth = pmeth_GostR3410_2001_cc; return 1; case NID_id_GostR3410_2001: *pmeth = pmeth_GostR3410_2001; return 1; + case NID_id_Gost28147_89_MAC: *pmeth = pmeth_Gost28147_MAC; return 1; default:; } @@ -223,7 +230,7 @@ static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, if (!ameth) { *nids = gost_pkey_meth_nids; - return 4; + return 5; } switch (nid) { @@ -231,6 +238,8 @@ static int gost_pkey_asn1_meths (ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, case NID_id_GostR3410_94: *ameth = ameth_GostR3410_94; return 1; case NID_id_GostR3410_2001_cc: *ameth = ameth_GostR3410_2001_cc; return 1; case NID_id_GostR3410_2001: *ameth = ameth_GostR3410_2001; return 1; + case NID_id_Gost28147_89_MAC: *ameth = ameth_Gost28147_MAC; return 1; + default:; } diff --git a/engines/ccgost/gost_lcl.h b/engines/ccgost/gost_lcl.h index 5904eeb834..bb33d7c0c8 100644 --- a/engines/ccgost/gost_lcl.h +++ b/engines/ccgost/gost_lcl.h @@ -35,14 +35,25 @@ 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) +/* 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) /* Pmeth internal representation */ struct gost_pmeth_data { int sign_param_nid; /* Should be set whenever parameters are filled */ EVP_PKEY *eph_seckey; EVP_MD *md; }; + + struct gost_mac_pmeth_data { + int key_set; + EVP_MD *md; + unsigned char key[32]; + } ; /* GOST-specific ASN1 structures */ @@ -146,6 +157,8 @@ extern EVP_CIPHER cipher_gost_cpacnt; extern EVP_MD imit_gost_vizir; extern EVP_MD imit_gost_cpa; #endif +#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 ); diff --git a/engines/ccgost/gost_md.c b/engines/ccgost/gost_md.c index 445679daa9..294a624d7d 100644 --- a/engines/ccgost/gost_md.c +++ b/engines/ccgost/gost_md.c @@ -59,12 +59,15 @@ int gost_digest_final(EVP_MD_CTX *ctx,unsigned char *md) int gost_digest_copy(EVP_MD_CTX *to,const EVP_MD_CTX *from) { + if (to->md_data && from->md_data) memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx)); + 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; } diff --git a/engines/ccgost/gost_pmeth.c b/engines/ccgost/gost_pmeth.c index 26ac02c8ce..8ed531f038 100644 --- a/engines/ccgost/gost_pmeth.c +++ b/engines/ccgost/gost_pmeth.c @@ -10,6 +10,7 @@ #include #include #include +#include /*For string_to_hex */ #include #include #include @@ -507,7 +508,176 @@ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) data->eph_seckey=eph_key; return 1; } +/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ +static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) + { + struct gost_mac_pmeth_data *data; + data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); + if (!data) return 0; + memset(data,0,sizeof(struct gost_mac_pmeth_data)); + EVP_PKEY_CTX_set_data(ctx,data); + return 1; + } +static void pkey_gost_mac_cleanup (EVP_PKEY_CTX *ctx) + { + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + OPENSSL_free(data); + } +static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) + { + struct gost_mac_pmeth_data *dst_data,*src_data; + if (!pkey_gost_mac_init(dst)) + { + return 0; + } + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + return 1; + } + +static int pkey_gost_mac_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2) + { + struct gost_mac_pmeth_data *data = +(struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); + switch (type) + { + case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + data->md = (EVP_MD *)p2; + return 1; + } + break; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (p1 != 32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + memcpy(data->key,p2,32); + data->key_set = 1; + return 1; + case EVP_PKEY_CTRL_DIGESTINIT: + { + EVP_MD_CTX *mctx = p2; + void *key; + if (!data->key_set) + { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (!key) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + } else { + key = &(data->key); + } + return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key); + } + } + return -2; + } +static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) + { + if (!strcmp(type, key_ctrl_string)) + { + if (strlen(value)!=32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32,(char *)value); + } + if (!strcmp(type, hexkey_ctrl_string)) + { + long keylen; int ret; + unsigned char *keybuf=string_to_hex(value,&keylen); + if (keylen != 32) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + ret= pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32,keybuf); + OPENSSL_free(keybuf); + return ret; + + } + return -2; + } + +static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) + { + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + unsigned char *keydata; + if (!data->key_set) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + keydata = OPENSSL_malloc(32); + memcpy(keydata,data->key,32); + EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); + return 1; + } + +static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) + { + void *key; + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + if (!mctx->digest) return 1; + if (!data->key_set) + { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (!key) + { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_MAC_KEY_NOT_SET); + return 0; + } + } else { + key = &(data->key); + } + return mctx->digest->md_ctrl(mctx,EVP_MD_CTRL_SET_KEY,32,key); +} + +static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) + { + if (!sig) + { + *siglen = 4; + return 1; + } + return EVP_DigestFinal_ex(mctx,sig,siglen); + } /* ----------------------------------------------------------------*/ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) { @@ -559,6 +729,14 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) pkey_gost_encrypt_init, pkey_GOST01cp_encrypt); EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth,pkey_gost_mac_signctx_init, pkey_gost_mac_signctx); + EVP_PKEY_meth_set_keygen(*pmeth,NULL, pkey_gost_mac_keygen); + EVP_PKEY_meth_set_init(*pmeth,pkey_gost_mac_init); + EVP_PKEY_meth_set_cleanup(*pmeth,pkey_gost_mac_cleanup); + EVP_PKEY_meth_set_copy(*pmeth,pkey_gost_mac_copy); + return 1; default: /*Unsupported method*/ return 0; } -- 2.25.1