]> www.wagner.pp.ru Git - openssl-gost/engine.git/commitdiff
Merge branch 'magma_impl' into openssl_1_0_2_alt
authorVitaly Chikunov <vt@altlinux.org>
Fri, 20 Jul 2018 01:52:40 +0000 (04:52 +0300)
committerVitaly Chikunov <vt@altlinux.org>
Fri, 20 Jul 2018 01:52:40 +0000 (04:52 +0300)
18 files changed:
CMakeLists.txt
INSTALL.md
e_gost_err.c
e_gost_err.h
etalon/gh.dat [new file with mode: 0644]
etalon/mac.txt [new file with mode: 0644]
etalon/magma.dat [new file with mode: 0644]
gost.ec
gost.txt [new file with mode: 0644]
gost89.c
gost89.h
gost_ameth.c
gost_crypt.c
gost_eng.c
gost_grasshopper_cipher.c
gost_lcl.h
gost_omac.c [new file with mode: 0644]
gost_pmeth.c

index 574161012e1edca8dc604ba3c2b5958958a05abb..4d834144a7f069ec7f32cdfaac0e9d224ffdeaf1 100644 (file)
@@ -88,12 +88,17 @@ set(GOST_EC_SOURCE_FILES
         gost_ec_sign.c
         )
 
