diff --git a/CMakeLists.txt b/CMakeLists.txt index a6a6dd6da..e6903578d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -162,7 +162,7 @@ set(GOST_ERR_SOURCE_FILES e_gost_err.h ) -set(GOST_LEGACY_CORE_SOURCE_FILES +set(GOST_CORE_SOURCE_FILES gost_ameth.c gost_pmeth.c gost_ctl.c @@ -178,14 +178,9 @@ set(GOST_LEGACY_CORE_SOURCE_FILES gost_lcl.h gost_params.c gost_keyexpimp.c - ) - -set(GOST_NEW_CORE_DIGEST_SOURCE_FILES - gost_digest_3411_2012.c - gost_digest_3411_94.c - gost_digest_base.c gost_digest.c -) + gost_digest_ctx.c + ) set(GOST_EC_SOURCE_FILES gost_ec_keyx.c @@ -206,7 +201,7 @@ set (GOST_OMAC_SOURCE_FILES ) set(GOST_LIB_SOURCE_FILES - ${GOST_LEGACY_CORE_SOURCE_FILES} + ${GOST_CORE_SOURCE_FILES} ${GOST_GRASSHOPPER_SOURCE_FILES} ${GOST_EC_SOURCE_FILES} ${GOST_OMAC_SOURCE_FILES} @@ -214,6 +209,8 @@ set(GOST_LIB_SOURCE_FILES set(GOST_ENGINE_SOURCE_FILES gost_eng.c + gost_eng_digest.c + gost_eng_digest_define.c ) set(GOST_PROV_SOURCE_FILES @@ -418,10 +415,6 @@ add_library(gost_err STATIC ${GOST_ERR_SOURCE_FILES}) set_target_properties(gost_err PROPERTIES POSITION_INDEPENDENT_CODE ON) target_link_libraries(gost_err PRIVATE OpenSSL::Crypto) -add_library(gost_new_core_digest STATIC ${GOST_NEW_CORE_DIGEST_SOURCE_FILES}) -set_target_properties(gost_new_core_digest PROPERTIES POSITION_INDEPENDENT_CODE ON) -target_link_libraries(gost_new_core_digest PRIVATE OpenSSL::Crypto gosthash gosthash2012) - # The GOST engine in module form add_library(gost_engine MODULE ${GOST_ENGINE_SOURCE_FILES}) # Set the suffix explicitly to adapt to OpenSSL's idea of what a @@ -451,7 +444,7 @@ set_target_properties(gost_prov PROPERTIES PREFIX "" OUTPUT_NAME "gostprov" SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX} COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;OPENSSL_NO_DYNAMIC_ENGINE" ) -target_link_libraries(gost_prov PRIVATE gost_core gost_new_core_digest libprov) +target_link_libraries(gost_prov PRIVATE gost_core libprov) if (NOT MSVC) # The GOST provider in library form @@ -462,7 +455,7 @@ set_target_properties(lib_gost_prov PROPERTIES OUTPUT_NAME "gostprov" COMPILE_DEFINITIONS "BUILDING_GOST_PROVIDER;BUILDING_PROVIDER_AS_LIBRARY;OPENSSL_NO_DYNAMIC_ENGINE" ) -target_link_libraries(lib_gost_prov PRIVATE gost_core gost_new_core_digest libprov) +target_link_libraries(lib_gost_prov PRIVATE gost_core libprov) endif() set(GOST_SUM_SOURCE_FILES diff --git a/gost_crypt.c b/gost_crypt.c index dab339d2d..5a5b90c3f 100644 --- a/gost_crypt.c +++ b/gost_crypt.c @@ -16,6 +16,7 @@ #include "gost_lcl.h" #include "gost_gost2015.h" #include "gost_tls12_additional.h" +#include "gost_digest_details.h" #if !defined(CCGOST_DEBUG) && !defined(DEBUG) # ifndef NDEBUG @@ -290,23 +291,20 @@ GOST_cipher magma_cbc_cipher = { /* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ /* Init functions which set specific parameters */ -static int gost_imit_init_cpa(EVP_MD_CTX *ctx); -static int gost_imit_init_cp_12(EVP_MD_CTX *ctx); -/* process block of data */ -static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count); -/* Return computed value */ -static int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md); -/* Copies context */ -static int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); -static int gost_imit_cleanup(EVP_MD_CTX *ctx); -/* Control function, knows how to set MAC key.*/ -static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); - -GOST_digest Gost28147_89_MAC_digest = { +static int gost_imit_init_cpa(GOST_digest_ctx *ctx); +static int gost_imit_init_cp_12(GOST_digest_ctx *ctx); +static int gost_imit_update(GOST_digest_ctx *ctx, const void *data, + size_t count); +static int gost_imit_final(GOST_digest_ctx *ctx, unsigned char *md); +static int gost_imit_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); +static int gost_imit_cleanup(GOST_digest_ctx *ctx); +static int gost_imit_ctrl(GOST_digest_ctx *ctx, int cmd, int p1, void *p2); + +GOST_digest Gost28147_89_mac = { .nid = NID_id_Gost28147_89_MAC, .result_size = 4, .input_blocksize = 8, - .app_datasize = sizeof(struct ossl_gost_imit_ctx), + .algctx_size = sizeof(struct ossl_gost_imit_ctx), .flags = EVP_MD_FLAG_XOF, .init = gost_imit_init_cpa, .update = gost_imit_update, @@ -316,11 +314,11 @@ GOST_digest Gost28147_89_MAC_digest = { .ctrl = gost_imit_ctrl, }; -GOST_digest Gost28147_89_mac_12_digest = { +GOST_digest Gost28147_89_mac_12 = { .nid = NID_gost_mac_12, .result_size = 4, .input_blocksize = 8, - .app_datasize = sizeof(struct ossl_gost_imit_ctx), + .algctx_size = sizeof(struct ossl_gost_imit_ctx), .flags = EVP_MD_FLAG_XOF, .init = gost_imit_init_cp_12, .update = gost_imit_update, @@ -1512,9 +1510,9 @@ static int magma_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) return 1; } -static int gost_imit_init(EVP_MD_CTX *ctx, gost_subst_block * block) +static int gost_imit_init(GOST_digest_ctx *ctx, gost_subst_block * block) { - struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_imit_ctx *c = GOST_digest_ctx_data(ctx); memset(c->buffer, 0, sizeof(c->buffer)); memset(c->partial_block, 0, sizeof(c->partial_block)); c->count = 0; @@ -1525,12 +1523,12 @@ static int gost_imit_init(EVP_MD_CTX *ctx, gost_subst_block * block) return 1; } -static int gost_imit_init_cpa(EVP_MD_CTX *ctx) +static int gost_imit_init_cpa(GOST_digest_ctx *ctx) { return gost_imit_init(ctx, &Gost28147_CryptoProParamSetA); } -static int gost_imit_init_cp_12(EVP_MD_CTX *ctx) +static int gost_imit_init_cp_12(GOST_digest_ctx *ctx) { return gost_imit_init(ctx, &Gost28147_TC26ParamSetZ); } @@ -1551,9 +1549,9 @@ static void mac_block_mesh(struct ossl_gost_imit_ctx *c, c->count = c->count % 1024 + 8; } -static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) +static int gost_imit_update(GOST_digest_ctx *ctx, const void *data, size_t count) { - struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_imit_ctx *c = GOST_digest_ctx_data(ctx); const unsigned char *p = data; size_t bytes = count; if (!(c->key_set)) { @@ -1584,9 +1582,9 @@ static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) return 1; } -static int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md) +static int gost_imit_final(GOST_digest_ctx *ctx, unsigned char *md) { - struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_imit_ctx *c = GOST_digest_ctx_data(ctx); if (!c->key_set) { GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET); return 0; @@ -1607,7 +1605,7 @@ static int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md) return 1; } -static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +static int gost_imit_ctrl(GOST_digest_ctx *ctx, int type, int arg, void *ptr) { switch (type) { case EVP_MD_CTRL_KEY_LEN: @@ -1615,13 +1613,13 @@ static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) return 1; case EVP_MD_CTRL_SET_KEY: { - struct ossl_gost_imit_ctx *gost_imit_ctx = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_imit_ctx *gost_imit_ctx = GOST_digest_ctx_data(ctx); - if (EVP_MD_meth_get_init(EVP_MD_CTX_md(ctx)) (ctx) <= 0) { + if (GOST_digest_meth_get_init(GOST_digest_ctx_digest(ctx))(ctx) <= 0) { GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET); return 0; } - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); + GOST_digest_ctx_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); if (arg == 0) { struct gost_mac_key *key = (struct gost_mac_key *)ptr; @@ -1649,7 +1647,7 @@ static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } case EVP_MD_CTRL_XOF_LEN: { - struct ossl_gost_imit_ctx *c = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_imit_ctx *c = GOST_digest_ctx_data(ctx); if (arg < 1 || arg > 8) { GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE); return 0; @@ -1663,19 +1661,19 @@ static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } } -static int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static int gost_imit_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { - if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) { - memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from), + if (GOST_digest_ctx_data(to) && GOST_digest_ctx_data(from)) { + memcpy(GOST_digest_ctx_data(to), GOST_digest_ctx_data(from), sizeof(struct ossl_gost_imit_ctx)); } return 1; } /* Clean up imit ctx */ -static int gost_imit_cleanup(EVP_MD_CTX *ctx) +static int gost_imit_cleanup(GOST_digest_ctx *ctx) { - memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(struct ossl_gost_imit_ctx)); + OPENSSL_cleanse(GOST_digest_ctx_data(ctx), sizeof(struct ossl_gost_imit_ctx)); return 1; } /* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */ diff --git a/gost_digest.c b/gost_digest.c index 761cbd369..49d0b2edf 100644 --- a/gost_digest.c +++ b/gost_digest.c @@ -1,5 +1,106 @@ #include "gost_digest.h" +#include "gost_digest_details.h" -void* GOST_digest_ctx_data(const GOST_digest_ctx* ctx) { - return ctx->algctx; +#include + +static int default_static_init(const GOST_digest_ctx *ctx) { + return 1; +} + +static int default_static_deinit(const GOST_digest_ctx *ctx) { + return 1; +} + +static int default_init(GOST_digest_ctx *ctx) { + return 1; +} + +static int default_update(GOST_digest_ctx *ctx, const void *data, size_t count) { + return 1; +} + +static int default_final(GOST_digest_ctx *ctx, unsigned char *md) { + return 1; +} + +static int default_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { + return 1; +} + +static int default_cleanup(GOST_digest_ctx *ctx){ + return 1; +} + +static int default_ctrl(GOST_digest_ctx *ctx, int cmd, int p1, void *p2) { + return -2; +} + +#define THIS_OR_BASE(st, field) \ + THIS_OR_BASE_OR_DEFAULT(st, field, 0) + +#define THIS_OR_BASE_OR_DEFAULT(st, field, dflt) ( \ + ((st)->field) ? ((st)->field) : BASE_VAL(st, field, dflt) \ +) + +#define BASE_VAL(st, field, dflt) ( \ + (((st)->base && (st)->base->field) ? (st)->base->field : dflt) \ +) + +const GOST_digest* GOST_digest_init(GOST_digest* d) { + if (d->this) { + return d->this; + } + + d->nid = THIS_OR_BASE(d, nid); + d->result_size = THIS_OR_BASE(d, result_size); + d->input_blocksize = THIS_OR_BASE(d, input_blocksize); + d->flags = THIS_OR_BASE(d, flags); + d->alias = THIS_OR_BASE(d, alias); + + d->algctx_size = THIS_OR_BASE(d, algctx_size); + + d->init = THIS_OR_BASE_OR_DEFAULT(d, init, default_init); + d->update = THIS_OR_BASE_OR_DEFAULT(d, update, default_update); + d->final = THIS_OR_BASE_OR_DEFAULT(d, final, default_final); + d->copy = THIS_OR_BASE_OR_DEFAULT(d, copy, default_copy); + d->cleanup = THIS_OR_BASE_OR_DEFAULT(d, cleanup, default_cleanup); + d->ctrl = THIS_OR_BASE_OR_DEFAULT(d, ctrl, default_ctrl); + + if (d->alias) + EVP_add_digest_alias(OBJ_nid2sn(d->nid), d->alias); + + d->this = d; + + return d; +} + +void GOST_digest_deinit(GOST_digest* d) { + if (!d->this) { + return; + } + + if (d->alias) + EVP_delete_digest_alias(d->alias); + + d->this = NULL; +} + +unsigned long GOST_digest_flags(const GOST_digest* d) { + return d->flags; +} + +int GOST_digest_type(const GOST_digest* d) { + return d->nid; +} + +int GOST_digest_block_size(const GOST_digest* d) { + return d->input_blocksize; +} + +int GOST_digest_size(const GOST_digest* d) { + return d->result_size; +} + +int (*GOST_digest_meth_get_init(const GOST_digest *d))(GOST_digest_ctx *) { + return d->init; } diff --git a/gost_digest.h b/gost_digest.h index 25bba20a9..7ea38be79 100644 --- a/gost_digest.h +++ b/gost_digest.h @@ -3,54 +3,35 @@ #include #include -#include "utils_one_level_inheritance.h" - struct gost_digest_st; typedef struct gost_digest_st GOST_digest; struct gost_digest_ctx_st; typedef struct gost_digest_ctx_st GOST_digest_ctx; -typedef GOST_digest_ctx* (gost_digest_st_new_fn)(const GOST_digest *); -typedef void (gost_digest_st_free_fn)(GOST_digest_ctx *); - -typedef int (gost_digest_st_init_fn)(GOST_digest_ctx *ctx); -typedef int (gost_digest_st_update_fn)(GOST_digest_ctx *ctx, const void *data, size_t count); -typedef int (gost_digest_st_final_fn)(GOST_digest_ctx *ctx, unsigned char *md); -typedef int (gost_digest_st_copy_fn)(GOST_digest_ctx *to, const GOST_digest_ctx *from); -typedef int (gost_digest_st_cleanup_fn)(GOST_digest_ctx *ctx); -typedef int (gost_digest_st_ctrl_fn)(GOST_digest_ctx *ctx, int cmd, int p1, void *p2); - -typedef void (gost_digest_st_static_init_fn)(const GOST_digest *); -typedef void (gost_digest_st_static_deinit_fn)(const GOST_digest *); - -struct gost_digest_st { - DECL_BASE(const struct gost_digest_st); - - DECL_MEMBER(int, nid); - DECL_MEMBER(const char *, alias); - DECL_MEMBER(int, result_size); - DECL_MEMBER(int, input_blocksize); - DECL_MEMBER(int, flags); - DECL_MEMBER(const char *, micalg); - DECL_MEMBER(size_t, algctx_size); - - DECL_MEMBER(gost_digest_st_new_fn *, new); - DECL_MEMBER(gost_digest_st_free_fn *, free); - DECL_MEMBER(gost_digest_st_init_fn *, init); - DECL_MEMBER(gost_digest_st_update_fn *, update); - DECL_MEMBER(gost_digest_st_final_fn *, final); - DECL_MEMBER(gost_digest_st_copy_fn *, copy); - DECL_MEMBER(gost_digest_st_cleanup_fn *, cleanup); - DECL_MEMBER(gost_digest_st_ctrl_fn *, ctrl); - - DECL_MEMBER(gost_digest_st_static_init_fn *, static_init); - DECL_MEMBER(gost_digest_st_static_deinit_fn *, static_deinit); -}; - -struct gost_digest_ctx_st { - const GOST_digest* cls; - void* algctx; -}; +extern size_t GOST_digest_ctx_size; + +// No GOST_digest instance may be used before GOST_digest_init call +const GOST_digest* GOST_digest_init(GOST_digest* digest); +void GOST_digest_deinit(GOST_digest* d); +unsigned long GOST_digest_flags(const GOST_digest* d); +int GOST_digest_type(const GOST_digest* d); +int GOST_digest_block_size(const GOST_digest* d); +int GOST_digest_size(const GOST_digest* d); +int (*GOST_digest_meth_get_init(const GOST_digest *md))(GOST_digest_ctx *ctx); + +GOST_digest_ctx* GOST_digest_ctx_new(); +void GOST_digest_ctx_free(GOST_digest_ctx *ctx); + +int GOST_digest_ctx_init(GOST_digest_ctx *ctx, const GOST_digest *cls); +int GOST_digest_ctx_update(GOST_digest_ctx *ctx, const void *data, size_t count); +int GOST_digest_ctx_final(GOST_digest_ctx *ctx, unsigned char *md); +int GOST_digest_ctx_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); +int GOST_digest_ctx_cleanup(GOST_digest_ctx *ctx); +int GOST_digest_ctx_ctrl(GOST_digest_ctx *ctx, int cmd, int p1, void *p2); +const GOST_digest* GOST_digest_ctx_digest(GOST_digest_ctx *ctx); void* GOST_digest_ctx_data(const GOST_digest_ctx* ctx); +void GOST_digest_ctx_set_flags(GOST_digest_ctx *ctx, unsigned long flags); +void GOST_digest_ctx_reset_flags(GOST_digest_ctx *ctx, unsigned long flags); +int GOST_digest_ctx_test_flags(const GOST_digest_ctx *ctx, unsigned long flags); diff --git a/gost_digest_3411_2012.c b/gost_digest_3411_2012.c deleted file mode 100644 index 1e8af1722..000000000 --- a/gost_digest_3411_2012.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include "gosthash2012.h" -#include "gost_digest_3411_2012.h" -#include "gost_digest_base.h" - -static int gost_digest_init(GOST_digest_ctx *ctx); -static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, - size_t count); -static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md); -static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); -static int gost_digest_cleanup(GOST_digest_ctx *ctx); - -#define INIT_COMMON_MEMBERS() \ - INIT_MEMBER(base, &GostR3411_digest_base), \ - \ - INIT_MEMBER(input_blocksize, 64), \ - INIT_MEMBER(algctx_size, sizeof(gost2012_hash_ctx)), \ - \ - INIT_MEMBER(init, gost_digest_init), \ - INIT_MEMBER(update, gost_digest_update), \ - INIT_MEMBER(final, gost_digest_final), \ - INIT_MEMBER(copy, gost_digest_copy), \ - INIT_MEMBER(cleanup, gost_digest_cleanup) - -const GOST_digest GostR3411_2012_256_digest = { - INIT_MEMBER(nid, NID_id_GostR3411_2012_256), - INIT_MEMBER(alias, "streebog256"), - INIT_MEMBER(micalg, "gostr3411-2012-256"), - INIT_MEMBER(result_size, 32), - - INIT_COMMON_MEMBERS(), -}; - -const GOST_digest GostR3411_2012_512_digest = { - INIT_MEMBER(nid, NID_id_GostR3411_2012_512), - INIT_MEMBER(alias, "streebog512"), - INIT_MEMBER(micalg, "gostr3411-2012-512"), - INIT_MEMBER(result_size, 64), - - INIT_COMMON_MEMBERS(), -}; - -static inline gost2012_hash_ctx* impl_digest_ctx_data(const GOST_digest_ctx *ctx) { - return (gost2012_hash_ctx*)GOST_digest_ctx_data(ctx); -} - -static int gost_digest_init(GOST_digest_ctx *ctx) -{ - init_gost2012_hash_ctx(impl_digest_ctx_data(ctx), 8 * GET_MEMBER(ctx->cls, result_size)); - return 1; -} - -static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count) -{ - gost2012_hash_block(impl_digest_ctx_data(ctx), data, count); - return 1; -} - -static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md) -{ - gost2012_finish_hash(impl_digest_ctx_data(ctx), md); - return 1; -} - -static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) -{ - memcpy(impl_digest_ctx_data(to), impl_digest_ctx_data(from), sizeof(gost2012_hash_ctx)); - - return 1; -} - -static int gost_digest_cleanup(GOST_digest_ctx *ctx) -{ - OPENSSL_cleanse(impl_digest_ctx_data(ctx), sizeof(gost2012_hash_ctx)); - - return 1; -} diff --git a/gost_digest_3411_2012.h b/gost_digest_3411_2012.h deleted file mode 100644 index d1d397955..000000000 --- a/gost_digest_3411_2012.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "gost_digest.h" - -extern const GOST_digest GostR3411_2012_256_digest; -extern const GOST_digest GostR3411_2012_512_digest; diff --git a/gost_digest_3411_94.c b/gost_digest_3411_94.c deleted file mode 100644 index dccf61d2e..000000000 --- a/gost_digest_3411_94.c +++ /dev/null @@ -1,76 +0,0 @@ -#include - -#include - -#include "gost_digest_3411_94.h" -#include "gost_digest_base.h" -#include "gosthash.h" -#include "gost89.h" - -static int gost_digest_init(GOST_digest_ctx *ctx); -static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, - size_t count); -static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md); -static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); -static int gost_digest_cleanup(GOST_digest_ctx *ctx); - -struct ossl_gost_digest_ctx { - gost_hash_ctx dctx; - gost_ctx cctx; -}; - -static inline struct ossl_gost_digest_ctx* impl_digest_ctx_data(const GOST_digest_ctx *ctx) { - return (struct ossl_gost_digest_ctx*)GOST_digest_ctx_data(ctx); -} - -const GOST_digest GostR3411_94_digest = { - INIT_MEMBER(nid, NID_id_GostR3411_94), - INIT_MEMBER(result_size, 32), - INIT_MEMBER(input_blocksize, 32), - INIT_MEMBER(algctx_size, sizeof(struct ossl_gost_digest_ctx)), - - INIT_MEMBER(base, &GostR3411_digest_base), - - INIT_MEMBER(init, gost_digest_init), - INIT_MEMBER(update, gost_digest_update), - INIT_MEMBER(final, gost_digest_final), - INIT_MEMBER(copy, gost_digest_copy), - INIT_MEMBER(cleanup, gost_digest_cleanup), -}; - -static int gost_digest_init(GOST_digest_ctx *ctx) -{ - struct ossl_gost_digest_ctx *c = impl_digest_ctx_data(ctx); - memset(&(c->dctx), 0, sizeof(gost_hash_ctx)); - gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet); - c->dctx.cipher_ctx = &(c->cctx); - return 1; -} - -static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count) -{ - return hash_block(&(impl_digest_ctx_data(ctx)->dctx), data, count); -} - -static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md) -{ - return finish_hash(&(impl_digest_ctx_data(ctx)->dctx), md); -} - -static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) -{ - struct ossl_gost_digest_ctx *md_ctx = impl_digest_ctx_data(to); - if (impl_digest_ctx_data(to) && impl_digest_ctx_data(from)) { - memcpy(impl_digest_ctx_data(to), impl_digest_ctx_data(from), - sizeof(struct ossl_gost_digest_ctx)); - md_ctx->dctx.cipher_ctx = &(md_ctx->cctx); - } - return 1; -} - -static int gost_digest_cleanup(GOST_digest_ctx *ctx) -{ - if (impl_digest_ctx_data(ctx)) - OPENSSL_cleanse(impl_digest_ctx_data(ctx), sizeof(struct ossl_gost_digest_ctx)); - return 1; -} diff --git a/gost_digest_3411_94.h b/gost_digest_3411_94.h deleted file mode 100644 index 494c8e052..000000000 --- a/gost_digest_3411_94.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "gost_digest.h" - -extern const GOST_digest GostR3411_94_digest; diff --git a/gost_digest_base.c b/gost_digest_base.c deleted file mode 100644 index fa4a8824a..000000000 --- a/gost_digest_base.c +++ /dev/null @@ -1,51 +0,0 @@ -#include - -#include "gost_digest_base.h" - -static void gost_digest_static_init(const GOST_digest* d); -static void gost_digest_static_deinit(const GOST_digest* d); - -static GOST_digest_ctx* gost_digest_new(const GOST_digest* d); -static void gost_digest_free(GOST_digest_ctx* vctx); - -const GOST_digest GostR3411_digest_base = { - INIT_MEMBER(static_init, gost_digest_static_init), - INIT_MEMBER(static_deinit, gost_digest_static_deinit), - INIT_MEMBER(new, gost_digest_new), - INIT_MEMBER(free, gost_digest_free), -}; - -static GOST_digest_ctx* gost_digest_new(const GOST_digest *d) -{ - GOST_digest_ctx *ctx = (GOST_digest_ctx*)OPENSSL_zalloc(sizeof(GOST_digest_ctx)); - if (!ctx) - return ctx; - - ctx->cls = d; - ctx->algctx = OPENSSL_zalloc(GET_MEMBER(d, algctx_size)); - if (!ctx->algctx) { - OPENSSL_free(ctx); - ctx = NULL; - } - - return ctx; -} - -void gost_digest_free(GOST_digest_ctx *ctx) -{ - if (!ctx) - return; - - OPENSSL_free(ctx->algctx); - OPENSSL_free(ctx); -} - -static void gost_digest_static_init(const GOST_digest* d) { - if (GET_MEMBER(d, alias)) - EVP_add_digest_alias(OBJ_nid2sn(GET_MEMBER(d, nid)), GET_MEMBER(d, alias)); -} - -static void gost_digest_static_deinit(const GOST_digest* d) { - if (GET_MEMBER(d, alias)) - EVP_delete_digest_alias(GET_MEMBER(d, alias)); -} diff --git a/gost_digest_base.h b/gost_digest_base.h deleted file mode 100644 index 0e2dce2a8..000000000 --- a/gost_digest_base.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "gost_digest.h" - -extern const GOST_digest GostR3411_digest_base; diff --git a/gost_digest_ctx.c b/gost_digest_ctx.c new file mode 100644 index 000000000..e13bb8f0b --- /dev/null +++ b/gost_digest_ctx.c @@ -0,0 +1,162 @@ +#include "gost_digest.h" +#include "gost_digest_details.h" + +#include + +#include + +struct gost_digest_ctx_st { + const GOST_digest* cls; + void* algctx; + unsigned long flags; + void* allocated_self; +}; + +size_t GOST_digest_ctx_size = sizeof(GOST_digest_ctx); + +void* GOST_digest_ctx_data(const GOST_digest_ctx* ctx) { + return ctx->algctx; +} + +void GOST_digest_ctx_set_flags(GOST_digest_ctx *ctx, unsigned long flags) +{ + ctx->flags |= flags; +} + +void GOST_digest_ctx_reset_flags(GOST_digest_ctx *ctx, unsigned long flags) +{ + ctx->flags &= ~flags; +} + +int GOST_digest_ctx_test_flags(const GOST_digest_ctx *ctx, unsigned long flags) +{ + return (ctx->flags & flags); +} + +GOST_digest_ctx* GOST_digest_ctx_new() { + void* buf = OPENSSL_zalloc(sizeof(GOST_digest_ctx)); + if (!buf) { + return NULL; + } + + GOST_digest_ctx* ctx = buf; + ctx->allocated_self = buf; + return ctx; +} + +static bool GOST_digest_ctx_initialized(const GOST_digest_ctx *ctx) { + return ctx && ctx->cls && ctx->algctx; +} + +void GOST_digest_ctx_free(GOST_digest_ctx *ctx) +{ + if (!ctx) + return; + + if (ctx->cls && ctx->algctx) { + ctx->cls->cleanup(ctx); + } + + OPENSSL_free(ctx->algctx); + ctx->algctx = NULL; + + OPENSSL_free(ctx->allocated_self); +} + +int GOST_digest_ctx_init(GOST_digest_ctx *ctx, const GOST_digest *cls) { + if (!ctx) { + return 0; + } + + if (GOST_digest_ctx_test_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT)) { + return 1; + } + + if (ctx->cls && ctx->algctx && !GOST_digest_ctx_cleanup(ctx)) { + return 0; + } + + ctx->cls = cls; + + ctx->algctx = OPENSSL_zalloc(ctx->cls->algctx_size); + if (ctx->cls->algctx_size && !ctx->algctx) { + return 0; + } + + int r = ctx->cls->init(ctx); + if (!r) { + OPENSSL_free(ctx->algctx); + ctx->algctx = NULL; + } + + return r; +} + +int GOST_digest_ctx_update(GOST_digest_ctx *ctx, const void *data, size_t count) { + if (!GOST_digest_ctx_initialized(ctx)) + return 0; + + return ctx->cls->update(ctx, data, count); +} + +int GOST_digest_ctx_final(GOST_digest_ctx *ctx, unsigned char *md) { + if (!GOST_digest_ctx_initialized(ctx)) + return 0; + + return ctx->cls->final(ctx, md); +} + +int GOST_digest_ctx_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { + if (!to || !from || to == from) { + return 0; + } + + if (!GOST_digest_ctx_initialized(from)) { + return 0; + } + + if (GOST_digest_ctx_initialized(to) + && GOST_digest_ctx_data(to) == GOST_digest_ctx_data(from)) { + to->algctx = OPENSSL_zalloc(to->cls->algctx_size); + if (to->cls->algctx_size && !to->algctx) { + return 0; + } + } + + to->flags = 0; + if (!GOST_digest_ctx_init(to, from->cls)) { + return 0; + } + + to->flags = from->flags; + + return to->cls->copy(to, from); +} + +int GOST_digest_ctx_cleanup(GOST_digest_ctx *ctx) { + if (!GOST_digest_ctx_initialized(ctx)) + return 0; + + ctx->flags = 0; + + int r = ctx->cls->cleanup(ctx); + + OPENSSL_free(ctx->algctx); + ctx->algctx = NULL; + + return r; +} + +int GOST_digest_ctx_ctrl(GOST_digest_ctx *ctx, int cmd, int p1, void *p2) { + if (!GOST_digest_ctx_initialized(ctx)) + return 0; + + return ctx->cls->ctrl(ctx, cmd, p1, p2); +} + +const GOST_digest* GOST_digest_ctx_digest(GOST_digest_ctx *ctx) { + if (!GOST_digest_ctx_initialized(ctx)) + return NULL; + + return ctx->cls; +} diff --git a/gost_digest_details.h b/gost_digest_details.h new file mode 100644 index 000000000..f1467dfc0 --- /dev/null +++ b/gost_digest_details.h @@ -0,0 +1,23 @@ +#pragma once + +#include "gost_digest.h" + +struct gost_digest_st { + struct gost_digest_st *base; + struct gost_digest_st *this; + + int nid; + int result_size; + int input_blocksize; + int flags; + const char* alias; + + size_t algctx_size; + + int (*init)(GOST_digest_ctx *ctx); + int (*update)(GOST_digest_ctx *ctx, const void *data, size_t count); + int (*final)(GOST_digest_ctx *ctx, unsigned char *md); + int (*copy)(GOST_digest_ctx *to, const GOST_digest_ctx *from); + int (*cleanup)(GOST_digest_ctx *ctx); + int (*ctrl)(GOST_digest_ctx *ctx, int cmd, int p1, void *p2); +}; diff --git a/gost_eng.c b/gost_eng.c index e02995fb0..df70f6b18 100644 --- a/gost_eng.c +++ b/gost_eng.c @@ -17,6 +17,7 @@ #include "e_gost_err.h" #include "gost_lcl.h" #include "gost-engine.h" +#include "gost_eng_digest.h" #include #include "gost_grasshopper_cipher.h" @@ -72,16 +73,16 @@ static EVP_PKEY_ASN1_METHOD* ameth_GostR3410_2001 = NULL, * ameth_magma_mac = NULL, * ameth_grasshopper_mac = NULL, * ameth_magma_mac_acpkm = NULL, * ameth_grasshopper_mac_acpkm = NULL; -GOST_digest *gost_digest_array[] = { - &GostR3411_94_digest_legacy, - &Gost28147_89_MAC_digest, - &GostR3411_2012_256_digest_legacy, - &GostR3411_2012_512_digest_legacy, - &Gost28147_89_mac_12_digest, - &magma_mac_digest, - &grasshopper_mac_digest, - &kuznyechik_ctracpkm_omac_digest, - &magma_ctracpkm_omac_digest, +GOST_eng_digest *gost_digest_array[] = { + &ENG_DIGEST_NAME(GostR3411_94_digest), + &ENG_DIGEST_NAME(Gost28147_89_mac), + &ENG_DIGEST_NAME(GostR3411_2012_256_digest), + &ENG_DIGEST_NAME(GostR3411_2012_512_digest), + &ENG_DIGEST_NAME(Gost28147_89_mac_12), + &ENG_DIGEST_NAME(magma_omac_mac), + &ENG_DIGEST_NAME(grasshopper_omac_mac), + &ENG_DIGEST_NAME(grasshopper_ctracpkm_mac), + &ENG_DIGEST_NAME(magma_ctracpkm_mac), }; GOST_cipher *gost_cipher_array[] = { @@ -207,13 +208,13 @@ static int gost_digests(ENGINE *e, const EVP_MD **digest, *nids = n; for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) - *n++ = gost_digest_array[i]->nid; + *n++ = GOST_eng_digest_nid(gost_digest_array[i]); return i; } for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) - if (nid == gost_digest_array[i]->nid) { - *digest = GOST_init_digest(gost_digest_array[i]); + if (nid == GOST_eng_digest_nid(gost_digest_array[i])) { + *digest = GOST_eng_digest_init(gost_digest_array[i]); return 1; } *digest = NULL; @@ -305,7 +306,7 @@ static int gost_engine_destroy(ENGINE* e) { int i; for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) - GOST_deinit_digest(gost_digest_array[i]); + GOST_eng_digest_deinit(gost_digest_array[i]); for (i = 0; i < OSSL_NELEM(gost_cipher_array); i++) GOST_deinit_cipher(gost_cipher_array[i]); @@ -456,12 +457,12 @@ int populate_gost_engine(ENGINE* e) { int i; for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) { - const EVP_MD *md = GOST_init_digest(gost_digest_array[i]); + const EVP_MD *md = GOST_eng_digest_init(gost_digest_array[i]); if (!EVP_add_digest(md)) goto end; - assert(EVP_get_digestbynid(gost_digest_array[i]->nid) != NULL); + assert(EVP_get_digestbynid(GOST_eng_digest_nid(gost_digest_array[i])) != NULL); } ret = 1; @@ -485,7 +486,7 @@ static int bind_gost_engine(ENGINE* e) { } for (i = 0; i < OSSL_NELEM(gost_digest_array); i++) { - if (!EVP_add_digest(GOST_init_digest(gost_digest_array[i]))) + if (!EVP_add_digest(GOST_eng_digest_init(gost_digest_array[i]))) goto end; } diff --git a/gost_eng_digest.c b/gost_eng_digest.c new file mode 100644 index 000000000..9237e9393 --- /dev/null +++ b/gost_eng_digest.c @@ -0,0 +1,126 @@ +#include + +#include + +#include "gost_eng_digest.h" +#include "gost_lcl.h" +#include "gost_digest_details.h" + +static int gost_digest_init(EVP_MD_CTX *ctx); +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count); +static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); +static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); +static int gost_digest_cleanup(EVP_MD_CTX *ctx); + +static const GOST_digest* digests[] = { + &GostR3411_94_digest, + &GostR3411_2012_256_digest, + &GostR3411_2012_512_digest, + &Gost28147_89_mac, + &Gost28147_89_mac_12, + &magma_omac_mac, + &grasshopper_omac_mac, + &magma_ctracpkm_mac, + &grasshopper_ctracpkm_mac +}; + +static const GOST_digest* get_digest(int nid) { + size_t i = 0; + for (; i < sizeof(digests)/sizeof(digests[0]); ++i){ + if (digests[i]->nid == nid) { + return digests[i]; + } + } + return NULL; +} + +static int gost_digest_init(EVP_MD_CTX *c) +{ + const EVP_MD *md = EVP_MD_CTX_get0_md(c); + const GOST_digest *d = get_digest(EVP_MD_nid(md)); + GOST_digest_ctx *ctx = (GOST_digest_ctx*)EVP_MD_CTX_md_data(c); + if (GOST_digest_ctx_test_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT)) + return 1; + + return GOST_digest_ctx_init(ctx, d); +} + +static int gost_digest_update(EVP_MD_CTX *c, const void *data, size_t count) +{ + GOST_digest_ctx *ctx = (GOST_digest_ctx*)EVP_MD_CTX_md_data(c); + return GOST_digest_ctx_update(ctx, data, count); +} + +static int gost_digest_final(EVP_MD_CTX *c, unsigned char *md) +{ + GOST_digest_ctx *ctx = (GOST_digest_ctx*)EVP_MD_CTX_md_data(c); + return GOST_digest_ctx_final(ctx, md); +} + +static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + GOST_digest_ctx *to_ctx = EVP_MD_CTX_md_data(to); + GOST_digest_ctx *from_ctx = EVP_MD_CTX_md_data(from); + + if (!to_ctx || !from_ctx) { + return 1; + } + + return GOST_digest_ctx_copy(to_ctx, from_ctx); +} + +static int gost_digest_cleanup(EVP_MD_CTX *c) +{ + GOST_digest_ctx *ctx = (GOST_digest_ctx*)EVP_MD_CTX_md_data(c); + if (!ctx) { + return 0; + } + return GOST_digest_ctx_cleanup(ctx); +} + +EVP_MD *GOST_eng_digest_init_impl(GOST_digest *digest, digest_ctrl_fn* ctrl) +{ + const GOST_digest* d = GOST_digest_init(digest); + EVP_MD *md; + if (!(md = EVP_MD_meth_new(d->nid, NID_undef)) + || !EVP_MD_meth_set_result_size(md, d->result_size) + || !EVP_MD_meth_set_input_blocksize(md, d->input_blocksize) + || !EVP_MD_meth_set_app_datasize(md, GOST_digest_ctx_size) + || !EVP_MD_meth_set_flags(md, d->flags) + || !EVP_MD_meth_set_init(md, gost_digest_init) + || !EVP_MD_meth_set_update(md, gost_digest_update) + || !EVP_MD_meth_set_final(md, gost_digest_final) + || !EVP_MD_meth_set_copy(md, gost_digest_copy) + || !EVP_MD_meth_set_cleanup(md, gost_digest_cleanup) + || !EVP_MD_meth_set_ctrl(md, ctrl)) { + EVP_MD_meth_free(md); + md = NULL; + } + + return md; +} + +EVP_MD *GOST_eng_digest_init(GOST_eng_digest *d) +{ + if (d->md) + return d->md; + + EVP_MD *md = GOST_eng_digest_init_impl(d->digest, d->ctrl); + + d->md = md; + return md; +} + +void GOST_eng_digest_deinit(GOST_eng_digest *d) +{ + GOST_digest_deinit(d->digest); + + EVP_MD_meth_free(d->md); + + d->md = NULL; +} + +int GOST_eng_digest_nid(const GOST_eng_digest *d) { + return GOST_digest_type(d->digest); +} diff --git a/gost_eng_digest.h b/gost_eng_digest.h new file mode 100644 index 000000000..50015729a --- /dev/null +++ b/gost_eng_digest.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include "gost_digest.h" + +typedef int (digest_ctrl_fn)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); + +typedef struct gost_eng_digest_st GOST_eng_digest; +struct gost_eng_digest_st { + GOST_digest *digest; + EVP_MD *md; + digest_ctrl_fn *ctrl; +}; + +EVP_MD *GOST_eng_digest_init(GOST_eng_digest *d); +void GOST_eng_digest_deinit(GOST_eng_digest *d); +int GOST_eng_digest_nid(const GOST_eng_digest *d); + +#define STRCAT_IMPL(prefix, suffix) prefix##suffix +#define STRCAT(prefix, suffix) STRCAT_IMPL(prefix, suffix) +#define ENG_DIGEST_NAME(GOST_DIGEST_NAME) STRCAT(GOST_DIGEST_NAME, _eng_digest) + +extern GOST_eng_digest ENG_DIGEST_NAME(GostR3411_94_digest); +extern GOST_eng_digest ENG_DIGEST_NAME(GostR3411_2012_256_digest); +extern GOST_eng_digest ENG_DIGEST_NAME(GostR3411_2012_512_digest); +extern GOST_eng_digest ENG_DIGEST_NAME(Gost28147_89_mac); +extern GOST_eng_digest ENG_DIGEST_NAME(Gost28147_89_mac_12); +extern GOST_eng_digest ENG_DIGEST_NAME(magma_omac_mac); +extern GOST_eng_digest ENG_DIGEST_NAME(grasshopper_omac_mac); +extern GOST_eng_digest ENG_DIGEST_NAME(magma_ctracpkm_mac); +extern GOST_eng_digest ENG_DIGEST_NAME(grasshopper_ctracpkm_mac); diff --git a/gost_eng_digest_define.c b/gost_eng_digest_define.c new file mode 100644 index 000000000..63f8d550a --- /dev/null +++ b/gost_eng_digest_define.c @@ -0,0 +1,38 @@ +#include "gost_eng_digest.h" +#include "gost_lcl.h" + +#define GOST_DIGEST_NAME GostR3411_94_digest +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME GostR3411_2012_256_digest +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME GostR3411_2012_512_digest +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME Gost28147_89_mac +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME Gost28147_89_mac_12 +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME magma_omac_mac +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME grasshopper_omac_mac +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME magma_ctracpkm_mac +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME + +#define GOST_DIGEST_NAME grasshopper_ctracpkm_mac +#include "gost_eng_digest_define.h" +#undef GOST_DIGEST_NAME diff --git a/gost_eng_digest_define.h b/gost_eng_digest_define.h new file mode 100644 index 000000000..e4791bffa --- /dev/null +++ b/gost_eng_digest_define.h @@ -0,0 +1,31 @@ +#define STRCAT_IMPL(prefix, suffix) prefix##suffix +#define STRCAT(prefix, suffix) STRCAT_IMPL(prefix, suffix) + +int STRCAT(GOST_DIGEST_NAME,_eng_ctrl)(EVP_MD_CTX *c, int cmd, int p1, void *p2) { + GOST_digest_ctx *ctx = c ? (GOST_digest_ctx*)EVP_MD_CTX_md_data(c) : NULL; + GOST_digest_ctx *new_ctx = NULL; + int r = 0; + + if (!ctx) { + new_ctx = GOST_digest_ctx_new(); + ctx = new_ctx; + } + + if (!GOST_digest_ctx_digest(ctx) && !GOST_digest_ctx_init(ctx, &GOST_DIGEST_NAME)) { + goto exit; + } + + r = GOST_digest_ctx_ctrl(ctx, cmd, p1, p2); + +exit: + GOST_digest_ctx_free(new_ctx); + return r; +} + +GOST_eng_digest ENG_DIGEST_NAME(GOST_DIGEST_NAME) = { + .digest = &GOST_DIGEST_NAME, + .ctrl = STRCAT(GOST_DIGEST_NAME,_eng_ctrl) +}; + +#undef STRCAT_IMPL +#undef STRCAT diff --git a/gost_lcl.h b/gost_lcl.h index 246eaf350..f53982076 100644 --- a/gost_lcl.h +++ b/gost_lcl.h @@ -20,7 +20,7 @@ # include # include "gost89.h" # include "gosthash.h" -# include "gost_mac.h" +# include "gost_digest.h" /* * This definitions are added in the patch to OpenSSL 3.4.2 version to support @@ -357,28 +357,6 @@ extern GOST_cipher grasshopper_ctr_acpkm_omac_cipher; extern GOST_cipher magma_kexp15_cipher; extern GOST_cipher kuznyechik_kexp15_cipher; - -struct gost_digest_st { - struct gost_digest_st *template; - int nid; - const char *alias; - EVP_MD *digest; - int result_size; - int input_blocksize; - int app_datasize; - int flags; - int (*init)(EVP_MD_CTX *ctx); - int (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); - int (*final)(EVP_MD_CTX *ctx, unsigned char *md); - int (*copy)(EVP_MD_CTX *to, const EVP_MD_CTX *from); - int (*cleanup)(EVP_MD_CTX *ctx); - int (*ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); -}; -typedef struct gost_digest_st GOST_digest; - -EVP_MD *GOST_init_digest(GOST_digest *d); -void GOST_deinit_digest(GOST_digest *d); - /* Internal functions */ EC_KEY * internal_ec_paramgen(int sign_param_nid); int internal_ec_ctrl(struct gost_pmeth_data *pctx, int pkey_nid, @@ -414,16 +392,15 @@ int internal_print_gost_priv(BIO *out, const EC_KEY *ec, int indent, int pkey_ni int internal_print_gost_ec_pub(BIO *out, const EC_KEY *ec, int indent, int pkey_nid); int internal_print_gost_ec_param(BIO *out, const EC_KEY *ec, int indent); -/* ENGINE implementation data */ -extern GOST_digest GostR3411_94_digest_legacy; -extern GOST_digest Gost28147_89_MAC_digest; -extern GOST_digest Gost28147_89_mac_12_digest; -extern GOST_digest GostR3411_2012_256_digest_legacy; -extern GOST_digest GostR3411_2012_512_digest_legacy; -extern GOST_digest magma_mac_digest; -extern GOST_digest grasshopper_mac_digest; -extern GOST_digest kuznyechik_ctracpkm_omac_digest; -extern GOST_digest magma_ctracpkm_omac_digest; +extern GOST_digest GostR3411_94_digest; +extern GOST_digest Gost28147_89_mac; +extern GOST_digest Gost28147_89_mac_12; +extern GOST_digest GostR3411_2012_256_digest; +extern GOST_digest GostR3411_2012_512_digest; +extern GOST_digest magma_omac_mac; +extern GOST_digest grasshopper_omac_mac; +extern GOST_digest grasshopper_ctracpkm_mac; +extern GOST_digest magma_ctracpkm_mac; /* job to initialize a missing NID */ diff --git a/gost_mac.h b/gost_mac.h deleted file mode 100644 index 1a0afa7e3..000000000 --- a/gost_mac.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include - -#define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) -#define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) \ No newline at end of file diff --git a/gost_md.c b/gost_md.c index e6690133e..44d87f2ef 100644 --- a/gost_md.c +++ b/gost_md.c @@ -11,109 +11,67 @@ #include "gost_lcl.h" #include "gosthash.h" #include "e_gost_err.h" +#include "gost_digest_details.h" /* implementation of GOST 34.11 hash function See gost_md.c*/ -static int gost_digest_init(EVP_MD_CTX *ctx); -static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, +static int gost_digest_init(GOST_digest_ctx *ctx); +static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count); -static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); -static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); -static int gost_digest_cleanup(EVP_MD_CTX *ctx); +static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md); +static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); +static int gost_digest_cleanup(GOST_digest_ctx *ctx); -GOST_digest GostR3411_94_digest_legacy = { +GOST_digest GostR3411_94_digest = { .nid = NID_id_GostR3411_94, .result_size = 32, .input_blocksize = 32, - .app_datasize = sizeof(struct ossl_gost_digest_ctx), + .algctx_size = sizeof(struct ossl_gost_digest_ctx), + .init = gost_digest_init, .update = gost_digest_update, .final = gost_digest_final, .copy = gost_digest_copy, - .cleanup = gost_digest_cleanup, + .cleanup = gost_digest_cleanup }; -/* - * Single level template accessor. - * Note: that you cannot template 0 value. - */ -#define TPL(st,field) ( \ - ((st)->field) ? ((st)->field) : TPL_VAL(st,field) \ -) - -#define TPL_VAL(st,field) ( \ - ((st)->template ? (st)->template->field : 0) \ -) - -EVP_MD *GOST_init_digest(GOST_digest *d) -{ - if (d->digest) - return d->digest; - - EVP_MD *md; - if (!(md = EVP_MD_meth_new(d->nid, NID_undef)) - || !EVP_MD_meth_set_result_size(md, TPL(d, result_size)) - || !EVP_MD_meth_set_input_blocksize(md, TPL(d, input_blocksize)) - || !EVP_MD_meth_set_app_datasize(md, TPL(d, app_datasize)) - || !EVP_MD_meth_set_flags(md, d->flags | TPL_VAL(d, flags)) - || !EVP_MD_meth_set_init(md, TPL(d, init)) - || !EVP_MD_meth_set_update(md, TPL(d, update)) - || !EVP_MD_meth_set_final(md, TPL(d, final)) - || !EVP_MD_meth_set_copy(md, TPL(d, copy)) - || !EVP_MD_meth_set_cleanup(md, TPL(d, cleanup)) - || !EVP_MD_meth_set_ctrl(md, TPL(d, ctrl))) { - EVP_MD_meth_free(md); - md = NULL; - } - if (md && d->alias) - EVP_add_digest_alias(EVP_MD_name(md), d->alias); - d->digest = md; - return md; +static inline struct ossl_gost_digest_ctx* impl_digest_ctx_data(const GOST_digest_ctx *ctx) { + return (struct ossl_gost_digest_ctx*)GOST_digest_ctx_data(ctx); } -void GOST_deinit_digest(GOST_digest *d) +static int gost_digest_init(GOST_digest_ctx *ctx) { - if (d->alias) - EVP_delete_digest_alias(d->alias); - EVP_MD_meth_free(d->digest); - d->digest = NULL; -} - -static int gost_digest_init(EVP_MD_CTX *ctx) -{ - struct ossl_gost_digest_ctx *c = EVP_MD_CTX_md_data(ctx); + struct ossl_gost_digest_ctx *c = impl_digest_ctx_data(ctx); memset(&(c->dctx), 0, sizeof(gost_hash_ctx)); gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet); c->dctx.cipher_ctx = &(c->cctx); return 1; } -static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) +static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count) { - return hash_block((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), data, count); + return hash_block(&(impl_digest_ctx_data(ctx)->dctx), data, count); } -static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md) { - return finish_hash((gost_hash_ctx *) EVP_MD_CTX_md_data(ctx), md); - + return finish_hash(&(impl_digest_ctx_data(ctx)->dctx), md); } -static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { - struct ossl_gost_digest_ctx *md_ctx = EVP_MD_CTX_md_data(to); - if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) { - memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from), + struct ossl_gost_digest_ctx *md_ctx = impl_digest_ctx_data(to); + if (impl_digest_ctx_data(to) && impl_digest_ctx_data(from)) { + memcpy(impl_digest_ctx_data(to), impl_digest_ctx_data(from), sizeof(struct ossl_gost_digest_ctx)); md_ctx->dctx.cipher_ctx = &(md_ctx->cctx); } return 1; } -static int gost_digest_cleanup(EVP_MD_CTX *ctx) +static int gost_digest_cleanup(GOST_digest_ctx *ctx) { - if (EVP_MD_CTX_md_data(ctx)) - memset(EVP_MD_CTX_md_data(ctx), 0, - sizeof(struct ossl_gost_digest_ctx)); + if (impl_digest_ctx_data(ctx)) + OPENSSL_cleanse(impl_digest_ctx_data(ctx), sizeof(struct ossl_gost_digest_ctx)); return 1; } /* vim: set expandtab cinoptions=\:0,l1,t0,g0,(0 sw=4 : */ diff --git a/gost_md2012.c b/gost_md2012.c index 3d7a52a09..7b49845c8 100644 --- a/gost_md2012.c +++ b/gost_md2012.c @@ -13,17 +13,18 @@ #include #include "gosthash2012.h" #include "gost_lcl.h" +#include "gost_digest_details.h" -static int gost_digest_init512(EVP_MD_CTX *ctx); -static int gost_digest_init256(EVP_MD_CTX *ctx); -static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, +static int gost_digest_init256(GOST_digest_ctx *ctx); +static int gost_digest_init512(GOST_digest_ctx *ctx); +static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count); -static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); -static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); -static int gost_digest_cleanup(EVP_MD_CTX *ctx); -static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, +static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md); +static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from); +static int gost_digest_cleanup(GOST_digest_ctx *ctx); +static int gost_digest_ctrl_256(GOST_digest_ctx *ctx, int type, int arg, void *ptr); -static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, +static int gost_digest_ctrl_512(GOST_digest_ctx *ctx, int type, int arg, void *ptr); const char micalg_256[] = "gostr3411-2012-256"; @@ -31,76 +32,76 @@ const char micalg_512[] = "gostr3411-2012-512"; GOST_digest GostR3411_2012_template_digest = { .input_blocksize = 64, - .app_datasize = sizeof(gost2012_hash_ctx), + .algctx_size = sizeof(gost2012_hash_ctx), .update = gost_digest_update, .final = gost_digest_final, .copy = gost_digest_copy, .cleanup = gost_digest_cleanup, }; -GOST_digest GostR3411_2012_256_digest_legacy = { +GOST_digest GostR3411_2012_256_digest = { .nid = NID_id_GostR3411_2012_256, .alias = "streebog256", - .template = &GostR3411_2012_template_digest, + .base = &GostR3411_2012_template_digest, .result_size = 32, .init = gost_digest_init256, .ctrl = gost_digest_ctrl_256, }; -GOST_digest GostR3411_2012_512_digest_legacy = { +GOST_digest GostR3411_2012_512_digest = { .nid = NID_id_GostR3411_2012_512, .alias = "streebog512", - .template = &GostR3411_2012_template_digest, + .base = &GostR3411_2012_template_digest, .result_size = 64, .init = gost_digest_init512, .ctrl = gost_digest_ctrl_512, }; -static int gost_digest_init512(EVP_MD_CTX *ctx) +static int gost_digest_init512(GOST_digest_ctx *ctx) { - init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), + init_gost2012_hash_ctx((gost2012_hash_ctx *) GOST_digest_ctx_data(ctx), 512); return 1; } -static int gost_digest_init256(EVP_MD_CTX *ctx) +static int gost_digest_init256(GOST_digest_ctx *ctx) { - init_gost2012_hash_ctx((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), + init_gost2012_hash_ctx((gost2012_hash_ctx *) GOST_digest_ctx_data(ctx), 256); return 1; } -static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) +static int gost_digest_update(GOST_digest_ctx *ctx, const void *data, size_t count) { - gost2012_hash_block((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), data, + gost2012_hash_block((gost2012_hash_ctx *) GOST_digest_ctx_data(ctx), data, count); return 1; } -static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +static int gost_digest_final(GOST_digest_ctx *ctx, unsigned char *md) { - gost2012_finish_hash((gost2012_hash_ctx *) EVP_MD_CTX_md_data(ctx), md); + gost2012_finish_hash((gost2012_hash_ctx *) GOST_digest_ctx_data(ctx), md); return 1; } -static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static int gost_digest_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { - if (EVP_MD_CTX_md_data(to) && EVP_MD_CTX_md_data(from)) - memcpy(EVP_MD_CTX_md_data(to), EVP_MD_CTX_md_data(from), + if (GOST_digest_ctx_data(to) && GOST_digest_ctx_data(from)) + memcpy(GOST_digest_ctx_data(to), GOST_digest_ctx_data(from), sizeof(gost2012_hash_ctx)); return 1; } -static int gost_digest_cleanup(EVP_MD_CTX *ctx) +static int gost_digest_cleanup(GOST_digest_ctx *ctx) { - if (EVP_MD_CTX_md_data(ctx)) - memset(EVP_MD_CTX_md_data(ctx), 0x00, sizeof(gost2012_hash_ctx)); + if (GOST_digest_ctx_data(ctx)) + memset(GOST_digest_ctx_data(ctx), 0x00, sizeof(gost2012_hash_ctx)); return 1; } -static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +static int gost_digest_ctrl_256(GOST_digest_ctx *ctx, int type, int arg, void *ptr) { switch (type) { case EVP_MD_CTRL_MICALG: @@ -117,7 +118,7 @@ static int gost_digest_ctrl_256(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } } -static int gost_digest_ctrl_512(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +static int gost_digest_ctrl_512(GOST_digest_ctx *ctx, int type, int arg, void *ptr) { switch (type) { case EVP_MD_CTRL_MICALG: diff --git a/gost_omac.c b/gost_omac.c index c3a3ddcbc..2f259b5c4 100644 --- a/gost_omac.c +++ b/gost_omac.c @@ -14,6 +14,7 @@ #include "e_gost_err.h" #include "gost_lcl.h" #include "gost_tls12_additional.h" +#include "gost_digest_details.h" #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -39,9 +40,13 @@ typedef struct omac_ctx { #define MAX_GOST_OMAC_SIZE 16 -static int omac_init(EVP_MD_CTX *ctx, const char *cipher_name) +static int omac_init(GOST_digest_ctx *ctx, const char *cipher_name) { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); + if (c == NULL) { + return 0; + } + memset(c, 0, sizeof(OMAC_CTX)); c->cipher_name = cipher_name; c->key_set = 0; @@ -59,19 +64,19 @@ static int omac_init(EVP_MD_CTX *ctx, const char *cipher_name) return 1; } -static int magma_imit_init(EVP_MD_CTX *ctx) +static int magma_imit_init(GOST_digest_ctx *ctx) { return omac_init(ctx, SN_magma_cbc); } -static int grasshopper_imit_init(EVP_MD_CTX *ctx) +static int grasshopper_imit_init(GOST_digest_ctx *ctx) { return omac_init(ctx, SN_grasshopper_cbc); } -static int omac_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) +static int omac_imit_update(GOST_digest_ctx *ctx, const void *data, size_t count) { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); if (!c->key_set) { GOSTerr(GOST_F_OMAC_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET); return 0; @@ -80,9 +85,9 @@ static int omac_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) return CMAC_Update(c->cmac_ctx, data, count); } -static int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md) +static int omac_imit_final(GOST_digest_ctx *ctx, unsigned char *md) { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); unsigned char mac[MAX_GOST_OMAC_SIZE]; size_t mac_size = sizeof(mac); @@ -97,10 +102,10 @@ static int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md) return 1; } -static int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static int omac_imit_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { - OMAC_CTX *c_to = EVP_MD_CTX_md_data(to); - const OMAC_CTX *c_from = EVP_MD_CTX_md_data(from); + OMAC_CTX *c_to = GOST_digest_ctx_data(to); + const OMAC_CTX *c_from = GOST_digest_ctx_data(from); if (c_from && c_to) { c_to->dgst_size = c_from->dgst_size; @@ -117,20 +122,23 @@ static int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) } return 1; } - if (c_to->cmac_ctx == c_from->cmac_ctx) { + if (c_to->cmac_ctx == c_from->cmac_ctx || !c_to->cmac_ctx) { c_to->cmac_ctx = CMAC_CTX_new(); } + if (!c_to->cmac_ctx) { + return 0; + } return CMAC_CTX_copy(c_to->cmac_ctx, c_from->cmac_ctx); } /* Clean up imit ctx */ -static int omac_imit_cleanup(EVP_MD_CTX *ctx) +static int omac_imit_cleanup(GOST_digest_ctx *ctx) { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); if (c) { CMAC_CTX_free(c->cmac_ctx); - memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(OMAC_CTX)); + memset(GOST_digest_ctx_data(ctx), 0, sizeof(OMAC_CTX)); } return 1; } @@ -154,8 +162,7 @@ static int omac_key(OMAC_CTX * c, const EVP_CIPHER *cipher, return 1; } -/* Called directly by gost_kexp15() */ -int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +static int omac_imit_ctrl(GOST_digest_ctx *ctx, int type, int arg, void *ptr) { switch (type) { case EVP_MD_CTRL_KEY_LEN: @@ -163,31 +170,34 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) 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); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); EVP_CIPHER *cipher = NULL; int ret = 0; - - if (c->cipher_name == NULL) { - if (EVP_MD_is_a(md, SN_magma_mac)) - c->cipher_name = SN_magma_cbc; - else if (EVP_MD_is_a(md, SN_grasshopper_mac)) - c->cipher_name = SN_grasshopper_cbc; + const char* cipher_name = NULL; + + if (!c || c->cipher_name == NULL) { + if (GOST_digest_type(GOST_digest_ctx_digest(ctx)) == NID_magma_mac) + cipher_name = SN_magma_cbc; + else if (GOST_digest_type(GOST_digest_ctx_digest(ctx)) == NID_grasshopper_mac) + cipher_name = SN_grasshopper_cbc; + } else { + cipher_name = c->cipher_name; } if ((cipher = - (EVP_CIPHER *)EVP_get_cipherbyname(c->cipher_name)) == NULL + (EVP_CIPHER *)EVP_get_cipherbyname(cipher_name)) == NULL && (cipher = - EVP_CIPHER_fetch(NULL, c->cipher_name, NULL)) == NULL) { + EVP_CIPHER_fetch(NULL, cipher_name, NULL)) == NULL) { GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_CIPHER_NOT_FOUND); goto set_key_end; } - if (EVP_MD_meth_get_init(EVP_MD_CTX_md(ctx)) (ctx) <= 0) { + if (GOST_digest_meth_get_init(GOST_digest_ctx_digest(ctx))(ctx) <= 0) { GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET); goto set_key_end; } - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); + GOST_digest_ctx_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); + c = GOST_digest_ctx_data(ctx); if (c->key_set) { GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_BAD_ORDER); goto set_key_end; @@ -214,7 +224,7 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } case EVP_MD_CTRL_XOF_LEN: /* Supported in OpenSSL */ { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); switch (OBJ_txt2nid(c->cipher_name)) { case NID_magma_cbc: if (arg < 1 || arg > 8) { @@ -238,7 +248,7 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) #ifdef EVP_MD_CTRL_TLSTREE case EVP_MD_CTRL_TLSTREE: { - OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_CTX *c = GOST_digest_ctx_data(ctx); if (c->key_set) { unsigned char diversed_key[32]; int ret = 0; @@ -279,7 +289,7 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) static GOST_digest omac_template_digest = { .input_blocksize = 8, - .app_datasize = sizeof(OMAC_CTX), + .algctx_size = sizeof(OMAC_CTX), .flags = EVP_MD_FLAG_XOF, .update = omac_imit_update, .final = omac_imit_final, @@ -288,16 +298,16 @@ static GOST_digest omac_template_digest = { .ctrl = omac_imit_ctrl, }; -GOST_digest magma_mac_digest = { +GOST_digest magma_omac_mac = { .nid = NID_magma_mac, - .template = &omac_template_digest, + .base = &omac_template_digest, .result_size = 8, .init = magma_imit_init, }; -GOST_digest grasshopper_mac_digest = { +GOST_digest grasshopper_omac_mac = { .nid = NID_grasshopper_mac, - .template = &omac_template_digest, + .base = &omac_template_digest, .result_size = 16, .init = grasshopper_imit_init, }; diff --git a/gost_omac_acpkm.c b/gost_omac_acpkm.c index 442e0727c..f7fb223f8 100644 --- a/gost_omac_acpkm.c +++ b/gost_omac_acpkm.c @@ -13,6 +13,7 @@ #include "e_gost_err.h" #include "gost_lcl.h" +#include "gost_digest_details.h" #define ACPKM_T_MAX (EVP_MAX_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH) @@ -341,9 +342,9 @@ typedef struct omac_acpkm_ctx { #define MAX_GOST_OMAC_ACPKM_SIZE 16 -static int omac_acpkm_init(EVP_MD_CTX *ctx, const char *cipher_name) +static int omac_acpkm_init(GOST_digest_ctx *ctx, const char *cipher_name) { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); memset(c, 0, sizeof(OMAC_ACPKM_CTX)); c->cipher_name = cipher_name; c->key_set = 0; @@ -360,20 +361,20 @@ static int omac_acpkm_init(EVP_MD_CTX *ctx, const char *cipher_name) return 1; } -static int grasshopper_omac_acpkm_init(EVP_MD_CTX *ctx) +static int grasshopper_omac_acpkm_init(GOST_digest_ctx *ctx) { return omac_acpkm_init(ctx, SN_grasshopper_cbc); } -static int magma_omac_acpkm_init(EVP_MD_CTX *ctx) +static int magma_omac_acpkm_init(GOST_digest_ctx *ctx) { return omac_acpkm_init(ctx, SN_magma_cbc); } -static int omac_acpkm_imit_update(EVP_MD_CTX *ctx, const void *data, +static int omac_acpkm_imit_update(GOST_digest_ctx *ctx, const void *data, size_t count) { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); if (!c->key_set) { GOSTerr(GOST_F_OMAC_ACPKM_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET); return 0; @@ -382,9 +383,9 @@ static int omac_acpkm_imit_update(EVP_MD_CTX *ctx, const void *data, return CMAC_ACPKM_Update(c->cmac_ctx, data, count); } -static int omac_acpkm_imit_final(EVP_MD_CTX *ctx, unsigned char *md) +static int omac_acpkm_imit_final(GOST_digest_ctx *ctx, unsigned char *md) { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); unsigned char mac[MAX_GOST_OMAC_ACPKM_SIZE]; size_t mac_size = sizeof(mac); int ret; @@ -400,10 +401,10 @@ static int omac_acpkm_imit_final(EVP_MD_CTX *ctx, unsigned char *md) return ret; } -static int omac_acpkm_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static int omac_acpkm_imit_copy(GOST_digest_ctx *to, const GOST_digest_ctx *from) { - OMAC_ACPKM_CTX *c_to = EVP_MD_CTX_md_data(to); - const OMAC_ACPKM_CTX *c_from = EVP_MD_CTX_md_data(from); + OMAC_ACPKM_CTX *c_to = GOST_digest_ctx_data(to); + const OMAC_ACPKM_CTX *c_from = GOST_digest_ctx_data(from); if (c_from && c_to) { c_to->dgst_size = c_from->dgst_size; @@ -427,13 +428,13 @@ static int omac_acpkm_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) } /* Clean up imit ctx */ -static int omac_acpkm_imit_cleanup(EVP_MD_CTX *ctx) +static int omac_acpkm_imit_cleanup(GOST_digest_ctx *ctx) { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); if (c) { CMAC_ACPKM_CTX_free(c->cmac_ctx); - memset(EVP_MD_CTX_md_data(ctx), 0, sizeof(OMAC_ACPKM_CTX)); + memset(GOST_digest_ctx_data(ctx), 0, sizeof(OMAC_ACPKM_CTX)); } return 1; } @@ -456,7 +457,7 @@ static int omac_acpkm_key(OMAC_ACPKM_CTX *c, const EVP_CIPHER *cipher, return 1; } -static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +static int omac_acpkm_imit_ctrl(GOST_digest_ctx *ctx, int type, int arg, void *ptr) { switch (type) { case EVP_MD_CTRL_KEY_LEN: @@ -464,17 +465,16 @@ static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) return 1; case EVP_MD_CTRL_SET_KEY: { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); - const EVP_MD *md = EVP_MD_CTX_md(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); EVP_CIPHER *cipher = NULL; int ret = 0; if (c->cipher_name == NULL) { - if (EVP_MD_is_a(md, SN_grasshopper_mac) - || EVP_MD_is_a(md, SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac)) + if (GOST_digest_type(GOST_digest_ctx_digest(ctx)) + == NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac) c->cipher_name = SN_grasshopper_cbc; - else if (EVP_MD_is_a(md, SN_magma_mac) - || EVP_MD_is_a(md, SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac)) + else if (GOST_digest_type(GOST_digest_ctx_digest(ctx)) + == NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac) c->cipher_name = SN_magma_cbc; } if ((cipher = @@ -483,11 +483,11 @@ static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) EVP_CIPHER_fetch(NULL, c->cipher_name, NULL)) == NULL) { GOSTerr(GOST_F_OMAC_ACPKM_IMIT_CTRL, GOST_R_CIPHER_NOT_FOUND); } - if (EVP_MD_meth_get_init(EVP_MD_CTX_md(ctx)) (ctx) <= 0) { + if (GOST_digest_meth_get_init(GOST_digest_ctx_digest(ctx))(ctx) <= 0) { GOSTerr(GOST_F_OMAC_ACPKM_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET); goto set_key_end; } - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); + GOST_digest_ctx_set_flags(ctx, EVP_MD_CTX_FLAG_NO_INIT); if (c->key_set) { GOSTerr(GOST_F_OMAC_ACPKM_IMIT_CTRL, GOST_R_BAD_ORDER); goto set_key_end; @@ -507,8 +507,8 @@ static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } case EVP_CTRL_KEY_MESH: { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); - if (!arg || (arg % EVP_MD_block_size(EVP_MD_CTX_md(ctx)))) + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); + if (!arg || (arg % GOST_digest_block_size(GOST_digest_ctx_digest(ctx)))) return -1; c->cmac_ctx->section_size = arg; if (ptr && *(int *)ptr) { @@ -535,7 +535,7 @@ static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } case EVP_MD_CTRL_XOF_LEN: /* Supported in OpenSSL */ { - OMAC_ACPKM_CTX *c = EVP_MD_CTX_md_data(ctx); + OMAC_ACPKM_CTX *c = GOST_digest_ctx_data(ctx); switch (OBJ_txt2nid(c->cipher_name)) { case NID_grasshopper_cbc: if (arg < 1 || arg > 16) { @@ -562,11 +562,11 @@ static int omac_acpkm_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } } -GOST_digest kuznyechik_ctracpkm_omac_digest = { +GOST_digest grasshopper_ctracpkm_mac = { .nid = NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, .result_size = MAX_GOST_OMAC_ACPKM_SIZE, .input_blocksize = 16, - .app_datasize = sizeof(OMAC_ACPKM_CTX), + .algctx_size = sizeof(OMAC_ACPKM_CTX), .flags = EVP_MD_FLAG_XOF, .init = grasshopper_omac_acpkm_init, .update = omac_acpkm_imit_update, @@ -576,11 +576,11 @@ GOST_digest kuznyechik_ctracpkm_omac_digest = { .ctrl = omac_acpkm_imit_ctrl, }; -GOST_digest magma_ctracpkm_omac_digest = { +GOST_digest magma_ctracpkm_mac = { .nid = NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, .result_size = 8, .input_blocksize = 8, - .app_datasize = sizeof(OMAC_ACPKM_CTX), + .algctx_size = sizeof(OMAC_ACPKM_CTX), .flags = EVP_MD_FLAG_XOF, .init = magma_omac_acpkm_init, .update = omac_acpkm_imit_update, diff --git a/gost_prov.c b/gost_prov.c index 3c86b197d..2aa6076e2 100644 --- a/gost_prov.c +++ b/gost_prov.c @@ -12,6 +12,7 @@ #include "gost_prov.h" #include "gost_prov_tls.h" #include "gost_prov_digest.h" +#include "gost_prov_mac.h" #include "gost_lcl.h" #include "prov/err.h" /* libprov err functions */ @@ -137,7 +138,7 @@ static void gost_teardown(void *vprovctx) { GOST_prov_deinit_ciphers(); GOST_prov_deinit_digests(); - GOST_prov_deinit_mac_digests(); + GOST_prov_deinit_macs(); provider_ctx_free(vprovctx); } @@ -186,6 +187,7 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *core, return 0; GOST_prov_init_digests(); + GOST_prov_init_macs(); *out = provider_functions; return 1; diff --git a/gost_prov.h b/gost_prov.h index 38193176f..81961794e 100644 --- a/gost_prov.h +++ b/gost_prov.h @@ -76,10 +76,8 @@ typedef struct gost_key_data_st int gost_get_max_keyexch_size(const GOST_KEY_DATA *); int gost_get_max_signature_size(const GOST_KEY_DATA *); -void GOST_prov_deinit_mac_digests(void); void GOST_prov_deinit_ciphers(void); -extern const OSSL_ALGORITHM GOST_prov_macs[]; extern const OSSL_ALGORITHM GOST_prov_ciphers[]; extern const OSSL_ALGORITHM GOST_prov_keymgmt[]; extern const OSSL_ALGORITHM GOST_prov_encoder[]; diff --git a/gost_prov_digest.c b/gost_prov_digest.c index db40b772c..bb1825e23 100644 --- a/gost_prov_digest.c +++ b/gost_prov_digest.c @@ -12,8 +12,7 @@ #include #include "gost_prov.h" #include "gost_prov_digest.h" -#include "gost_digest_3411_94.h" -#include "gost_digest_3411_2012.h" +#include "gost_lcl.h" /* * Forward declarations of all OSSL_DISPATCH functions, to make sure they @@ -40,7 +39,7 @@ static void digest_freectx(void *vgctx) if (!gctx) return; - GET_MEMBER(gctx->descriptor, free)(gctx->dctx); + GOST_digest_ctx_free(gctx->dctx); OPENSSL_free(gctx); } @@ -52,7 +51,7 @@ static GOST_CTX *digest_newctx(void *provctx, const GOST_digest *descriptor) gctx->provctx = provctx; gctx->descriptor = descriptor; - gctx->dctx = GET_MEMBER(gctx->descriptor, new)(gctx->descriptor); + gctx->dctx = GOST_digest_ctx_new(); if (gctx->dctx == NULL) { digest_freectx(gctx); gctx = NULL; @@ -67,7 +66,7 @@ static void *digest_dupctx(void *vsrc) GOST_CTX *dst = digest_newctx(src->provctx, src->descriptor); if (dst != NULL) - GET_MEMBER(src->descriptor, copy)(dst->dctx, src->dctx); + GOST_digest_ctx_copy(dst->dctx, src->dctx); return dst; } @@ -77,11 +76,11 @@ static int digest_get_params(const GOST_digest *descriptor, OSSL_PARAM params[]) OSSL_PARAM *p; if (((p = OSSL_PARAM_locate(params, "blocksize")) != NULL - && !OSSL_PARAM_set_size_t(p, GET_MEMBER(descriptor, input_blocksize))) + && !OSSL_PARAM_set_size_t(p, GOST_digest_block_size(descriptor))) || ((p = OSSL_PARAM_locate(params, "size")) != NULL - && !OSSL_PARAM_set_size_t(p, GET_MEMBER(descriptor, result_size))) + && !OSSL_PARAM_set_size_t(p, GOST_digest_size(descriptor))) || ((p = OSSL_PARAM_locate(params, "xof")) != NULL - && !OSSL_PARAM_set_size_t(p, GET_MEMBER(descriptor, flags) & EVP_MD_FLAG_XOF))) + && !OSSL_PARAM_set_size_t(p, GOST_digest_flags(descriptor) & EVP_MD_FLAG_XOF))) return 0; return 1; } @@ -90,14 +89,14 @@ static int digest_init(void *vgctx, const OSSL_PARAM unused_params[]) { GOST_CTX *gctx = vgctx; - return GET_MEMBER(gctx->descriptor, init)(gctx->dctx) > 0; + return GOST_digest_ctx_init(gctx->dctx, gctx->descriptor) > 0; } static int digest_update(void *vgctx, const unsigned char *in, size_t inl) { GOST_CTX *gctx = vgctx; - return GET_MEMBER(gctx->descriptor, update)(gctx->dctx, in, inl) > 0; + return GOST_digest_ctx_update(gctx->dctx, in, inl) > 0; } static int digest_final(void *vgctx, @@ -105,15 +104,24 @@ static int digest_final(void *vgctx, { GOST_CTX *gctx = vgctx; - if (outsize < GET_MEMBER(gctx->descriptor, result_size)) + if (outl == NULL) { + return 0; + } + + if (out == NULL) { + *outl = GOST_digest_size(gctx->descriptor); + return 1; + } + + if (outsize < GOST_digest_size(gctx->descriptor)) return 0; - int res = GET_MEMBER(gctx->descriptor, final)(gctx->dctx, out); + int res = GOST_digest_ctx_final(gctx->dctx, out); - GET_MEMBER(gctx->descriptor, cleanup)(gctx->dctx); + GOST_digest_ctx_cleanup(gctx->dctx); - if (res > 0 && outl != NULL) - *outl = GET_MEMBER(gctx->descriptor, result_size); + if (res > 0) + *outl = GOST_digest_size(gctx->descriptor); return res > 0; } @@ -169,7 +177,7 @@ const OSSL_ALGORITHM GOST_prov_digests[] = { { NULL , NULL, NULL } }; -static const GOST_digest *digests[] = { +static GOST_digest *digests[] = { &GostR3411_94_digest, &GostR3411_2012_256_digest, &GostR3411_2012_512_digest, @@ -180,11 +188,11 @@ static const GOST_digest *digests[] = { void GOST_prov_init_digests(void) { size_t i; for (i = 0; i < arraysize(digests); i++) - GET_MEMBER(digests[i], static_init)(digests[i]); + GOST_digest_init(digests[i]); } void GOST_prov_deinit_digests(void) { size_t i; for (i = 0; i < arraysize(digests); i++) - GET_MEMBER(digests[i], static_deinit)(digests[i]); + GOST_digest_deinit(digests[i]); } diff --git a/gost_prov_mac.c b/gost_prov_mac.c index 77dcb7bff..9580ad756 100644 --- a/gost_prov_mac.c +++ b/gost_prov_mac.c @@ -11,6 +11,7 @@ #include #include #include "gost_prov.h" +#include "gost_digest.h" #include "gost_lcl.h" /* @@ -56,22 +57,24 @@ struct gost_prov_mac_ctx_st { */ /* The EVP_MD created from |descriptor| */ - EVP_MD *digest; + const GOST_digest *digest; /* The context for the EVP_MD functions */ - EVP_MD_CTX *dctx; + GOST_digest_ctx *dctx; }; typedef struct gost_prov_mac_ctx_st GOST_CTX; static void mac_freectx(void *vgctx) { GOST_CTX *gctx = vgctx; + if (!gctx) + return; /* * We don't free gctx->digest here. * That will be done by the provider teardown, via - * GOST_prov_deinit_digests() (defined at the bottom of this file). + * GOST_prov_deinit_macs() (defined at the bottom of this file). */ - EVP_MD_CTX_free(gctx->dctx); + GOST_digest_ctx_free(gctx->dctx); OPENSSL_free(gctx); } @@ -83,13 +86,12 @@ static GOST_CTX *mac_newctx(void *provctx, const GOST_DESC *descriptor) gctx->provctx = provctx; gctx->descriptor = descriptor; gctx->mac_size = descriptor->initial_mac_size; - gctx->digest = GOST_init_digest(descriptor->digest_desc); - gctx->dctx = EVP_MD_CTX_new(); + gctx->digest = GOST_digest_init(descriptor->digest_desc); + gctx->dctx = GOST_digest_ctx_new(); if (gctx->digest == NULL || gctx->dctx == NULL - || EVP_DigestInit_ex(gctx->dctx, gctx->digest, - gctx->provctx->e) <= 0) { + || GOST_digest_ctx_init(gctx->dctx, gctx->digest) <= 0) { mac_freectx(gctx); gctx = NULL; } @@ -100,11 +102,23 @@ static GOST_CTX *mac_newctx(void *provctx, const GOST_DESC *descriptor) static void *mac_dupctx(void *vsrc) { GOST_CTX *src = vsrc; - GOST_CTX *dst = - mac_newctx(src->provctx, src->descriptor); + if (src == NULL) { + return NULL; + } + + GOST_CTX *dst = mac_newctx(src->provctx, src->descriptor); + if (dst == NULL) { + return dst; + } + + if (GOST_digest_ctx_copy(dst->dctx, src->dctx) <= 0) { + mac_freectx(dst); + return NULL; + } + + dst->mac_size = src->mac_size; + dst->xof_mode = src->xof_mode; - if (dst != NULL) - EVP_MD_CTX_copy(dst->dctx, src->dctx); return dst; } @@ -115,7 +129,7 @@ static int mac_init(void *mctx, const unsigned char *key, return mac_set_ctx_params(gctx, params) && (key == NULL - || EVP_MD_CTX_ctrl(gctx->dctx, EVP_MD_CTRL_SET_KEY, + || GOST_digest_ctx_ctrl(gctx->dctx, EVP_MD_CTRL_SET_KEY, (int)keylen, (void *)key) > 0); } @@ -123,32 +137,33 @@ static int mac_update(void *mctx, const unsigned char *in, size_t inl) { GOST_CTX *gctx = mctx; - return EVP_DigestUpdate(gctx->dctx, in, inl) > 0; + return GOST_digest_ctx_update(gctx->dctx, in, inl) > 0; } static int mac_final(void *mctx, unsigned char *out, size_t *outl, size_t outsize) { GOST_CTX *gctx = mctx; - unsigned int tmpoutl; int ret = 0; - /* This is strange code... but it duplicates pkey_gost_mac_signctx() */ - if (outl == NULL) return 0; - /* for platforms where sizeof(int) != * sizeof(size_t) */ - tmpoutl = *outl; - - if (out != NULL) { - /* We ignore the error for GOST MDs that don't support setting - the size */ - EVP_MD_CTX_ctrl(gctx->dctx, EVP_MD_CTRL_XOF_LEN, gctx->mac_size, NULL); - ret = EVP_DigestFinal_ex(gctx->dctx, out, &tmpoutl); + if (out == NULL) { + *outl = (size_t)gctx->mac_size; + return 1; } - if (outl != NULL) + + if (outsize < gctx->mac_size) + return 0; + + /* We ignore the error for GOST MDs that don't support setting the size */ + GOST_digest_ctx_ctrl(gctx->dctx, EVP_MD_CTRL_XOF_LEN, gctx->mac_size, NULL); + ret = GOST_digest_ctx_final(gctx->dctx, out); + if (ret > 0) { *outl = (size_t)gctx->mac_size; + } + return ret; } @@ -210,13 +225,13 @@ static int mac_get_ctx_params(void *mctx, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, "keylen")) != NULL) { unsigned int len = 0; - if (EVP_MD_CTX_ctrl(gctx->dctx, EVP_MD_CTRL_KEY_LEN, 0, &len) <= 0 + if (GOST_digest_ctx_ctrl(gctx->dctx, EVP_MD_CTRL_KEY_LEN, 0, &len) <= 0 || !OSSL_PARAM_set_size_t(p, len)) return 0; } if ((p = OSSL_PARAM_locate(params, "xof")) != NULL - && (!(EVP_MD_flags(EVP_MD_CTX_md(gctx->dctx)) & EVP_MD_FLAG_XOF) + && (!(GOST_digest_flags(GOST_digest_ctx_digest(gctx->dctx)) & EVP_MD_FLAG_XOF) || !OSSL_PARAM_set_int(p, gctx->xof_mode))) return 0; @@ -239,13 +254,13 @@ static int mac_set_ctx_params(void *mctx, const OSSL_PARAM params[]) if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&key, &keylen)) return 0; - ret = EVP_MD_CTX_ctrl(gctx->dctx, EVP_MD_CTRL_SET_KEY, + ret = GOST_digest_ctx_ctrl(gctx->dctx, EVP_MD_CTRL_SET_KEY, (int)keylen, (void *)key); if (ret <= 0 && ret != -2) return 0; } if ((p = OSSL_PARAM_locate_const(params, "xof")) != NULL - && (!(EVP_MD_flags(EVP_MD_CTX_md(gctx->dctx)) & EVP_MD_FLAG_XOF) + && (!(GOST_digest_flags(GOST_digest_ctx_digest(gctx->dctx)) & EVP_MD_FLAG_XOF) || !OSSL_PARAM_get_int(p, &gctx->xof_mode))) return 0; if ((p = OSSL_PARAM_locate_const(params, "key-mesh")) != NULL) { @@ -266,29 +281,17 @@ static int mac_set_ctx_params(void *mctx, const OSSL_PARAM params[]) } } - if (EVP_MD_CTX_ctrl(gctx->dctx, EVP_CTRL_KEY_MESH, + if (GOST_digest_ctx_ctrl(gctx->dctx, EVP_CTRL_KEY_MESH, key_mesh, p_cipher_key_mesh) <= 0) return 0; } return 1; } -/* - * Macros to map the MAC algorithms to their respective GOST_digest - * implementation where necessary. Not needed for magma and grasshopper, as - * they already have fitting names. - */ -#define id_Gost28147_89_MAC_digest Gost28147_89_MAC_digest -#define gost_mac_12_digest Gost28147_89_mac_12_digest -#define id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac_digest \ - kuznyechik_ctracpkm_omac_digest -#define id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac_digest \ - magma_ctracpkm_omac_digest - typedef void (*fptr_t)(void); #define MAKE_FUNCTIONS(name, macsize) \ const GOST_DESC name##_desc = { \ - &name##_digest, \ + &name, \ macsize, \ }; \ static OSSL_FUNC_mac_newctx_fn name##_newctx; \ @@ -324,45 +327,47 @@ typedef void (*fptr_t)(void); { OSSL_FUNC_MAC_SET_CTX_PARAMS, (fptr_t)mac_set_ctx_params }, \ } -/* - * The name used here is the same as the NID name. Some of the names are - * horribly long, but that can't be helped... - */ -MAKE_FUNCTIONS(id_Gost28147_89_MAC, 4); -MAKE_FUNCTIONS(gost_mac_12, 4); -MAKE_FUNCTIONS(magma_mac, 8); -MAKE_FUNCTIONS(grasshopper_mac, 16); -MAKE_FUNCTIONS(id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac, 16); -MAKE_FUNCTIONS(id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac, 8); +MAKE_FUNCTIONS(Gost28147_89_mac, 4); +MAKE_FUNCTIONS(Gost28147_89_mac_12, 4); +MAKE_FUNCTIONS(magma_omac_mac, 8); +MAKE_FUNCTIONS(grasshopper_omac_mac, 16); +MAKE_FUNCTIONS(grasshopper_ctracpkm_mac, 16); +MAKE_FUNCTIONS(magma_ctracpkm_mac, 8); /* The OSSL_ALGORITHM for the provider's operation query function */ const OSSL_ALGORITHM GOST_prov_macs[] = { { SN_id_Gost28147_89_MAC ":1.2.643.2.2.22", NULL, - id_Gost28147_89_MAC_functions, "GOST 28147-89 MAC" }, - { SN_gost_mac_12, NULL, gost_mac_12_functions }, - { SN_magma_mac, NULL, magma_mac_functions }, - { SN_grasshopper_mac, NULL, grasshopper_mac_functions }, + Gost28147_89_mac_functions, "GOST 28147-89 MAC" }, + { SN_gost_mac_12, NULL, Gost28147_89_mac_12_functions }, + { SN_magma_mac, NULL, magma_omac_mac_functions }, + { SN_grasshopper_mac, NULL, grasshopper_omac_mac_functions }, { SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac ":1.2.643.7.1.1.5.2.2", NULL, - id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac_functions }, + grasshopper_ctracpkm_mac_functions }, { SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac - ":1.2.643.7.1.1.5.1.2", NULL, - id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac_functions }, + ":1.2.643.7.1.1.5.1.2", NULL, magma_ctracpkm_mac_functions }, { NULL , NULL, NULL } }; -void GOST_prov_deinit_mac_digests(void) { - static GOST_digest *list[] = { - &Gost28147_89_MAC_digest, - &Gost28147_89_mac_12_digest, - &magma_mac_digest, - &grasshopper_mac_digest, - &kuznyechik_ctracpkm_omac_digest, - &magma_ctracpkm_omac_digest - }; +static GOST_digest *digests[] = { + &Gost28147_89_mac, + &Gost28147_89_mac_12, + &magma_omac_mac, + &grasshopper_omac_mac, + &grasshopper_ctracpkm_mac, + &magma_ctracpkm_mac +}; + +#define arraysize(l) (sizeof(l) / sizeof(l[0])) + +void GOST_prov_init_macs(void) { size_t i; -#define elems(l) (sizeof(l) / sizeof(l[0])) + for (i = 0; i < arraysize(digests); i++) + GOST_digest_init(digests[i]); +} - for (i = 0; i < elems(list); i++) - GOST_deinit_digest(list[i]); +void GOST_prov_deinit_macs(void) { + size_t i; + for (i = 0; i < arraysize(digests); i++) + GOST_digest_deinit(digests[i]); } diff --git a/gost_prov_mac.h b/gost_prov_mac.h new file mode 100644 index 000000000..450ba05b9 --- /dev/null +++ b/gost_prov_mac.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +void GOST_prov_init_macs(void); +void GOST_prov_deinit_macs(void); + +extern const OSSL_ALGORITHM GOST_prov_macs[]; diff --git a/gost_tls12_additional_kexpimp.c b/gost_tls12_additional_kexpimp.c index 82ccbd311..174308c2d 100644 --- a/gost_tls12_additional_kexpimp.c +++ b/gost_tls12_additional_kexpimp.c @@ -13,7 +13,7 @@ #include #include "gost_tls12_additional_kexpimp.h" -#include "gost_mac.h" +#include "gost_lcl.h" #include "e_gost_err.h" static int calculate_mac(int nid, unsigned char *mac_key, diff --git a/utils_one_level_inheritance.h b/utils_one_level_inheritance.h deleted file mode 100644 index a8be47089..000000000 --- a/utils_one_level_inheritance.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#define MEMBER_SUFFIX _private -#define MEMBER_SUFFIX_ISSET _private_isset - -#define DETAILS_BASE_NAME base - -#define DETAILS_MAKE_NAME_IMPL(prefix, suffix) prefix##suffix -#define DETAILS_MAKE_NAME(prefix, suffix) DETAILS_MAKE_NAME_IMPL(prefix, suffix) - -#define DETAILS_MEMBER_NAME(name) DETAILS_MAKE_NAME(name, MEMBER_SUFFIX) -#define DETAILS_MEMBER_NAME_ISSET(name) DETAILS_MAKE_NAME(name, MEMBER_SUFFIX_ISSET) - -#define DETAILS_GET_BASE_MEMBER(object, name) ( \ - ((object)->DETAILS_MEMBER_NAME(DETAILS_BASE_NAME)) ? \ - ((object)->DETAILS_MEMBER_NAME(DETAILS_BASE_NAME)->DETAILS_MEMBER_NAME(name)) : \ - 0 \ -) - -#define DETAILS_GET_MEMBER(object, name) ( \ - ((object)->DETAILS_MEMBER_NAME_ISSET(name)) ? \ - ((object)->DETAILS_MEMBER_NAME(name)) : \ - DETAILS_GET_BASE_MEMBER(object, name) \ -) - -#define DECL_MEMBER(type, name) \ - type DETAILS_MEMBER_NAME(name); \ - bool DETAILS_MEMBER_NAME_ISSET(name) - -#define DECL_BASE(type) DECL_MEMBER(type*, DETAILS_BASE_NAME) - -#define INIT_MEMBER(name, val) \ - .DETAILS_MEMBER_NAME(name) = (val), \ - .DETAILS_MEMBER_NAME_ISSET(name) = true - -#define GET_MEMBER(object, name) DETAILS_GET_MEMBER(object, name)