X-Git-Url: http://www.wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gost_omac.c;h=648cd8f39550bee5a31aa982c118ec71f07f1c43;hb=HEAD;hp=0cbd45d2dd02a7913ba2bf382889da048e6a7b23;hpb=6089a16ce94ea362ed3a4f743f32bfe7f829ba1f;p=openssl-gost%2Fengine.git diff --git a/gost_omac.c b/gost_omac.c index 0cbd45d..648cd8f 100644 --- a/gost_omac.c +++ b/gost_omac.c @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2019 Dmitry Belyavskiy + * Copyright (c) 2020 Vitaly Chikunov + * + * Contents licensed under the terms of the OpenSSL license + * See https://www.openssl.org/source/license.html for details + */ #include #include #include @@ -12,7 +19,7 @@ typedef struct omac_ctx { CMAC_CTX *cmac_ctx; size_t dgst_size; - int cipher_nid; + const char *cipher_name; int key_set; /* * Here begins stuff related to TLSTREE processing @@ -31,14 +38,14 @@ typedef struct omac_ctx { #define MAX_GOST_OMAC_SIZE 16 -static int omac_init(EVP_MD_CTX *ctx, int cipher_nid) +static int omac_init(EVP_MD_CTX *ctx, const char *cipher_name) { OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); memset(c, 0, sizeof(OMAC_CTX)); - c->cipher_nid = cipher_nid; + c->cipher_name = cipher_name; c->key_set = 0; - switch (cipher_nid) { + switch (OBJ_txt2nid(cipher_name)) { case NID_magma_cbc: c->dgst_size = 8; break; @@ -53,12 +60,12 @@ static int omac_init(EVP_MD_CTX *ctx, int cipher_nid) static int magma_imit_init(EVP_MD_CTX *ctx) { - return omac_init(ctx, NID_magma_cbc); + return omac_init(ctx, SN_magma_cbc); } static int grasshopper_imit_init(EVP_MD_CTX *ctx) { - return omac_init(ctx, NID_grasshopper_cbc); + return omac_init(ctx, SN_grasshopper_cbc); } static int omac_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) @@ -72,7 +79,7 @@ static int omac_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) return CMAC_Update(c->cmac_ctx, data, count); } -int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md) +static 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]; @@ -89,14 +96,14 @@ int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md) return 1; } -int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +static 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->cipher_name = c_from->cipher_name; c_to->key_set = c_from->key_set; memcpy(c_to->key, c_from->key, 32); } else { @@ -116,7 +123,7 @@ int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) } /* Clean up imit ctx */ -int omac_imit_cleanup(EVP_MD_CTX *ctx) +static int omac_imit_cleanup(EVP_MD_CTX *ctx) { OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); @@ -132,6 +139,7 @@ static int omac_key(OMAC_CTX * c, const EVP_CIPHER *cipher, { int ret = 0; + CMAC_CTX_free(c->cmac_ctx); c->cmac_ctx = CMAC_CTX_new(); if (c->cmac_ctx == NULL) { GOSTerr(GOST_F_OMAC_KEY, ERR_R_MALLOC_FAILURE); @@ -145,6 +153,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) { switch (type) { @@ -155,35 +164,32 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) { OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); const EVP_MD *md = EVP_MD_CTX_md(ctx); - const EVP_CIPHER *cipher = NULL; + EVP_CIPHER *cipher = NULL; int ret = 0; - if (c->cipher_nid == NID_undef) { - switch (EVP_MD_nid(md)) { - case NID_magma_mac: - c->cipher_nid = NID_magma_cbc; - break; - - case NID_grasshopper_mac: - c->cipher_nid = NID_grasshopper_cbc; - break; - } + 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; } - cipher = EVP_get_cipherbynid(c->cipher_nid); - - if (cipher == NULL) { + if ((cipher = + (EVP_CIPHER *)EVP_get_cipherbyname(c->cipher_name)) == NULL + && (cipher = + EVP_CIPHER_fetch(NULL, c->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) { GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_MAC_KEY_NOT_SET); - return 0; + goto set_key_end; } 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; + goto set_key_end; } if (arg == 0) { @@ -191,20 +197,24 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) ret = omac_key(c, cipher, key->key, 32); if (ret > 0) memcpy(c->key, key->key, 32); - return ret; + goto set_key_end; } else if (arg == 32) { ret = omac_key(c, cipher, ptr, 32); if (ret > 0) memcpy(c->key, ptr, 32); - return ret; + goto set_key_end; } GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE); + set_key_end: + EVP_CIPHER_free(cipher); + if (ret > 0) + return ret; return 0; } - case EVP_MD_CTRL_MAC_LEN: + case EVP_MD_CTRL_XOF_LEN: /* Supported in OpenSSL */ { OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); - switch (c->cipher_nid) { + switch (OBJ_txt2nid(c->cipher_name)) { case NID_magma_cbc: if (arg < 1 || arg > 8) { GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_SIZE); @@ -230,81 +240,48 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) OMAC_CTX *c = EVP_MD_CTX_md_data(ctx); if (c->key_set) { unsigned char diversed_key[32]; - return gost_tlstree(c->cipher_nid, c->key, diversed_key, - (const unsigned char *)ptr) ? - omac_key(c, EVP_get_cipherbynid(c->cipher_nid), - diversed_key, 32) : 0; + int ret = 0; + if (gost_tlstree(OBJ_txt2nid(c->cipher_name), + c->key, diversed_key, + (const unsigned char *)ptr)) { + EVP_CIPHER *cipher; + if ((cipher = (EVP_CIPHER *)EVP_get_cipherbyname(c->cipher_name)) + || (cipher = EVP_CIPHER_fetch(NULL, c->cipher_name, NULL))) + ret = omac_key(c, cipher, diversed_key, 32); + EVP_CIPHER_free(cipher); + } + return ret; } GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_BAD_ORDER); return 0; } - return 0; #endif 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, 8) - || !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, 16) - || !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; -} +static GOST_digest omac_template_digest = { + .input_blocksize = 8, + .app_datasize = sizeof(OMAC_CTX), + .flags = EVP_MD_FLAG_XOF, + .update = omac_imit_update, + .final = omac_imit_final, + .copy = omac_imit_copy, + .cleanup = omac_imit_cleanup, + .ctrl = omac_imit_ctrl, +}; + +GOST_digest magma_mac_digest = { + .nid = NID_magma_mac, + .template = &omac_template_digest, + .result_size = 8, + .init = magma_imit_init, +}; + +GOST_digest grasshopper_mac_digest = { + .nid = NID_grasshopper_mac, + .template = &omac_template_digest, + .result_size = 16, + .init = grasshopper_imit_init, +};