+set (GOST_OMAC_SOURCE_FILES
+        gost_omac.c
+        )
+
 set(GOST_LIB_SOURCE_FILES
         ${GOST_89_SOURCE_FILES}
         ${GOST_HASH_SOURCE_FILES}
         ${GOST_HASH_2012_SOURCE_FILES}
         ${GOST_GRASSHOPPER_SOURCE_FILES}
         ${GOST_EC_SOURCE_FILES}
+        ${GOST_OMAC_SOURCE_FILES}
         )
 
 set(GOST_ENGINE_SOURCE_FILES
@@ -102,6 +107,7 @@ set(GOST_ENGINE_SOURCE_FILES
         gost_md.c
         gost_md2012.c
         gost_pmeth.c
+        gost_omac.c
         )
 
 add_library(gost_core STATIC ${GOST_LIB_SOURCE_FILES})
@@ -125,6 +131,11 @@ set(GOST_12_SUM_SOURCE_FILES
 add_executable(gost12sum ${GOST_12_SUM_SOURCE_FILES})
 target_link_libraries(gost12sum gost_core)
 
+set_source_files_properties(tags PROPERTIES GENERATED true)
+add_custom_target(tags
+    COMMAND ctags -R . ${OPENSSL_ROOT_DIR}
+    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
 # install
 set(OPENSSL_ENGINES_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/engines-${OPENSSL_VERSION_MAJOR}_${OPENSSL_VERSION_MINOR})
 set(OPENSSL_MAN_INSTALL_DIR ${CMAKE_INSTALL_MANDIR}/man1)
index e0e89468dcb5e3412f8071f4c7385939820afcf1..5849af24013b7d7fb51096284f741ab628a7b951 100644 (file)
@@ -6,7 +6,7 @@ How to Build
 
 To build and install OpenSSL GOST Engine, you will need
 
-* OpenSSL 1.1.*
+* OpenSSL 1.1.1
 * an ANSI C compiler
 * CMake (3.0 or newer)
 
index baaeb44ec7aebeac60076bf65a96bb87b65f139e..c8804faa0d07d8fc39cbacda75bef2b802f15e62 100644 (file)
-/* e_gost_err.c */
-/* ====================================================================
- * Copyright (c) 1999-2016 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.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-
 /*
- * 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.
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
-#include <stdio.h>
 #include <openssl/err.h>
 #include "e_gost_err.h"
 
-/* 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)
-
 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_GOST_EC_PARAMS), "FILL_GOST_EC_PARAMS"},
-    {ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"},
-    {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_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"},
-    {ERR_FUNC(GOST_F_GOST_EC_COMPUTE_PUBLIC), "GOST_EC_COMPUTE_PUBLIC"},
-    {ERR_FUNC(GOST_F_GOST_EC_KEYGEN), "GOST_EC_KEYGEN"},
-    {ERR_FUNC(GOST_F_GOST_EC_SIGN), "GOST_EC_SIGN"},
-    {ERR_FUNC(GOST_F_GOST_EC_VERIFY), "GOST_EC_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_GOST_EC), "PARAM_COPY_GOST_EC"},
-    {ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"},
-    {ERR_FUNC(GOST_F_PKEY_GOST12_PARAMGEN), "PKEY_GOST12_PARAMGEN"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_DECRYPT), "PKEY_GOST_ECCP_DECRYPT"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_ECCP_ENCRYPT), "PKEY_GOST_ECCP_ENCRYPT"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_EC_CTRL_STR_256), "PKEY_GOST_EC_CTRL_STR_256"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_EC_CTRL_STR_512), "PKEY_GOST_EC_CTRL_STR_512"},
-    {ERR_FUNC(GOST_F_PKEY_GOST_EC_DERIVE), "PKEY_GOST_EC_DERIVE"},
-    {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_PKEY_GOST_MAC_SIGNCTX_INIT),
-     "PKEY_GOST_MAC_SIGNCTX_INIT"},
-    {ERR_FUNC(GOST_F_PRINT_GOST_EC_PUB), "PRINT_GOST_EC_PUB"},
-    {ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"},
-    {ERR_FUNC(GOST_F_PUB_DECODE_GOST_EC), "PUB_DECODE_GOST_EC"},
-    {ERR_FUNC(GOST_F_PUB_ENCODE_GOST_EC), "PUB_ENCODE_GOST_EC"},
-    {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"},
-    {ERR_FUNC(GOST_F_VKO_COMPUTE_KEY), "VKO_COMPUTE_KEY"},
+    {ERR_PACK(0, GOST_F_DECODE_GOST_ALGOR_PARAMS, 0),
+     "decode_gost_algor_params"},
+    {ERR_PACK(0, GOST_F_ENCODE_GOST_ALGOR_PARAMS, 0),
+     "encode_gost_algor_params"},
+    {ERR_PACK(0, GOST_F_FILL_GOST_EC_PARAMS, 0), "fill_GOST_EC_params"},
+    {ERR_PACK(0, GOST_F_GET_ENCRYPTION_PARAMS, 0), "get_encryption_params"},
+    {ERR_PACK(0, GOST_F_GOST89_GET_ASN1_PARAMETERS, 0),
+     "gost89_get_asn1_parameters"},
+    {ERR_PACK(0, GOST_F_GOST89_SET_ASN1_PARAMETERS, 0),
+     "gost89_set_asn1_parameters"},
+    {ERR_PACK(0, GOST_F_GOST_CIPHER_CTL, 0), "gost_cipher_ctl"},
+    {ERR_PACK(0, GOST_F_GOST_EC_COMPUTE_PUBLIC, 0), "gost_ec_compute_public"},
+    {ERR_PACK(0, GOST_F_GOST_EC_KEYGEN, 0), "gost_ec_keygen"},
+    {ERR_PACK(0, GOST_F_GOST_EC_SIGN, 0), "gost_ec_sign"},
+    {ERR_PACK(0, GOST_F_GOST_EC_VERIFY, 0), "gost_ec_verify"},
+    {ERR_PACK(0, GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, 0),
+     "gost_grasshopper_cipher_ctl"},
+    {ERR_PACK(0, GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS, 0),
+     "gost_grasshopper_set_asn1_parameters"},
+    {ERR_PACK(0, GOST_F_GOST_IMIT_CTRL, 0), "gost_imit_ctrl"},
+    {ERR_PACK(0, GOST_F_GOST_IMIT_FINAL, 0), "gost_imit_final"},
+    {ERR_PACK(0, GOST_F_GOST_IMIT_UPDATE, 0), "gost_imit_update"},
+    {ERR_PACK(0, GOST_F_OMAC_IMIT_CTRL, 0), "omac_imit_ctrl"},
+    {ERR_PACK(0, GOST_F_OMAC_IMIT_FINAL, 0), "omac_imit_final"},
+    {ERR_PACK(0, GOST_F_OMAC_IMIT_UPDATE, 0), "omac_imit_update"},
+    {ERR_PACK(0, GOST_F_OMAC_KEY, 0), "omac_key"},
+    {ERR_PACK(0, GOST_F_PARAM_COPY_GOST_EC, 0), "param_copy_gost_ec"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST2001_PARAMGEN, 0), "pkey_gost2001_paramgen"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST2012_PARAMGEN, 0), "pkey_gost2012_paramgen"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_CTRL, 0), "pkey_gost_ctrl"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_ECCP_DECRYPT, 0), "pkey_GOST_ECcp_decrypt"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_ECCP_ENCRYPT, 0), "pkey_GOST_ECcp_encrypt"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_EC_CTRL_STR_256, 0),
+     "pkey_gost_ec_ctrl_str_256"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_EC_CTRL_STR_512, 0),
+     "pkey_gost_ec_ctrl_str_512"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_EC_DERIVE, 0), "pkey_gost_ec_derive"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, 0),
+     "pkey_gost_grasshopper_mac_signctx_init"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_CTRL, 0), "pkey_gost_mac_ctrl"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_CTRL_STR, 0), "pkey_gost_mac_ctrl_str"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_KEYGEN_BASE, 0),
+     "pkey_gost_mac_keygen_base"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, 0),
+     "pkey_gost_mac_signctx_init"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, 0),
+     "pkey_gost_magma_mac_signctx_init"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_OMAC_CTRL, 0), "pkey_gost_omac_ctrl"},
+    {ERR_PACK(0, GOST_F_PKEY_GOST_OMAC_CTRL_STR, 0), "pkey_gost_omac_ctrl_str"},
+    {ERR_PACK(0, GOST_F_PRINT_GOST_EC_PUB, 0), "print_gost_ec_pub"},
+    {ERR_PACK(0, GOST_F_PRIV_DECODE_GOST, 0), "priv_decode_gost"},
+    {ERR_PACK(0, GOST_F_PUB_DECODE_GOST_EC, 0), "pub_decode_gost_ec"},
+    {ERR_PACK(0, GOST_F_PUB_ENCODE_GOST_EC, 0), "pub_encode_gost_ec"},
+    {ERR_PACK(0, GOST_F_UNPACK_CP_SIGNATURE, 0), "unpack_cp_signature"},
+    {ERR_PACK(0, GOST_F_VKO_COMPUTE_KEY, 0), "VKO_compute_key"},
     {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_PARSING_KEY_TRANSPORT_INFO),
-     "error parsing key transport info"},
-    {ERR_REASON(GOST_R_ERROR_POINT_MUL), "error point mul"},
-    {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_IV_LENGTH), "invalid iv length"},
-    {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"},
-    {ERR_REASON(GOST_R_INVALID_MAC_KEY_SIZE), "invalid mac key size"},
-    {ERR_REASON(GOST_R_INVALID_MAC_PARAMS), "invalid mac params"},
-    {ERR_REASON(GOST_R_INVALID_MAC_SIZE), "invalid mac size"},
-    {ERR_REASON(GOST_R_INVALID_PARAMSET), "invalid paramset"},
-    {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_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_RNG_ERROR), "rng error"},
-    {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"},
+    {ERR_PACK(0, 0, GOST_R_BAD_KEY_PARAMETERS_FORMAT),
+    "bad key parameters format"},
+    {ERR_PACK(0, 0, GOST_R_BAD_ORDER), "bad order"},
+    {ERR_PACK(0, 0, GOST_R_BAD_PKEY_PARAMETERS_FORMAT),
+    "bad pkey parameters format"},
+    {ERR_PACK(0, 0, GOST_R_CANNOT_PACK_EPHEMERAL_KEY),
+    "cannot pack ephemeral key"},
+    {ERR_PACK(0, 0, GOST_R_CIPHER_NOT_FOUND), "cipher not found"},
+    {ERR_PACK(0, 0, GOST_R_CTRL_CALL_FAILED), "ctrl call failed"},
+    {ERR_PACK(0, 0, GOST_R_ERROR_COMPUTING_SHARED_KEY),
+    "error computing shared key"},
+    {ERR_PACK(0, 0, GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO),
+    "error parsing key transport info"},
+    {ERR_PACK(0, 0, GOST_R_ERROR_POINT_MUL), "error point mul"},
+    {ERR_PACK(0, 0, GOST_R_INCOMPATIBLE_ALGORITHMS), "incompatible algorithms"},
+    {ERR_PACK(0, 0, GOST_R_INCOMPATIBLE_PEER_KEY), "incompatible peer key"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_CIPHER_PARAMS), "invalid cipher params"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_CIPHER_PARAM_OID),
+    "invalid cipher param oid"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_DIGEST_TYPE), "invalid digest type"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_IV_LENGTH), "invalid iv length"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_MAC_KEY_SIZE), "invalid mac key size"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_MAC_PARAMS), "invalid mac params"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_MAC_SIZE), "invalid mac size"},
+    {ERR_PACK(0, 0, GOST_R_INVALID_PARAMSET), "invalid paramset"},
+    {ERR_PACK(0, 0, GOST_R_KEY_IS_NOT_INITIALIZED), "key is not initialized"},
+    {ERR_PACK(0, 0, GOST_R_KEY_PARAMETERS_MISSING), "key parameters missing"},
+    {ERR_PACK(0, 0, GOST_R_MAC_KEY_NOT_SET), "mac key not set"},
+    {ERR_PACK(0, 0, GOST_R_NO_PARAMETERS_SET), "no parameters set"},
+    {ERR_PACK(0, 0, GOST_R_NO_PEER_KEY), "no peer key"},
+    {ERR_PACK(0, 0, GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR),
+    "no private part of non ephemeral keypair"},
+    {ERR_PACK(0, 0, GOST_R_PUBLIC_KEY_UNDEFINED), "public key undefined"},
+    {ERR_PACK(0, 0, GOST_R_RNG_ERROR), "rng error"},
+    {ERR_PACK(0, 0, GOST_R_SIGNATURE_MISMATCH), "signature mismatch"},
+    {ERR_PACK(0, 0, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q),
+    "signature parts greater than q"},
+    {ERR_PACK(0, 0, GOST_R_UKM_NOT_SET), "ukm not set"},
+    {ERR_PACK(0, 0, GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND),
+    "unsupported cipher ctl command"},
+    {ERR_PACK(0, 0, 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}
-};
-#endif
+static int lib_code = 0;
+static int error_loaded = 0;
 
-static int GOST_lib_error_code = 0;
-static int GOST_error_init = 1;
-
-void ERR_load_GOST_strings(void)
+int ERR_load_GOST_strings(void)
 {
-    if (GOST_lib_error_code == 0)
-        GOST_lib_error_code = ERR_get_next_error_library();
+    if (lib_code == 0)
+        lib_code = ERR_get_next_error_library();
 
-    if (GOST_error_init) {
-        GOST_error_init = 0;
+    if (!error_loaded) {
 #ifndef OPENSSL_NO_ERR
-        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);
+        ERR_load_strings(lib_code, GOST_str_functs);
+        ERR_load_strings(lib_code, GOST_str_reasons);
 #endif
+        error_loaded = 1;
     }
+    return 1;
 }
 
 void ERR_unload_GOST_strings(void)
 {
-    if (GOST_error_init == 0) {
+    if (error_loaded) {
 #ifndef OPENSSL_NO_ERR
-        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(lib_code, GOST_str_functs);
+        ERR_unload_strings(lib_code, GOST_str_reasons);
 #endif
-        GOST_error_init = 1;
+        error_loaded = 0;
     }
 }
 
 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 (lib_code == 0)
+        lib_code = ERR_get_next_error_library();
+    ERR_PUT_error(lib_code, function, reason, file, line);
 }
index d0f7d8943a07c6e86760b5b585e896384e716b28..b9ea379ed353004517f13afbab5bdc879810eac5 100644 (file)
@@ -1,77 +1,32 @@
-/* ====================================================================
- * Copyright (c) 2001-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. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com).  This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
  */
 
-#ifndef HEADER_GOST_ERR_H
-# define HEADER_GOST_ERR_H
+#ifndef HEADER_GOSTERR_H
+# define HEADER_GOSTERR_H
+
+# define GOSTerr(f, r) ERR_GOST_error((f), (r), OPENSSL_FILE, OPENSSL_LINE)
+
 
 # ifdef  __cplusplus
 extern "C" {
 # endif
+int ERR_load_GOST_strings(void);
+void ERR_unload_GOST_strings(void);
+void ERR_GOST_error(int function, int reason, char *file, int line);
+# ifdef  __cplusplus
+}
+# endif
 
-/* BEGIN ERROR CODES */
 /*
- * 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.
+ * GOST function codes.
  */
-    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__)
-
-/* Error codes for the GOST functions. */
-
-/* Function codes. */
 # define GOST_F_DECODE_GOST_ALGOR_PARAMS                  100
 # define GOST_F_ENCODE_GOST_ALGOR_PARAMS                  101
 # define GOST_F_FILL_GOST_EC_PARAMS                       102
@@ -83,63 +38,74 @@ extern "C" {
 # define GOST_F_GOST_EC_KEYGEN                            108
 # define GOST_F_GOST_EC_SIGN                              109
 # define GOST_F_GOST_EC_VERIFY                            110
-# define GOST_F_GOST_IMIT_CTRL                            111
-# define GOST_F_GOST_IMIT_FINAL                           112
-# define GOST_F_GOST_IMIT_UPDATE                          113
-# define GOST_F_PARAM_COPY_GOST_EC                        114
-# define GOST_F_PKEY_GOST01_PARAMGEN                      115
-# define GOST_F_PKEY_GOST12_PARAMGEN                      116
-# define GOST_F_PKEY_GOST_CTRL                            117
-# define GOST_F_PKEY_GOST_ECCP_DECRYPT                    118
-# define GOST_F_PKEY_GOST_ECCP_ENCRYPT                    119
-# define GOST_F_PKEY_GOST_EC_CTRL_STR_256                 120
-# define GOST_F_PKEY_GOST_EC_CTRL_STR_512                 121
-# define GOST_F_PKEY_GOST_EC_DERIVE                       122
-# define GOST_F_PKEY_GOST_MAC_CTRL                        123
-# define GOST_F_PKEY_GOST_MAC_CTRL_STR                    124
-# define GOST_F_PKEY_GOST_MAC_KEYGEN                      125
-# define GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT                132
-# define GOST_F_PRINT_GOST_EC_PUB                         126
-# define GOST_F_PRIV_DECODE_GOST                          127
-# define GOST_F_PUB_DECODE_GOST_EC                        128
-# define GOST_F_PUB_ENCODE_GOST_EC                        129
-# define GOST_F_UNPACK_CP_SIGNATURE                       130
-# define GOST_F_VKO_COMPUTE_KEY                           131
+# define GOST_F_GOST_GRASSHOPPER_CIPHER_CTL               111
+# define GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS      112
+# define GOST_F_GOST_IMIT_CTRL                            113
+# define GOST_F_GOST_IMIT_FINAL                           114
+# define GOST_F_GOST_IMIT_UPDATE                          115
+# define GOST_F_OMAC_IMIT_CTRL                            116
+# define GOST_F_OMAC_IMIT_FINAL                           117
+# define GOST_F_OMAC_IMIT_UPDATE                          118
+# define GOST_F_OMAC_KEY                                  138
+# define GOST_F_PARAM_COPY_GOST_EC                        119
+# define GOST_F_PKEY_GOST2001_PARAMGEN                    120
+# define GOST_F_PKEY_GOST2012_PARAMGEN                    121
+# define GOST_F_PKEY_GOST_CTRL                            122
+# define GOST_F_PKEY_GOST_ECCP_DECRYPT                    123
+# define GOST_F_PKEY_GOST_ECCP_ENCRYPT                    124
+# define GOST_F_PKEY_GOST_EC_CTRL_STR_256                 125
+# define GOST_F_PKEY_GOST_EC_CTRL_STR_512                 126
+# define GOST_F_PKEY_GOST_EC_DERIVE                       127
+# define GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT    141
+# define GOST_F_PKEY_GOST_MAC_CTRL                        128
+# define GOST_F_PKEY_GOST_MAC_CTRL_STR                    129
+# define GOST_F_PKEY_GOST_MAC_KEYGEN_BASE                 130
+# define GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT                131
+# define GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT          142
+# define GOST_F_PKEY_GOST_OMAC_CTRL                       139
+# define GOST_F_PKEY_GOST_OMAC_CTRL_STR                   140
+# define GOST_F_PRINT_GOST_EC_PUB                         132
+# define GOST_F_PRIV_DECODE_GOST                          133
+# define GOST_F_PUB_DECODE_GOST_EC                        134
+# define GOST_F_PUB_ENCODE_GOST_EC                        135
+# define GOST_F_UNPACK_CP_SIGNATURE                       136
+# define GOST_F_VKO_COMPUTE_KEY                           137
 
-/* Reason codes. */
+/*
+ * GOST reason codes.
+ */
 # define GOST_R_BAD_KEY_PARAMETERS_FORMAT                 100
+# define GOST_R_BAD_ORDER                                 132
 # define GOST_R_BAD_PKEY_PARAMETERS_FORMAT                101
 # define GOST_R_CANNOT_PACK_EPHEMERAL_KEY                 102
-# define GOST_R_CTRL_CALL_FAILED                          103
-# define GOST_R_ERROR_COMPUTING_SHARED_KEY                104
-# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO          105
-# define GOST_R_ERROR_POINT_MUL                           106
-# define GOST_R_INCOMPATIBLE_ALGORITHMS                   107
-# define GOST_R_INCOMPATIBLE_PEER_KEY                     108
-# define GOST_R_INVALID_CIPHER_PARAMS                     109
-# define GOST_R_INVALID_CIPHER_PARAM_OID                  110
-# define GOST_R_INVALID_DIGEST_TYPE                       111
-# define GOST_R_INVALID_IV_LENGTH                         112
-# define GOST_R_INVALID_MAC_KEY_LENGTH                    113
-# define GOST_R_INVALID_MAC_KEY_SIZE                      128
-# define GOST_R_INVALID_MAC_PARAMS                        130
-# define GOST_R_INVALID_MAC_SIZE                          129
-# define GOST_R_INVALID_PARAMSET                          114
-# define GOST_R_KEY_IS_NOT_INITIALIZED                    115
-# define GOST_R_KEY_PARAMETERS_MISSING                    116
-# define GOST_R_MAC_KEY_NOT_SET                           117
-# define GOST_R_NO_PARAMETERS_SET                         118
-# define GOST_R_NO_PEER_KEY                               119
-# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR  120
-# define GOST_R_PUBLIC_KEY_UNDEFINED                      121
-# define GOST_R_RNG_ERROR                                 122
-# define GOST_R_SIGNATURE_MISMATCH                        123
-# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q            124
-# define GOST_R_UKM_NOT_SET                               125
-# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND            126
-# define GOST_R_UNSUPPORTED_PARAMETER_SET                 127
+# define GOST_R_CIPHER_NOT_FOUND                          103
+# define GOST_R_CTRL_CALL_FAILED                          104
+# define GOST_R_ERROR_COMPUTING_SHARED_KEY                105
+# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO          106
+# define GOST_R_ERROR_POINT_MUL                           107
+# define GOST_R_INCOMPATIBLE_ALGORITHMS                   108
+# define GOST_R_INCOMPATIBLE_PEER_KEY                     109
+# define GOST_R_INVALID_CIPHER_PARAMS                     110
+# define GOST_R_INVALID_CIPHER_PARAM_OID                  111
+# define GOST_R_INVALID_DIGEST_TYPE                       112
+# define GOST_R_INVALID_IV_LENGTH                         113
+# define GOST_R_INVALID_MAC_KEY_LENGTH                    114
+# define GOST_R_INVALID_MAC_KEY_SIZE                      115
+# define GOST_R_INVALID_MAC_PARAMS                        116
+# define GOST_R_INVALID_MAC_SIZE                          117
+# define GOST_R_INVALID_PARAMSET                          118
+# define GOST_R_KEY_IS_NOT_INITIALIZED                    119
+# define GOST_R_KEY_PARAMETERS_MISSING                    120
+# define GOST_R_MAC_KEY_NOT_SET                           121
+# define GOST_R_NO_PARAMETERS_SET                         122
+# define GOST_R_NO_PEER_KEY                               123
+# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR  124
+# define GOST_R_PUBLIC_KEY_UNDEFINED                      125
+# define GOST_R_RNG_ERROR                                 126
+# define GOST_R_SIGNATURE_MISMATCH                        127
+# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q            128
+# define GOST_R_UKM_NOT_SET                               129
+# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND            130
+# define GOST_R_UNSUPPORTED_PARAMETER_SET                 131
 
-# ifdef  __cplusplus
-}
-# endif
 #endif
diff --git a/etalon/gh.dat b/etalon/gh.dat
new file mode 100644 (file)
index 0000000..0fc0f32
Binary files /dev/null and b/etalon/gh.dat differ
diff --git a/etalon/mac.txt b/etalon/mac.txt
new file mode 100644 (file)
index 0000000..c673ac7
--- /dev/null
@@ -0,0 +1,5 @@
+openssl dgst -mac magma-mac -macopt hexkey:ffeeddccbbaa99887766554433221100f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff magma.dat
+154e7210
+
+openssl dgst -mac grasshopper-mac -macopt hexkey:8899aabbccddeeff0011223344556677fedcba98765432100123456789abcdef gh.dat 
+336f4d296059fbe3
diff --git a/etalon/magma.dat b/etalon/magma.dat
new file mode 100644 (file)
index 0000000..12f236b
--- /dev/null
@@ -0,0 +1,2 @@
+\92Þðk<\13
+YÛTÇ\ 4ø\18\9d J\98û.g¨\ 2L\89\12@\9b\17µ~A
\ No newline at end of file
diff --git a/gost.ec b/gost.ec
index 6c2c85e57c0c88a62e0df4f69945f41be87ee66e..7cf8662ac55fb7627c12aa6c23cce9a97b73621b 100644 (file)
--- a/gost.ec
+++ b/gost.ec
@@ -1,5 +1 @@
 L GOST                         e_gost_err.h                    e_gost_err.c
-L NONE                 asymm.h                         NONE
-L NONE                 md.h                            NONE
-L NONE                 crypt.h                         NONE
-L NONE                 gostkeyx.h                      NONE
diff --git a/gost.txt b/gost.txt
new file mode 100644 (file)
index 0000000..4a515f9
--- /dev/null
+++ b/gost.txt
@@ -0,0 +1,89 @@
+# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License").  You may not use
+# this file except in compliance with the License.  You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# Function codes
+GOST_F_DECODE_GOST_ALGOR_PARAMS:100:decode_gost_algor_params
+GOST_F_ENCODE_GOST_ALGOR_PARAMS:101:encode_gost_algor_params
+GOST_F_FILL_GOST_EC_PARAMS:102:fill_GOST_EC_params
+GOST_F_GET_ENCRYPTION_PARAMS:103:get_encryption_params
+GOST_F_GOST89_GET_ASN1_PARAMETERS:104:gost89_get_asn1_parameters
+GOST_F_GOST89_SET_ASN1_PARAMETERS:105:gost89_set_asn1_parameters
+GOST_F_GOST_CIPHER_CTL:106:gost_cipher_ctl
+GOST_F_GOST_EC_COMPUTE_PUBLIC:107:gost_ec_compute_public
+GOST_F_GOST_EC_KEYGEN:108:gost_ec_keygen
+GOST_F_GOST_EC_SIGN:109:gost_ec_sign
+GOST_F_GOST_EC_VERIFY:110:gost_ec_verify
+GOST_F_GOST_GRASSHOPPER_CIPHER_CTL:111:gost_grasshopper_cipher_ctl
+GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS:112:\
+       gost_grasshopper_set_asn1_parameters
+GOST_F_GOST_IMIT_CTRL:113:gost_imit_ctrl
+GOST_F_GOST_IMIT_FINAL:114:gost_imit_final
+GOST_F_GOST_IMIT_UPDATE:115:gost_imit_update
+GOST_F_OMAC_IMIT_CTRL:116:omac_imit_ctrl
+GOST_F_OMAC_IMIT_FINAL:117:omac_imit_final
+GOST_F_OMAC_IMIT_UPDATE:118:omac_imit_update
+GOST_F_OMAC_KEY:138:omac_key
+GOST_F_PARAM_COPY_GOST_EC:119:param_copy_gost_ec
+GOST_F_PKEY_GOST2001_PARAMGEN:120:pkey_gost2001_paramgen
+GOST_F_PKEY_GOST2012_PARAMGEN:121:pkey_gost2012_paramgen
+GOST_F_PKEY_GOST_CTRL:122:pkey_gost_ctrl
+GOST_F_PKEY_GOST_ECCP_DECRYPT:123:pkey_GOST_ECcp_decrypt
+GOST_F_PKEY_GOST_ECCP_ENCRYPT:124:pkey_GOST_ECcp_encrypt
+GOST_F_PKEY_GOST_EC_CTRL_STR_256:125:pkey_gost_ec_ctrl_str_256
+GOST_F_PKEY_GOST_EC_CTRL_STR_512:126:pkey_gost_ec_ctrl_str_512
+GOST_F_PKEY_GOST_EC_DERIVE:127:pkey_gost_ec_derive
+GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT:141:\
+       pkey_gost_grasshopper_mac_signctx_init
+GOST_F_PKEY_GOST_MAC_CTRL:128:pkey_gost_mac_ctrl
+GOST_F_PKEY_GOST_MAC_CTRL_STR:129:pkey_gost_mac_ctrl_str
+GOST_F_PKEY_GOST_MAC_KEYGEN_BASE:130:pkey_gost_mac_keygen_base
+GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT:131:pkey_gost_mac_signctx_init
+GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT:142:pkey_gost_magma_mac_signctx_init
+GOST_F_PKEY_GOST_OMAC_CTRL:139:pkey_gost_omac_ctrl
+GOST_F_PKEY_GOST_OMAC_CTRL_STR:140:pkey_gost_omac_ctrl_str
+GOST_F_PRINT_GOST_EC_PUB:132:print_gost_ec_pub
+GOST_F_PRIV_DECODE_GOST:133:priv_decode_gost
+GOST_F_PUB_DECODE_GOST_EC:134:pub_decode_gost_ec
+GOST_F_PUB_ENCODE_GOST_EC:135:pub_encode_gost_ec
+GOST_F_UNPACK_CP_SIGNATURE:136:unpack_cp_signature
+GOST_F_VKO_COMPUTE_KEY:137:VKO_compute_key
+
+#Reason codes
+GOST_R_BAD_KEY_PARAMETERS_FORMAT:100:bad key parameters format
+GOST_R_BAD_ORDER:132:bad order
+GOST_R_BAD_PKEY_PARAMETERS_FORMAT:101:bad pkey parameters format
+GOST_R_CANNOT_PACK_EPHEMERAL_KEY:102:cannot pack ephemeral key
+GOST_R_CIPHER_NOT_FOUND:103:cipher not found
+GOST_R_CTRL_CALL_FAILED:104:ctrl call failed
+GOST_R_ERROR_COMPUTING_SHARED_KEY:105:error computing shared key
+GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO:106:error parsing key transport info
+GOST_R_ERROR_POINT_MUL:107:error point mul
+GOST_R_INCOMPATIBLE_ALGORITHMS:108:incompatible algorithms
+GOST_R_INCOMPATIBLE_PEER_KEY:109:incompatible peer key
+GOST_R_INVALID_CIPHER_PARAMS:110:invalid cipher params
+GOST_R_INVALID_CIPHER_PARAM_OID:111:invalid cipher param oid
+GOST_R_INVALID_DIGEST_TYPE:112:invalid digest type
+GOST_R_INVALID_IV_LENGTH:113:invalid iv length
+GOST_R_INVALID_MAC_KEY_LENGTH:114:invalid mac key length
+GOST_R_INVALID_MAC_KEY_SIZE:115:invalid mac key size
+GOST_R_INVALID_MAC_PARAMS:116:invalid mac params
+GOST_R_INVALID_MAC_SIZE:117:invalid mac size
+GOST_R_INVALID_PARAMSET:118:invalid paramset
+GOST_R_KEY_IS_NOT_INITIALIZED:119:key is not initialized
+GOST_R_KEY_PARAMETERS_MISSING:120:key parameters missing
+GOST_R_MAC_KEY_NOT_SET:121:mac key not set
+GOST_R_NO_PARAMETERS_SET:122:no parameters set
+GOST_R_NO_PEER_KEY:123:no peer key
+GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR:124:\
+       no private part of non ephemeral keypair
+GOST_R_PUBLIC_KEY_UNDEFINED:125:public key undefined
+GOST_R_RNG_ERROR:126:rng error
+GOST_R_SIGNATURE_MISMATCH:127:signature mismatch
+GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q:128:signature parts greater than q
+GOST_R_UKM_NOT_SET:129:ukm not set
+GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND:130:unsupported cipher ctl command
+GOST_R_UNSUPPORTED_PARAMETER_SET:131:unsupported parameter set
index 47b7ba0227c5aec79e04fac4ffc54d318c00f588..8b1ce067e833660cde55613851bc0294361341d9 100644 (file)
--- a/gost89.c
+++ b/gost89.c
@@ -242,6 +242,13 @@ const byte CryptoProKeyMeshingKey[] = {
     0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B
 };
 
+const byte ACPKM_D_const[] = {
+       0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 
+       0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
+       0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 
+       0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
+};
+
 /* Initialization of gost_ctx subst blocks*/
 static void kboxinit(gost_ctx * c, const gost_subst_block * b)
 {
@@ -438,7 +445,7 @@ void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock,
     gostcrypt(c, inblock, outblock);
 }
 
-/* Set 256 bit  key into context */
+/* Set 256 bit gost89 key into context */
 void gost_key(gost_ctx * c, const byte * k)
 {
     int i, j;
@@ -449,7 +456,18 @@ void gost_key(gost_ctx * c, const byte * k)
     }
 }
 
-/* Retrieve 256-bit key from context */
+/* Set 256 bit Magma key into context */
+void magma_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+3] | (k[j + 2] << 8) | (k[j + 1] << 16) | ((word32) k[j] <<
+                                                         24);
+    }
+}
+
+/* Retrieve 256-bit gost89 key from context */
 void gost_get_key(gost_ctx * c, byte * k)
 {
     int i, j;
@@ -461,6 +479,18 @@ void gost_get_key(gost_ctx * c, byte * k)
     }
 }
 
