From: Dmitry Belyavskiy Date: Thu, 14 Jun 2018 15:14:55 +0000 (+0300) Subject: OMACs implementation. Unfinished. X-Git-Tag: v3.0.0~412^2~13 X-Git-Url: http://www.wagner.pp.ru/gitweb/?p=openssl-gost%2Fengine.git;a=commitdiff_plain;h=14e654cab19089027b00733594480eb03d8c6da5 OMACs implementation. Unfinished. --- 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 $ DESTINATION ${OPENSSL_ENGINES_INSTALL_DIR} OPTIONAL) install(FILES $ $ 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 +#include +#include +#include +#include + +#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; }