aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt8
-rw-r--r--e_gost_err.c8
-rw-r--r--e_gost_err.h102
-rw-r--r--gost.txt84
-rw-r--r--gost_ameth.c10
-rw-r--r--gost_eng.c103
-rw-r--r--gost_lcl.h4
-rw-r--r--gost_omac.c258
-rw-r--r--gost_pmeth.c25
9 files changed, 520 insertions, 82 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 295ca76..82c0ac4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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})
@@ -136,4 +142,4 @@ install(FILES gostsum.1 gost12sum.1 DESTINATION ${OPENSSL_MAN_INSTALL_DIR})
if (MSVC)
install(FILES $<TARGET_PDB_FILE:gost_engine> DESTINATION ${OPENSSL_ENGINES_INSTALL_DIR} OPTIONAL)
install(FILES $<TARGET_PDB_FILE:gostsum> $<TARGET_PDB_FILE:gost12sum> DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL)
-endif() \ No newline at end of file
+endif()
diff --git a/e_gost_err.c b/e_gost_err.c
index 9089c4b..4f2c709 100644
--- a/e_gost_err.c
+++ b/e_gost_err.c
@@ -36,8 +36,10 @@ static ERR_STRING_DATA GOST_str_functs[] = {
{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_MAGMA_IMIT_FINAL, 0), "magma_imit_final"},
- {ERR_PACK(0, GOST_F_MAGMA_IMIT_UPDATE, 0), "magma_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"},
@@ -67,10 +69,12 @@ static ERR_STRING_DATA GOST_str_functs[] = {
static ERR_STRING_DATA GOST_str_reasons[] = {
{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"},
diff --git a/e_gost_err.h b/e_gost_err.h
index 9276df1..439ac90 100644
--- a/e_gost_err.h
+++ b/e_gost_err.h
@@ -43,61 +43,65 @@ void ERR_GOST_error(int function, int reason, char *file, int line);
# define GOST_F_GOST_IMIT_CTRL 113
# define GOST_F_GOST_IMIT_FINAL 114
# define GOST_F_GOST_IMIT_UPDATE 115
-# define GOST_F_MAGMA_IMIT_FINAL 116
-# define GOST_F_MAGMA_IMIT_UPDATE 117
-# define GOST_F_PARAM_COPY_GOST_EC 118
-# define GOST_F_PKEY_GOST2001_PARAMGEN 119
-# define GOST_F_PKEY_GOST2012_PARAMGEN 120
-# define GOST_F_PKEY_GOST_CTRL 121
-# define GOST_F_PKEY_GOST_ECCP_DECRYPT 122
-# define GOST_F_PKEY_GOST_ECCP_ENCRYPT 123
-# define GOST_F_PKEY_GOST_EC_CTRL_STR_256 124
-# define GOST_F_PKEY_GOST_EC_CTRL_STR_512 125
-# define GOST_F_PKEY_GOST_EC_DERIVE 126
-# define GOST_F_PKEY_GOST_MAC_CTRL 127
-# define GOST_F_PKEY_GOST_MAC_CTRL_STR 128
-# define GOST_F_PKEY_GOST_MAC_KEYGEN_BASE 129
-# define GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT 130
-# define GOST_F_PRINT_GOST_EC_PUB 131
-# define GOST_F_PRIV_DECODE_GOST 132
-# define GOST_F_PUB_DECODE_GOST_EC 133
-# define GOST_F_PUB_ENCODE_GOST_EC 134
-# define GOST_F_UNPACK_CP_SIGNATURE 135
-# define GOST_F_VKO_COMPUTE_KEY 136
+# 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_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_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
/*
* 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 114
-# define GOST_R_INVALID_MAC_PARAMS 115
-# define GOST_R_INVALID_MAC_SIZE 116
-# define GOST_R_INVALID_PARAMSET 117
-# define GOST_R_KEY_IS_NOT_INITIALIZED 118
-# define GOST_R_KEY_PARAMETERS_MISSING 119
-# define GOST_R_MAC_KEY_NOT_SET 120
-# define GOST_R_NO_PARAMETERS_SET 121
-# define GOST_R_NO_PEER_KEY 122
-# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 123
-# define GOST_R_PUBLIC_KEY_UNDEFINED 124
-# define GOST_R_RNG_ERROR 125
-# define GOST_R_SIGNATURE_MISMATCH 126
-# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127
-# define GOST_R_UKM_NOT_SET 128
-# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129
-# define GOST_R_UNSUPPORTED_PARAMETER_SET 130
+# define GOST_R_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
#endif
diff --git a/gost.txt b/gost.txt
index e69de29..2681911 100644
--- a/gost.txt
+++ b/gost.txt
@@ -0,0 +1,84 @@
+# 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_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_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
diff --git a/gost_ameth.c b/gost_ameth.c
index 05d9cd2..8ce4505 100644
--- a/gost_ameth.c
+++ b/gost_ameth.c
@@ -922,6 +922,16 @@ 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;
+/* TODO
+ case NID_magma_mac:
+ EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
+ EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost);
+ break;
+ case NID_grasshopper_mac:
+ EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost);
+ EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12);
+ break;
+*/
}
return 1;
}
diff --git a/gost_eng.c b/gost_eng.c
index 0a2af55..0cef2fa 100644
--- a/gost_eng.c
+++ b/gost_eng.c
@@ -47,11 +47,12 @@ static int gost_cipher_nids[] = {
NID_grasshopper_cfb,
NID_grasshopper_ofb,
NID_grasshopper_ctr,
+ NID_magma_cbc,
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 +68,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 +87,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;
@@ -102,32 +113,38 @@ static int gost_engine_finish(ENGINE* e) {
}
static int gost_engine_destroy(ENGINE* e) {
- digest_gost_destroy();
- digest_gost2012_256_destroy();
- digest_gost2012_512_destroy();
-
- imit_gost_cpa_destroy();
- imit_gost_cp_12_destroy();
-
- cipher_gost_destroy();
-
- gost_param_free();
-
- pmeth_GostR3410_2001 = NULL;
- pmeth_Gost28147_MAC = NULL;
- pmeth_GostR3410_2012_256 = NULL;
- pmeth_GostR3410_2012_512 = NULL;
- pmeth_Gost28147_MAC_12 = NULL;
-
- ameth_GostR3410_2001 = NULL;
- ameth_Gost28147_MAC = NULL;
- ameth_GostR3410_2012_256 = NULL;
- ameth_GostR3410_2012_512 = NULL;
- ameth_Gost28147_MAC_12 = NULL;
-
- ERR_unload_GOST_strings();
-
- return 1;
+ digest_gost_destroy();
+ digest_gost2012_256_destroy();
+ digest_gost2012_512_destroy();
+
+ imit_gost_cpa_destroy();
+ imit_gost_cp_12_destroy();
+ magma_omac_destroy();
+ grasshopper_omac_destroy();
+
+ cipher_gost_destroy();
+
+ gost_param_free();
+
+ pmeth_GostR3410_2001 = NULL;
+ pmeth_Gost28147_MAC = NULL;
+ 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();
+
+ return 1;
}
static int bind_gost(ENGINE* e, const char* id) {
@@ -196,6 +213,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-OMAC", "GOST R 34.13-2015 Magma MAC"))
+ goto end;
+ if (!register_ameth_gost(NID_grasshopper_mac, &ameth_grasshopper_mac,
+ "GRASSHOPPER-OMAC", "GOST R 34.13-2015 Grasshopper MAC"))
+ goto end;
if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0))
goto end;
@@ -211,6 +234,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)
@@ -263,6 +290,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 +327,8 @@ 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 {
ok = 0;
*cipher = NULL;
@@ -326,6 +359,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 +396,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:;
}
diff --git a/gost_lcl.h b/gost_lcl.h
index 6f3cadc..58ac94d 100644
--- a/gost_lcl.h
+++ b/gost_lcl.h
@@ -178,6 +178,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;
diff --git a/gost_omac.c b/gost_omac.c
new file mode 100644
index 0000000..ad96662
--- /dev/null
+++ b/gost_omac.c
@@ -0,0 +1,258 @@
+#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;
+ }
+ 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_CIPHER *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;
+}
+
diff --git a/gost_pmeth.c b/gost_pmeth.c
index 787b480..a29e5f0 100644
--- a/gost_pmeth.c
+++ b/gost_pmeth.c
@@ -523,7 +523,8 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
case EVP_PKEY_CTRL_MD:
{
int nid = EVP_MD_type((const EVP_MD *)p2);
- if (nid != NID_id_Gost28147_89_MAC && nid != NID_gost_mac_12) {
+ if (nid != NID_id_Gost28147_89_MAC && nid != NID_gost_mac_12
+ && nid != NID_magma_mac && nid != NID_grasshopper_mac) {
GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,
GOST_R_INVALID_DIGEST_TYPE);
return 0;
@@ -802,6 +803,28 @@ 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;
+/* TODO
+ case NID_magma_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_12);
+ 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;
+ case NID_grasshopper_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_12);
+ 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;
}