+/* Retrieve 256-bit magma key from context */
+void magma_get_key(gost_ctx * c, byte * k)
+{
+    int i, j;
+    for (i = 0, j = 0; i < 8; i++, j += 4) {
+        k[j + 3] = (byte) (c->k[i] & 0xFF);
+        k[j + 2] = (byte) ((c->k[i] >> 8) & 0xFF);
+        k[j + 1] = (byte) ((c->k[i] >> 16) & 0xFF);
+        k[j + 0] = (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)
 {
@@ -601,3 +631,86 @@ void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv)
     gostcrypt(ctx, iv, newiv);
     memcpy(iv, newiv, 8);
 }
+
+void acpkm_magma_key_meshing(gost_ctx *ctx)
+{
+    unsigned char newkey[32];
+               int i, j;
+               unsigned char buf[8], keybuf[8];
+
+               for (i = 0; i < 4; i++)
+               {
+                       for (j = 0; j < 8; j++)
+                       {
+                               buf[j] = ACPKM_D_const[8*i + 7-j];
+                       }
+                       gostcrypt(ctx, buf, keybuf);
+                       memcpy(newkey+8*i,   keybuf+4, 4);
+                       memcpy(newkey+8*i+4, keybuf,   4);
+               }
+    /* set new key */
+    gost_key(ctx, newkey);
+}
+
+#ifdef ENABLE_UNIT_TESTS
+#include <stdio.h>
+#include <string.h>
+
+static void hexdump(FILE *f, const char *title, const unsigned char *s, int l)
+{
+    int n = 0;
+
+    fprintf(f, "%s", title);
+    for (; n < l; ++n) {
+        if ((n % 16) == 0)
+            fprintf(f, "\n%04x", n);
+        fprintf(f, " %02x", s[n]);
+    }
+    fprintf(f, "\n");
+}
+
+int main(void)
+{
+       const unsigned char initial_key[] = {
+               0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
+               0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+               0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10,
+               0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF
+       };
+
+       const unsigned char meshed_key[] = {
+               0x86, 0x3E, 0xA0, 0x17, 0x84, 0x2C, 0x3D, 0x37, 
+               0x2B, 0x18, 0xA8, 0x5A, 0x28, 0xE2, 0x31, 0x7D,
+               0x74, 0xBE, 0xFC, 0x10, 0x77, 0x20, 0xDE, 0x0C, 
+               0x9E, 0x8A, 0xB9, 0x74, 0xAB, 0xD0, 0x0C, 0xA0,
+       };
+
+       unsigned char buf[32];
+
+       gost_ctx ctx;
+       kboxinit(&ctx, &Gost28147_TC26ParamSetZ);
+       magma_key(&ctx, initial_key);
+       magma_get_key(&ctx, buf);
+
+       hexdump(stdout, "Initial key", buf, 32);
+
+       acpkm_magma_key_meshing(&ctx);
+       magma_get_key(&ctx, buf);
+       hexdump(stdout, "Meshed key - K2", buf, 32);
+
+       if (memcmp(meshed_key, buf, 32))
+       {
+               fprintf(stderr, "Magma meshing failed");
+       }
+
+       acpkm_magma_key_meshing(&ctx);
+       magma_get_key(&ctx, buf);
+       hexdump(stdout, "Meshed key - K3", buf, 32);
+
+       acpkm_magma_key_meshing(&ctx);
+       magma_get_key(&ctx, buf);
+       hexdump(stdout, "Meshed key - K4", buf, 32);
+
+}
+
+#endif
index 13f35e15953a0c1be50bb8e12e5132ff83030985..59a938fa311cc69a934befbefb93ebee3c6cd625 100644 (file)
--- a/gost89.h
+++ b/gost89.h
@@ -59,6 +59,8 @@ void gostcrypt(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);
+/* Set key into context */
+void magma_key(gost_ctx * ctx, const byte * key);
 /* Get key from context */
 void gost_get_key(gost_ctx * ctx, byte * key);
 /* Set S-blocks into context */
index 58f4df40a01356fd28c66e84838709cd994ea65e..5b93ea6c1cbb7a5622f1af5b32779e5675b63179 100644 (file)
@@ -842,6 +842,30 @@ static int mac_ctrl_gost_12(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     return -2;
 }
 
+static int mac_ctrl_magma(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        if (arg2) {
+            *(int *)arg2 = NID_magma_mac;
+            return 2;
+        }
+    }
+    return -2;
+}
+
+static int mac_ctrl_grasshopper(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
+        if (arg2) {
+            *(int *)arg2 = NID_grasshopper_mac;
+            return 2;
+        }
+    }
+    return -2;
+}
+
 static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
 {
     int nid =
@@ -922,6 +946,14 @@ int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth,
         EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
         EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12);
         break;
