{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_GOST_KEXP15, 0), "gost_kexp15"},
{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"},
--- /dev/null
+# 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
--- /dev/null
+#include <string.h>
+#include <openssl/evp.h>
+
+#include "gost_lcl.h"
+#include "e_gost_err.h"
+
+/*
+ * Function expects that out is a preallocated buffer of length
+ * defined as sum of shared_len and mac length defined by mac_nid
+ * */
+int gost_kexp15(const unsigned char *shared_key, const int shared_len,
+ int cipher_nid, const unsigned char *cipher_key, const size_t cipher_key_len,
+ int mac_nid, unsigned char *mac_key, const size_t mac_key_len,
+ const char *iv, const size_t ivlen,
+ unsigned char *out, int *out_len
+)
+{
+ /* out_len = key_len + mac_len */
+ unsigned char iv_full[16], mac_buf[8];
+ unsigned int mac_len;
+
+ EVP_CIPHER_CTX *ciph = NULL;
+ EVP_MD_CTX *mac = NULL;
+
+ int ret = 0;
+
+ /* we expect IV of half length */
+ memset(iv_full, 0, 16);
+ memcpy(iv_full, iv, ivlen);
+
+ mac = EVP_MD_CTX_new();
+ if (mac == NULL) {
+ GOSTerr(GOST_F_GOST_KEXP15, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if(EVP_DigestInit_ex(mac, EVP_get_digestbynid(mac_nid), NULL) <= 0
+ || EVP_MD_CTX_ctrl(mac, EVP_MD_CTRL_SET_KEY, mac_key_len, mac_key) <= 0
+ || EVP_DigestUpdate(mac, shared_key, shared_len) <= 0
+ || EVP_DigestFinal_ex(mac, mac_buf, &mac_len) <= 0) {
+ GOSTerr(GOST_F_GOST_KEXP15, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ ciph = EVP_CIPHER_CTX_new();
+ if (ciph == NULL) {
+ GOSTerr(GOST_F_GOST_KEXP15, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (EVP_CipherInit_ex(ciph, EVP_get_cipherbynid(cipher_nid), NULL, NULL, NULL, 1) <= 0
+ || EVP_CipherInit_ex(ciph, NULL, NULL, cipher_key, iv_full, 1) <= 0
+ || EVP_CipherUpdate(ciph, out, out_len, shared_key, shared_len) <= 0
+ || EVP_CipherFinal_ex(ciph, out, out_len) <= 0) {
+ GOSTerr(GOST_F_GOST_KEXP15, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ memcpy(out + *out_len, mac_buf, mac_len);
+ *out_len += mac_len;
+
+ ret = 1;
+
+ err:
+ EVP_MD_CTX_free(mac);
+ EVP_CIPHER_CTX_free(ciph);
+
+ return ret;
+}
+
+int gost_kimp15(const char *expkey, const size_t expkeylen,
+ int cipher_nid, const char *cipher_key, const size_t cipher_key_len,
+ int mac_nid, const char *mac_key, const size_t mac_key_len,
+ const char *iv, const size_t ivlen,
+ char *shared_key, size_t *shared_len
+)
+{
+ return 0;
+}
+