Initial GOST MAC support. Not fully working yet...
authorDr. Stephen Henson <steve@openssl.org>
Thu, 17 May 2007 17:44:09 +0000 (17:44 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Thu, 17 May 2007 17:44:09 +0000 (17:44 +0000)
engines/Makefile
engines/ccgost/e_gost_err.c
engines/ccgost/e_gost_err.h
engines/ccgost/gost_ameth.c
engines/ccgost/gost_crypt.c
engines/ccgost/gost_eng.c
engines/ccgost/gost_lcl.h
engines/ccgost/gost_md.c
engines/ccgost/gost_pmeth.c

index 2454f3ba5ed6d224e51da5331a7cd906512a3649..7796cb53511a1aa8cfbe7c121c891756577c5235 100644 (file)
@@ -131,6 +131,7 @@ errors:
                $(PERL) ../util/mkerr.pl -conf e_$$l.ec \
                        -nostatic -staticloader -write e_$$l.c; \
        done
                $(PERL) ../util/mkerr.pl -conf e_$$l.ec \
                        -nostatic -staticloader -write e_$$l.c; \
        done
+       (cd ccgost; $(MAKE) PERL=$(PERL) errors)
 
 tests:
 
 
 tests:
 
index 3dad4f4fc32fff501d0a02be23f402052b55a498..62c8bacbe41c8e180e7d1f13e48f5cca431ba77d 100644 (file)
@@ -1,6 +1,6 @@
 /* e_gost_err.c */
 /* ====================================================================
 /* 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
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 static ERR_STRING_DATA GOST_str_functs[]=
        {
 
 static ERR_STRING_DATA GOST_str_functs[]=
        {
-       {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS),     "DECODE_GOST_ALGOR_PARAMS"},
-       {ERR_FUNC(GOST_F_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[]=
        {
        };
 
 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[]=
        };
 
 #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
 
        };
 #endif
 
index 49f4cd576694e945e556800745c8956a848b2aff..0818a681cf169ad512ed43e828948c6fe314951e 100644 (file)
@@ -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_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_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
 #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_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
 #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_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_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
 #define GOST_R_MALLOC_FAILURE                           124
 #define GOST_R_NOT_ENOUGH_SPACE_FOR_KEY                         125
 #define GOST_R_NO_MEMORY                                106
index 807aff6bbdf3937409c638ee1d6f014e799b4b2b..f5ac9c2d80155a6be4c024f189391b74e99f37d8 100644 (file)
@@ -9,6 +9,7 @@
  **********************************************************************/
 #include <openssl/engine.h>
 #include <openssl/evp.h>
  **********************************************************************/
 #include <openssl/engine.h>
 #include <openssl/evp.h>
+#include <openssl/asn1.h>
 #include <string.h>
 #include "gost_params.h"
 #include "gost_lcl.h"
 #include <string.h>
 #include "gost_params.h"
 #include "gost_lcl.h"
@@ -706,7 +707,80 @@ static int pkey_bits_gost(const EVP_PKEY *pk)
        {
        return 256;
        }
        {
        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) 
        {
 /* ----------------------------------------------------------------------*/
 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;
        
                        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;
        }
                }               
        return 1;
        }
index 04b1e555c2fb0e6502314588562878a9b7412c8e..e6645c2e8c4e1ffaa24b234234064ba94dc0a54b 100644 (file)
@@ -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;
 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;
        c->key_meshing=1;
        gost_init(&(c->cctx),&Gost28147_CryptoProParamSetA);
        return 1;
index 1c5a493df692abae8bd7fdcf02ecfcc27d96776b..fd474dc1a5163835f6c404f0542882df12eda3f8 100644 (file)
@@ -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,
 
 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,
 
 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,
 
 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)
 
 
 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_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_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)
        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;
        if (!pmeth) 
                {
                *nids = gost_pkey_meth_nids;
-               return 4;
+               return 5;
                }
 
        switch (nid) 
                }
 
        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_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:;
                }
        
                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;
        if (!ameth) 
                {
                *nids = gost_pkey_meth_nids;
-               return 4;
+               return 5;
                }
        switch (nid) 
                {
                }
        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_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:;
                }
        
                default:;
                }
        
index 5904eeb8344f85daa5231c50dac4ab527acca55f..bb33d7c0c8aadec4ae295da047fc808d14835727 100644 (file)
        int register_pmeth_gost (int id, EVP_PKEY_METHOD **pmeth, int flags);
 
 /* Gost-specific pmeth control-function parameters */
        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)
 /* 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;
        };
 /* 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 */
 
 
 /* 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
 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 );
 /* 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 );
index 445679daa9a9f444e3d57e3ad765db45d4f58b92..294a624d7d5dc67bbe73119df52a51d221f2d85a 100644 (file)
@@ -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) 
        {
 
 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));
        memcpy(to->md_data,from->md_data,sizeof(struct ossl_gost_digest_ctx));
+
        return 1;
        }               
 
 int gost_digest_cleanup(EVP_MD_CTX *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;
        }       
        memset(ctx->md_data,0,sizeof(struct ossl_gost_digest_ctx));
        return 1;
        }       
index 26ac02c8ce2210610c8cd974b9432989c1ca8a98..8ed531f038bad3e1deee4f9498b3a2bcf9be4bce 100644 (file)
@@ -10,6 +10,7 @@
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/ec.h>
+#include <openssl/x509v3.h> /*For string_to_hex */
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -507,7 +508,176 @@ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx)
        data->eph_seckey=eph_key;
        return 1;
        }
        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)
        {
 /* ----------------------------------------------------------------*/
 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;
                                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;
                }
                default: /*Unsupported method*/
                        return 0;
                }