+    case NID_magma_mac:
+        EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
+        EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_magma);
+        break;
+    case NID_grasshopper_mac:
+        EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
+        EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_grasshopper);
+        break;
     }
     return 1;
 }
index c7c8caaeaa70b96166f2d9762a7e804f176b98f1..e248305f5441a4585778d1f25f4f0ae9a3ec91a6 100644 (file)
@@ -46,6 +46,14 @@ static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params);
 /* Control function */
 static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
 
+static int magma_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                                const unsigned char *iv, int enc);
+/* Handles block of data in CBC mode */
+static int magma_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                              const unsigned char *in, size_t inl);
+static int magma_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl);
+
 static EVP_CIPHER *_hidden_Gost28147_89_cipher = NULL;
 const EVP_CIPHER *cipher_gost(void)
 {
@@ -187,6 +195,75 @@ const EVP_CIPHER *cipher_gost_cpcnt_12(void)
     return _hidden_gost89_cnt_12;
 }
 
+static EVP_CIPHER *_hidden_magma_ctr = NULL;
+const EVP_CIPHER *cipher_magma_ctr(void)
+{
+    if (_hidden_magma_ctr == NULL
+        && ((_hidden_magma_ctr =
+             EVP_CIPHER_meth_new(NID_magma_ctr, 1 /* block_size */ ,
+                                 32 /* key_size */ )) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(_hidden_magma_ctr, 8)
+            || !EVP_CIPHER_meth_set_flags(_hidden_magma_ctr,
+                                          EVP_CIPH_CTR_MODE |
+                                          EVP_CIPH_NO_PADDING |
+                                          EVP_CIPH_CUSTOM_IV |
+                                          EVP_CIPH_RAND_KEY |
+                                          EVP_CIPH_ALWAYS_CALL_INIT)
+            || !EVP_CIPHER_meth_set_init(_hidden_magma_ctr,
+                                         magma_cipher_init)
+            || !EVP_CIPHER_meth_set_do_cipher(_hidden_magma_ctr,
+                                              magma_cipher_do_ctr)
+            || !EVP_CIPHER_meth_set_cleanup(_hidden_magma_ctr,
+                                            gost_cipher_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_magma_ctr,
+                                                  sizeof(struct
+                                                         ossl_gost_cipher_ctx))
+            || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_magma_ctr,
+                                                    gost89_set_asn1_parameters)
+            || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_magma_ctr,
+                                                    gost89_get_asn1_parameters)
+            || !EVP_CIPHER_meth_set_ctrl(_hidden_magma_ctr,
+                                         gost_cipher_ctl))) {
+        EVP_CIPHER_meth_free(_hidden_magma_ctr);
+        _hidden_magma_ctr = NULL;
+    }
+    return _hidden_magma_ctr;
+}
+
+static EVP_CIPHER *_hidden_magma_cbc = NULL;
+const EVP_CIPHER *cipher_magma_cbc(void)
+{
+    if (_hidden_magma_cbc == NULL
+        && ((_hidden_magma_cbc =
+             EVP_CIPHER_meth_new(NID_magma_cbc, 8 /* block_size */ ,
+                                 32 /* key_size */ )) == NULL
+            || !EVP_CIPHER_meth_set_iv_length(_hidden_magma_cbc, 8)
+            || !EVP_CIPHER_meth_set_flags(_hidden_magma_cbc,
+                                          EVP_CIPH_CBC_MODE |
+                                          EVP_CIPH_CUSTOM_IV |
+                                          EVP_CIPH_RAND_KEY |
+                                          EVP_CIPH_ALWAYS_CALL_INIT)
+            || !EVP_CIPHER_meth_set_init(_hidden_magma_cbc,
+                                         magma_cipher_init)
+            || !EVP_CIPHER_meth_set_do_cipher(_hidden_magma_cbc,
+                                              magma_cipher_do_cbc)
+            || !EVP_CIPHER_meth_set_cleanup(_hidden_magma_cbc,
+                                            gost_cipher_cleanup)
+            || !EVP_CIPHER_meth_set_impl_ctx_size(_hidden_magma_cbc,
+                                                  sizeof(struct
+                                                         ossl_gost_cipher_ctx))
+            || !EVP_CIPHER_meth_set_set_asn1_params(_hidden_magma_cbc,
+                                                    gost89_set_asn1_parameters)
+            || !EVP_CIPHER_meth_set_get_asn1_params(_hidden_magma_cbc,
+                                                    gost89_get_asn1_parameters)
+            || !EVP_CIPHER_meth_set_ctrl(_hidden_magma_cbc,
+                                         gost_cipher_ctl))) {
+        EVP_CIPHER_meth_free(_hidden_magma_cbc);
+        _hidden_magma_cbc = NULL;
+    }
+    return _hidden_magma_cbc;
+}
+
 void cipher_gost_destroy(void)
 {
     EVP_CIPHER_meth_free(_hidden_Gost28147_89_cipher);
@@ -197,6 +274,10 @@ void cipher_gost_destroy(void)
     _hidden_Gost28147_89_cbc = NULL;
     EVP_CIPHER_meth_free(_hidden_gost89_cnt_12);
     _hidden_gost89_cnt_12 = NULL;
+    EVP_CIPHER_meth_free(_hidden_magma_cbc);
+    _hidden_magma_cbc = NULL;
+    EVP_CIPHER_meth_free(_hidden_magma_ctr);
+    _hidden_magma_ctr = NULL;
 }
 
 /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */
@@ -385,6 +466,28 @@ static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx,
     return 1;
 }
 
+static int magma_cipher_init_param(EVP_CIPHER_CTX *ctx,
+                                  const unsigned char *key,
+                                  const unsigned char *iv, int enc,
+                                  int paramNID, int mode)
+{
+    struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    if (EVP_CIPHER_CTX_get_app_data(ctx) == NULL) {
+        if (!gost_cipher_set_param(c, NID_id_tc26_gost_28147_param_Z))
+            return 0;
+        EVP_CIPHER_CTX_set_app_data(ctx, EVP_CIPHER_CTX_get_cipher_data(ctx));
+    }
+    if (key)
+        magma_key(&(c->cctx), key);
+    if (iv) {
+        memcpy((unsigned char *)EVP_CIPHER_CTX_original_iv(ctx), iv,
+               EVP_CIPHER_CTX_iv_length(ctx));
+    }
+    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx),
+           EVP_CIPHER_CTX_original_iv(ctx), EVP_CIPHER_CTX_iv_length(ctx));
+    return 1;
+}
+
 static int gost_cipher_init_cnt(EVP_CIPHER_CTX *ctx,
                                 const unsigned char *key,
                                 const unsigned char *iv,
@@ -434,6 +537,14 @@ int gost_cipher_init_cbc(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                                   EVP_CIPH_CBC_MODE);
 }
 
+/* Initializes EVP_CIPHER_CTX with default values */
+int magma_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+                         const unsigned char *iv, int enc)
+{
+    return magma_cipher_init_param(ctx, key, iv, enc, NID_undef,
+                                  EVP_CIPH_CBC_MODE);
+}
+
 /*
  * Wrapper around gostcrypt function from gost89.c which perform key meshing
  * when nesseccary
@@ -483,7 +594,7 @@ static void gost_cnt_next(void *ctx, unsigned char *iv, unsigned char *buf)
     c->count = c->count % 1024 + 8;
 }
 
-/* GOST encryptoon in CBC mode */
+/* GOST encryption in CBC mode */
 int gost_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
                        const unsigned char *in, size_t inl)
 {
@@ -520,6 +631,114 @@ int gost_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
     return 1;
 }
 
+/* MAGMA encryption in CBC mode */
+int magma_cipher_do_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl)
+{
+    unsigned char b[8];
+               unsigned char d[8];
+    const unsigned char *in_ptr = in;
+    unsigned char *out_ptr = out;
+    int i;
+    struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
+    if (EVP_CIPHER_CTX_encrypting(ctx)) {
+        while (inl > 0) {
+
+            for (i = 0; i < 8; i++) {
+                b[7-i] = iv[i] ^ in_ptr[i];
+            }
+            gostcrypt(&(c->cctx), b, d);
+
+            for (i = 0; i < 8; i++) {
+                out_ptr[7-i] = d[i];
+            }
+            memcpy(iv, out_ptr, 8);
+            out_ptr += 8;
+            in_ptr += 8;
+            inl -= 8;
+        }
+    } else {
+        while (inl > 0) {
+            for (i = 0; i < 8; i++) {
+                d[7-i] = in_ptr[i];
+            }
+            gostdecrypt(&(c->cctx), d, b);
+            for (i = 0; i < 8; i++) {
+                out_ptr[i] = iv[i] ^ b[7-i];
+            }
+            memcpy(iv, in_ptr, 8);
+            out_ptr += 8;
+            in_ptr += 8;
+            inl -= 8;
+        }
+    }
+    return 1;
+}
+
+/* increment counter (64-bit int) by 1 */
+static void ctr64_inc(unsigned char *counter)
+{
+       inc_counter(counter, 8);
+}
+
+/* MAGMA encryption in CTR mode */
+static int magma_cipher_do_ctr(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                       const unsigned char *in, size_t inl)
+{
+    const unsigned char *in_ptr = in;
+    unsigned char *out_ptr = out;
+    size_t i = 0;
+    size_t j;
+    struct ossl_gost_cipher_ctx *c = EVP_CIPHER_CTX_get_cipher_data(ctx);
+    unsigned char *buf = EVP_CIPHER_CTX_buf_noconst(ctx);
+    unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
+    unsigned char b[8];
+/* Process partial blocks */
+    if (EVP_CIPHER_CTX_num(ctx)) {
+        for (j = EVP_CIPHER_CTX_num(ctx), i = 0; j < 8 && i < inl;
+             j++, i++, in_ptr++, out_ptr++) {
+            *out_ptr = buf[7-j] ^ (*in_ptr);
+        }
+        if (j == 8) {
+            EVP_CIPHER_CTX_set_num(ctx, 0);
+        } else {
+            EVP_CIPHER_CTX_set_num(ctx, j);
+            return 1;
+        }
+    }
+
+/* Process full blocks */
+               for (; i + 8 <= inl; i += 8, in_ptr += 8, out_ptr += 8) {
+                       for (j = 0; j < 8; j++) {
+                               b[7-j] = iv[j];
+                       }
+                       gostcrypt(&(c->cctx), b, buf);
+                       for (j = 0; j < 8; j++) {
+                               out_ptr[j] = buf[7-j] ^ in_ptr[j];
+                       }
+                       ctr64_inc(iv);
+               }
+
+/* Process the rest of plaintext */
+    if (i < inl) {
+                       for (j = 0; j < 8; j++) {
+                               b[7-j] = iv[j];
+                       }
+                       gostcrypt(&(c->cctx), iv, buf);
+                       ctr64_inc(iv);
+      for (j = 0; i < inl; j++, i++) {
+         out_ptr[j] = buf[7-j] ^ in_ptr[j];
+      }
+
+      EVP_CIPHER_CTX_set_num(ctx, j);
+    } else {
+       EVP_CIPHER_CTX_set_num(ctx, 0);
+               }
+
+       return 1; 
+}
+
 /* GOST encryption in CFB mode */
 int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
                        const unsigned char *in, size_t inl)
index 517a7da2e6a0d2f95b5dd69373ce0e2783fb0a2b..caedf9afe1f2302214faeea6764d18cd2a96ec2a 100644 (file)
@@ -47,11 +47,13 @@ static int gost_cipher_nids[] = {
         NID_grasshopper_cfb,
         NID_grasshopper_ofb,
         NID_grasshopper_ctr,
+        NID_magma_cbc,
+        NID_magma_ctr,
         0
 };
 
 static int gost_digest_nids(const int** nids) {
-    static int digest_nids[6] = {0, 0, 0, 0, 0, 0};
+    static int digest_nids[8] = {0, 0, 0, 0, 0, 0, 0, 0};
     static int pos = 0;
     static int init = 0;
 
@@ -67,6 +69,12 @@ static int gost_digest_nids(const int** nids) {
             digest_nids[pos++] = EVP_MD_type(md);
         if ((md = imit_gost_cp_12()) != NULL)
             digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = magma_omac()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+        if ((md = grasshopper_omac()) != NULL)
+            digest_nids[pos++] = EVP_MD_type(md);
+
+
         digest_nids[pos] = 0;
         init = 1;
     }
@@ -80,18 +88,22 @@ static int gost_pkey_meth_nids[] = {
         NID_id_GostR3410_2012_256,
         NID_id_GostR3410_2012_512,
         NID_gost_mac_12,
+        NID_magma_mac,
+        NID_grasshopper_mac,
         0
 };
 
 static EVP_PKEY_METHOD* pmeth_GostR3410_2001 = NULL,
         * pmeth_GostR3410_2012_256 = NULL,
         * pmeth_GostR3410_2012_512 = NULL,
-        * pmeth_Gost28147_MAC = NULL, * pmeth_Gost28147_MAC_12 = NULL;
+        * pmeth_Gost28147_MAC = NULL, * pmeth_Gost28147_MAC_12 = NULL,
+        * pmeth_magma_mac = NULL,  * pmeth_grasshopper_mac = NULL;
 
 static EVP_PKEY_ASN1_METHOD* ameth_GostR3410_2001 = NULL,
         * ameth_GostR3410_2012_256 = NULL,
         * ameth_GostR3410_2012_512 = NULL,
-        * ameth_Gost28147_MAC = NULL, * ameth_Gost28147_MAC_12 = NULL;
+        * ameth_Gost28147_MAC = NULL, * ameth_Gost28147_MAC_12 = NULL,
+        * ameth_magma_mac = NULL,  * ameth_grasshopper_mac = NULL;
 
 static int gost_engine_init(ENGINE* e) {
     return 1;
@@ -108,6 +120,8 @@ static int gost_engine_destroy(ENGINE* e) {
 
     imit_gost_cpa_destroy();
     imit_gost_cp_12_destroy();
+    magma_omac_destroy();
+    grasshopper_omac_destroy();
 
     cipher_gost_destroy();
     cipher_gost_grasshopper_destroy();
@@ -119,12 +133,16 @@ static int gost_engine_destroy(ENGINE* e) {
     pmeth_GostR3410_2012_256 = NULL;
     pmeth_GostR3410_2012_512 = NULL;
     pmeth_Gost28147_MAC_12 = NULL;
+    pmeth_magma_mac = NULL;
+    pmeth_grasshopper_mac = NULL;
 
     ameth_GostR3410_2001 = NULL;
     ameth_Gost28147_MAC = NULL;
     ameth_GostR3410_2012_256 = NULL;
     ameth_GostR3410_2012_512 = NULL;
     ameth_Gost28147_MAC_12 = NULL;
+    ameth_magma_mac = NULL;
+    ameth_grasshopper_mac = NULL;
 
        ERR_unload_GOST_strings();
        
@@ -197,6 +215,12 @@ static int bind_gost(ENGINE* e, const char* id) {
                              "GOST-MAC-12",
                              "GOST 28147-89 MAC with 2012 params"))
         goto end;
+    if (!register_ameth_gost(NID_magma_mac, &ameth_magma_mac,
+                             "MAGMA-MAC", "GOST R 34.13-2015 Magma MAC"))
+        goto end;
+    if (!register_ameth_gost(NID_grasshopper_mac, &ameth_grasshopper_mac,
+                             "GRASSHOPPER-MAC", "GOST R 34.13-2015 Grasshopper MAC"))
+        goto end;
 
     if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0))
         goto end;
@@ -212,6 +236,10 @@ static int bind_gost(ENGINE* e, const char* id) {
         goto end;
     if (!register_pmeth_gost(NID_gost_mac_12, &pmeth_Gost28147_MAC_12, 0))
         goto end;
+    if (!register_pmeth_gost(NID_magma_mac, &pmeth_magma_mac, 0))
+        goto end;
+    if (!register_pmeth_gost(NID_grasshopper_mac, &pmeth_grasshopper_mac, 0))
+        goto end;
     if (!ENGINE_register_ciphers(e)
         || !ENGINE_register_digests(e)
         || !ENGINE_register_pkey_meths(e)
@@ -225,11 +253,15 @@ static int bind_gost(ENGINE* e, const char* id) {
         || !EVP_add_cipher(cipher_gost_grasshopper_cfb())
         || !EVP_add_cipher(cipher_gost_grasshopper_ofb())
         || !EVP_add_cipher(cipher_gost_grasshopper_ctr())
+        || !EVP_add_cipher(cipher_magma_cbc())
+        || !EVP_add_cipher(cipher_magma_ctr())
         || !EVP_add_digest(digest_gost())
         || !EVP_add_digest(digest_gost2012_512())
         || !EVP_add_digest(digest_gost2012_256())
         || !EVP_add_digest(imit_gost_cpa())
         || !EVP_add_digest(imit_gost_cp_12())
+        || !EVP_add_digest(magma_omac())
+        || !EVP_add_digest(grasshopper_omac())
             ) {
         goto end;
     }
@@ -263,6 +295,10 @@ static int gost_digests(ENGINE* e, const EVP_MD** digest,
         *digest = digest_gost2012_512();
     } else if (nid == NID_gost_mac_12) {
         *digest = imit_gost_cp_12();
+    } else if (nid == NID_magma_mac) {
+        *digest = magma_omac();
+    } else if (nid == NID_grasshopper_mac) {
+        *digest = grasshopper_omac();
     } else {
         ok = 0;
         *digest = NULL;
@@ -296,6 +332,10 @@ static int gost_ciphers(ENGINE* e, const EVP_CIPHER** cipher,
         *cipher = cipher_gost_grasshopper_ofb();
     } else if (nid == NID_grasshopper_ctr) {
         *cipher = cipher_gost_grasshopper_ctr();
+    } else if (nid == NID_magma_cbc) {
+        *cipher = cipher_magma_cbc();
+    } else if (nid == NID_magma_ctr) {
+        *cipher = cipher_magma_ctr();
     } else {
         ok = 0;
         *cipher = NULL;
@@ -326,6 +366,12 @@ static int gost_pkey_meths(ENGINE* e, EVP_PKEY_METHOD** pmeth,
         case NID_gost_mac_12:
             *pmeth = pmeth_Gost28147_MAC_12;
             return 1;
+        case NID_magma_mac:
+            *pmeth = pmeth_magma_mac;
+            return 1;
+        case NID_grasshopper_mac:
+            *pmeth = pmeth_grasshopper_mac;
+            return 1;
 
         default:;
     }
@@ -357,6 +403,12 @@ static int gost_pkey_asn1_meths(ENGINE* e, EVP_PKEY_ASN1_METHOD** ameth,
         case NID_gost_mac_12:
             *ameth = ameth_Gost28147_MAC_12;
             return 1;
+        case NID_magma_mac:
+            *ameth = ameth_magma_mac;
+            return 1;
+        case NID_grasshopper_mac:
+            *ameth = ameth_grasshopper_mac;
+            return 1;
 
         default:;
     }
index 2cce25176a1e43bf09f273472c9c9444272c612c..da68057e855777371a9ff09c7d20195b0de65c0a 100644 (file)
@@ -17,6 +17,7 @@ extern "C" {
 #include <openssl/err.h>
 #include <string.h>
 
+#include "gost_lcl.h"
 #include "e_gost_err.h"
 
 enum GRASSHOPPER_CIPHER_TYPE {
@@ -279,11 +280,10 @@ int gost_grasshopper_cipher_do_cbc(EVP_CIPHER_CTX* ctx, unsigned char* out,
     return 1;
 }
 
-/* increment counter (128-bit int) by 1 */
-static void ctr128_inc(unsigned char *counter)
+void inc_counter(unsigned char* counter, size_t counter_bytes)
 {
-    unsigned int n = 16;
     unsigned char c;
+    unsigned int n = counter_bytes;
 
     do {
         --n;
@@ -294,6 +294,12 @@ static void ctr128_inc(unsigned char *counter)
     } while (n);
 }
 
+/* increment counter (128-bit int) by 1 */
+static void ctr128_inc(unsigned char *counter)
+{
+       inc_counter(counter, 16);
+}
+
 int gost_grasshopper_cipher_do_ctr(EVP_CIPHER_CTX* ctx, unsigned char* out,
                                           const unsigned char* in, size_t inl) {
     gost_grasshopper_cipher_ctx_ctr* c = (gost_grasshopper_cipher_ctx_ctr*) EVP_CIPHER_CTX_get_cipher_data(ctx);
@@ -541,7 +547,7 @@ int gost_grasshopper_set_asn1_parameters(EVP_CIPHER_CTX* ctx, ASN1_TYPE* params)
 
     if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) {
         OPENSSL_free(buf);
-        GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE);
+        GOSTerr(GOST_F_GOST_GRASSHOPPER_SET_ASN1_PARAMETERS, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     OPENSSL_free(buf);
@@ -564,13 +570,13 @@ int gost_grasshopper_cipher_ctl(EVP_CIPHER_CTX* ctx, int type, int arg, void* pt
     switch (type) {
         case EVP_CTRL_RAND_KEY: {
             if (RAND_bytes((unsigned char*) ptr, EVP_CIPHER_CTX_key_length(ctx)) <= 0) {
-                GOSTerr(GOST_F_GOST_CIPHER_CTL, GOST_R_RNG_ERROR);
+                GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_RNG_ERROR);
                 return -1;
             }
             break;
         }
         default:
-            GOSTerr(GOST_F_GOST_CIPHER_CTL, GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
+            GOSTerr(GOST_F_GOST_GRASSHOPPER_CIPHER_CTL, GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND);
             return -1;
     }
     return 1;
index f9e93dd85347dbbf98404ff73e32c8f865430e6c..bc378f09bbf204cacc2f8247686b101851574cf0 100644 (file)
@@ -179,6 +179,10 @@ EVP_MD *imit_gost_cpa(void);
 void imit_gost_cpa_destroy(void);
 EVP_MD *imit_gost_cp_12(void);
 void imit_gost_cp_12_destroy(void);
+EVP_MD *magma_omac(void);
+void magma_omac_destroy(void);
+EVP_MD *grasshopper_omac(void);
+void grasshopper_omac_destroy(void);
 /* Cipher context used for EVP_CIPHER operation */
 struct ossl_gost_cipher_ctx {
     int paramNID;
@@ -212,7 +216,12 @@ const EVP_CIPHER *cipher_gost();
 const EVP_CIPHER *cipher_gost_cbc();
 const EVP_CIPHER *cipher_gost_cpacnt();
 const EVP_CIPHER *cipher_gost_cpcnt_12();
+const EVP_CIPHER *cipher_magma_cbc();
+const EVP_CIPHER *cipher_magma_ctr();
 void cipher_gost_destroy();
+
+void inc_counter(unsigned char* buffer, size_t buf_len);
+
 # 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_MAC_LEN (EVP_MD_CTRL_ALG_CTRL+5)
diff --git a/gost_omac.c b/gost_omac.c
new file mode 100644 (file)
index 0000000..fa7ab74
--- /dev/null
@@ -0,0 +1,278 @@
+#include <string.h>
+#include <openssl/cmac.h>
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+#include "e_gost_err.h"
+#include "gost_lcl.h"
+
+typedef struct omac_ctx {
+       CMAC_CTX *cmac_ctx;
+       size_t   dgst_size;
+       int      cipher_nid;
+       int      key_set;
+} OMAC_CTX;
+
+#define MAX_GOST_OMAC_SIZE 16
+
+static int omac_init(EVP_MD_CTX *ctx, int cipher_nid)
+{
+    OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+               memset(c, 0, sizeof(OMAC_CTX));
+               c->cipher_nid = cipher_nid;
+               c->key_set    = 0;
+
+               switch(cipher_nid) {
+                       case NID_magma_cbc:
+                               c->dgst_size = 4;
+                       break;
+
+                       case NID_grasshopper_cbc:
+                               c->dgst_size = 8;
+                       break;
+               }
+
+    return 1;
+}
+
+static int magma_imit_init(EVP_MD_CTX *ctx)
+{
+    return omac_init(ctx, NID_magma_cbc);
+}
+
+static int grasshopper_imit_init(EVP_MD_CTX *ctx)
+{
+    return omac_init(ctx, NID_grasshopper_cbc);
+}
+
+static int omac_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+{
+    OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+               if (!c->key_set)
+               {
+        GOSTerr(GOST_F_OMAC_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET);
+        return 0;
+               }
+
+               return CMAC_Update(c->cmac_ctx, data, count);
+}
+
+int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md)
+{
+    OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+               unsigned char mac[MAX_GOST_OMAC_SIZE];
+               size_t mac_size = sizeof(mac);
+
+    if (!c->key_set) {
+        GOSTerr(GOST_F_OMAC_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET);
+        return 0;
+    }
+
+               CMAC_Final(c->cmac_ctx, mac, &mac_size);
+
+    memcpy(md, mac, c->dgst_size);
+    return 1;
+}
+
+int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
+{
+    OMAC_CTX *c_to = EVP_MD_CTX_md_data(to);
+               const OMAC_CTX *c_from = EVP_MD_CTX_md_data(from);
+
+    if (c_from && c_to) {
+                       c_to->dgst_size  = c_from->dgst_size;
+                       c_to->cipher_nid = c_from->cipher_nid;
+                       c_to->key_set    = c_from->key_set;
+    }
+               else
+               {
+                       return 0;
+               }
+               if (c_to->cmac_ctx == c_from->cmac_ctx)
+               {
+                       return 1;
+               }
+               return CMAC_CTX_copy(c_to->cmac_ctx, c_from->cmac_ctx);
+}
+
+/* Clean up imit ctx */
+int omac_imit_cleanup(EVP_MD_CTX *ctx)
+{
+    OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+
+               if (c)
+               {
+                       CMAC_CTX_free(c->cmac_ctx);
+           memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(OMAC_CTX));
+               }
+    return 1;
+}
+
+static int omac_key(OMAC_CTX *c, const EVP_CIPHER *cipher, const unsigned char *key, size_t key_size)
+{
+       int ret = 0;
+
+       c->cmac_ctx = CMAC_CTX_new();
+       if (c->cmac_ctx == NULL)
+       {
+               GOSTerr(GOST_F_OMAC_KEY, ERR_R_MALLOC_FAILURE);
+               return 0;
+       }
+
+       ret = CMAC_Init(c->cmac_ctx, key, key_size, cipher, NULL);
+       if (ret > 0)
+       {
+               c->key_set = 1;
+       }
+       return 1;
+}                                              
+
+int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr)
+{
+    switch (type) {
+    case EVP_MD_CTRL_KEY_LEN:
+        *((unsigned int *)(ptr)) = 32;
+        return 1;
+    case EVP_MD_CTRL_SET_KEY:
+                               {
+                                       OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+                                       const EVP_MD *md = EVP_MD_CTX_md(ctx);
+                                       const EVP_CIPHER *cipher = NULL;
+
+                                       if (c->cipher_nid == NID_undef)
+                                       {
+                                               switch (EVP_MD_nid(md))
+                                               {
+                                                       case NID_magma_mac:
+                                                               c->cipher_nid = NID_magma_cbc;
+                                                               break;
+
+                                                       case NID_grasshopper_mac:
+                                                               c->cipher_nid = NID_grasshopper_cbc;
+                                                               break;
+                                               }
+                                       }
+                                       cipher = EVP_get_cipherbynid(c->cipher_nid);
+
+                                       if (cipher == NULL)
+                                       {
+                                               GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_CIPHER_NOT_FOUND);
+                                       }
+
+                                       if (EVP_MD_meth_get_init(EVP_MD_CTX_md(ctx)) (ctx) <= 0) {
+                                               GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET);
+                                               return 0;
+                                       }
+                                       EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT);
+
+                                       if (c->key_set)
+                                       {
+                                               GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_BAD_ORDER);
+                                               return 0;
+                                       }
+
+                                       if (arg == 0) {
+                                               struct gost_mac_key *key = (struct gost_mac_key *)ptr;
+                                               return omac_key(c, cipher, key->key, 32);
+
+                                       } else if (arg == 32) {
+                                               return omac_key(c, cipher, ptr, 32);
+                                       }
+                                       GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE);
+                                       return 0;
+                               }
+    case EVP_MD_CTRL_MAC_LEN:
+        {
+                                       OMAC_CTX *c = EVP_MD_CTX_md_data(ctx);
+                                       switch (c->cipher_nid)
+                                       {
+                                               case NID_magma_cbc:
+            if (arg < 1 || arg > 8) {
+                GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
+                return 0;
+            }
+            c->dgst_size = arg;
+                                               break;
+                                               case NID_grasshopper_cbc:
+            if (arg < 1 || arg > 16) {
+                GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE);
+                return 0;
+            }
+            c->dgst_size = arg;
+                                               break;
+                                               default:
+                                               return 0;
+                                       }
+          return 1;
+        }
+
+    default:
+        return 0;
+    }
+}
+
+static EVP_MD *_hidden_magma_mac_md = NULL;
+
+EVP_MD *magma_omac(void)
+{
+    if (_hidden_magma_mac_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_magma_mac, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, 4)
+            || !EVP_MD_meth_set_input_blocksize(md, 8)
+            || !EVP_MD_meth_set_app_datasize(md, sizeof(OMAC_CTX))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, magma_imit_init)
+            || !EVP_MD_meth_set_update(md, omac_imit_update)
+            || !EVP_MD_meth_set_final(md, omac_imit_final)
+            || !EVP_MD_meth_set_copy(md, omac_imit_copy)
+            || !EVP_MD_meth_set_cleanup(md, omac_imit_cleanup)
+            || !EVP_MD_meth_set_ctrl(md, omac_imit_ctrl)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+       _hidden_magma_mac_md = md;
+    }
+    return _hidden_magma_mac_md;
+}
+
+void magma_omac_destroy(void)
+{
+    EVP_MD_meth_free(_hidden_magma_mac_md);
+    _hidden_magma_mac_md = NULL;
+}
+
+static EVP_MD *_hidden_grasshopper_mac_md = NULL;
+
+EVP_MD *grasshopper_omac(void)
+{
+    if (_hidden_grasshopper_mac_md == NULL) {
+        EVP_MD *md;
+
+        if ((md = EVP_MD_meth_new(NID_grasshopper_mac, NID_undef)) == NULL
+            || !EVP_MD_meth_set_result_size(md, 4)
+            || !EVP_MD_meth_set_input_blocksize(md, 8)
+            || !EVP_MD_meth_set_app_datasize(md, sizeof(OMAC_CTX))
+            || !EVP_MD_meth_set_flags(md, 0)
+            || !EVP_MD_meth_set_init(md, grasshopper_imit_init)
+            || !EVP_MD_meth_set_update(md, omac_imit_update)
+            || !EVP_MD_meth_set_final(md, omac_imit_final)
+            || !EVP_MD_meth_set_copy(md, omac_imit_copy)
+            || !EVP_MD_meth_set_cleanup(md, omac_imit_cleanup)
+            || !EVP_MD_meth_set_ctrl(md, omac_imit_ctrl)) {
+            EVP_MD_meth_free(md);
+            md = NULL;
+        }
+       _hidden_grasshopper_mac_md = md;
+    }
+    return _hidden_grasshopper_mac_md;
+}
+
+void grasshopper_omac_destroy(void)
+{
+    EVP_MD_meth_free(_hidden_grasshopper_mac_md);
+    _hidden_grasshopper_mac_md = NULL;
+}
+
index ce162f55d3a3e2a2e9783107f556ba2d433ad65d..69080bdc52f689907ea240c1003e9ead0b1538b1 100644 (file)
@@ -283,7 +283,7 @@ static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     EC_KEY *ec = NULL;
 
     if (!data || data->sign_param_nid == NID_undef) {
-        GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
+        GOSTerr(GOST_F_PKEY_GOST2001_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
         return 0;
     }
 
@@ -303,7 +303,7 @@ static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     int result = 0;
 
     if (!data || data->sign_param_nid == NID_undef) {
-        GOSTerr(GOST_F_PKEY_GOST12_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
+        GOSTerr(GOST_F_PKEY_GOST2012_PARAMGEN, GOST_R_NO_PARAMETERS_SET);
         return 0;
     }
 
@@ -492,6 +492,39 @@ static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx)
     return 1;
 }
 
+static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size)
+{
+    struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data));
+    EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+
+    if (!data)
+        return 0;
+    memset(data, 0, sizeof(*data));
+    data->mac_size = mac_size;
+    data->mac_param_nid = NID_undef;
+
+    if (pkey) {
+        struct gost_mac_key *key = EVP_PKEY_get0(pkey);
+        if (key) {
+            data->mac_param_nid = key->mac_param_nid;
+            data->mac_size = key->mac_size;
+        }
+    }
+
+    EVP_PKEY_CTX_set_data(ctx, data);
+    return 1;
+}
+
+static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx)
+{
+       return pkey_gost_omac_init(ctx, 4);
+}
+
+static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx)
+{
+       return pkey_gost_omac_init(ctx, 8);
+}
+
 static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx)
 {
     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
@@ -651,13 +684,147 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx,
     return -2;
 }
 
+static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size)
+{
+    struct gost_mac_pmeth_data *data =
+        (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx);
+
+    switch (type) {
+    case EVP_PKEY_CTRL_MD:
+        {
+            int nid = EVP_MD_type((const EVP_MD *)p2);
+            if (nid != NID_magma_mac && nid != NID_grasshopper_mac) {
+                GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
+                        GOST_R_INVALID_DIGEST_TYPE);
+                return 0;
+            }
+            data->md = (EVP_MD *)p2;
+            return 1;
+        }
+
+    case EVP_PKEY_CTRL_GET_MD:
+        *(const EVP_MD **)p2 = data->md;
+        return 1;
+
+    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_OMAC_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;
+            struct gost_mac_key *key;
+            if (!data->key_set) {
+                EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx);
+                if (!pkey) {
+                    GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
+                            GOST_R_MAC_KEY_NOT_SET);
+                    return 0;
+                }
+                key = EVP_PKEY_get0(pkey);
+                if (!key) {
+                    GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL,
+                            GOST_R_MAC_KEY_NOT_SET);
+                    return 0;
+                }
+                return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+                    (mctx, EVP_MD_CTRL_SET_KEY, 0, key);
+            } else {
+                return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx))
+                    (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key));
+            }
+        }
+    case EVP_PKEY_CTRL_MAC_LEN:
+        {
+            if (p1 < 1 || p1 > max_size) {
+
+                GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE);
+                return 0;
+            }
+            data->mac_size = p1;
+            return 1;
+        }
+    }
+    return -2;
+}
+
+static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+       return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8);
+}
+
+static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+{
+       return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16);
+}
+
+static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx,
+                                  const char *type, const char *value, size_t max_size)
+{
+    if (strcmp(type, key_ctrl_string) == 0) {
+        if (strlen(value) != 32) {
+            GOSTerr(GOST_F_PKEY_GOST_OMAC_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) == 0) {
+        long keylen;
+        int ret;
+        unsigned char *keybuf = string_to_hex(value, &keylen);
+        if (!keybuf || keylen != 32) {
+            GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR,
+                    GOST_R_INVALID_MAC_KEY_LENGTH);
+            OPENSSL_free(keybuf);
+            return 0;
+        }
+        ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf);
+        OPENSSL_free(keybuf);
+        return ret;
+
+    }
+    if (!strcmp(type, maclen_ctrl_string)) {
+        char *endptr;
+        long size = strtol(value, &endptr, 10);
+        if (*endptr != '\0') {
+            GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE);
+            return 0;
+        }
+        return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size);
+    }
+    return -2;
+}
+
+static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx,
+                                  const char *type, const char *value)
+{
+       return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
+}
+
+static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx,
+                                  const char *type, const char *value)
+{
+       return pkey_gost_omac_ctrl_str(ctx, type, value, 8);
+}
+
 static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx,
                                      EVP_PKEY *pkey, int mac_nid)
 {
     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
     struct gost_mac_key *keydata;
     if (!data || !data->key_set) {
-        GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET);
+        GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN_BASE, GOST_R_MAC_KEY_NOT_SET);
         return 0;
     }
     keydata = OPENSSL_malloc(sizeof(struct gost_mac_key));
@@ -680,6 +847,16 @@ static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC);
 }
 
+static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac);
+}
+
+static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
+{
+    return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac);
+}
+
 static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
 {
     struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
@@ -697,6 +874,40 @@ static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
     return 1;
 }
 
+static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+    struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+    if (data == NULL) {
+        pkey_gost_omac_init(ctx, 4);
+    }
+
+    data = EVP_PKEY_CTX_get_data(ctx);
+    if (!data) {
+        GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
+        return 0;
+    }
+
+    return 1;
+}
+
+static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
+{
+    struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx);
+
+    if (data == NULL) {
+        pkey_gost_omac_init(ctx, 8);
+    }
+
+    data = EVP_PKEY_CTX_get_data(ctx);
+    if (!data) {
+        GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET);
+        return 0;
+    }
+
+    return 1;
+}
+
 static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig,
                                  size_t *siglen, EVP_MD_CTX *mctx)
 {
@@ -802,6 +1013,26 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags)
         EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
         EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
         return 1;
+    case NID_magma_mac:
+        EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_magma_mac_ctrl,
+                               pkey_gost_magma_mac_ctrl_str);
+        EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_magma_mac_signctx_init,
+                                  pkey_gost_mac_signctx);
+        EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_magma_mac_keygen);
+        EVP_PKEY_meth_set_init(*pmeth, pkey_gost_magma_mac_init);
+        EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup);
+        EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy);
+        return 1;
+    case NID_grasshopper_mac:
+        EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_grasshopper_mac_ctrl,
+                               pkey_gost_grasshopper_mac_ctrl_str);
+        EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_grasshopper_mac_signctx_init,
+                                  pkey_gost_mac_signctx);
+        EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_grasshopper_mac_keygen);
+        EVP_PKEY_meth_set_init(*pmeth, pkey_gost_grasshopper_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;
     }