X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gost_omac.c;h=a1e7ab4d047bcf804585936abf4e176b2f6d7f38;hb=ea281d2516111f018f224409098d5a1d11e967bd;hp=49113a5cf24da75be3bbe01202d8cf6889c1a1a6;hpb=12be7c21781eba9f7a37762e7e307571225c6c47;p=openssl-gost%2Fengine.git diff --git a/gost_omac.c b/gost_omac.c index 49113a5..a1e7ab4 100644 --- a/gost_omac.c +++ b/gost_omac.c @@ -14,6 +14,19 @@ typedef struct omac_ctx { size_t dgst_size; int cipher_nid; int key_set; +/* + * Here begins stuff related to TLSTREE processing + * We MUST store the original key to derive TLSTREE keys from it + * and TLS seq no. + * */ + unsigned char key[32]; +/* + * TODO + * TLSTREE intermediate values should be recalculated only when + * C_i & (seq_no+1) != C_i & (seq_no) + * so somewhen we will store C_i & (seq_no) in this structure + * to avoid redundant hash calculations. + * */ } OMAC_CTX; #define MAX_GOST_OMAC_SIZE 16 @@ -27,11 +40,11 @@ static int omac_init(EVP_MD_CTX *ctx, int cipher_nid) switch (cipher_nid) { case NID_magma_cbc: - c->dgst_size = 4; + c->dgst_size = 8; break; case NID_grasshopper_cbc: - c->dgst_size = 8; + c->dgst_size = 16; break; } @@ -72,8 +85,7 @@ int omac_imit_final(EVP_MD_CTX *ctx, unsigned char *md) CMAC_Final(c->cmac_ctx, mac, &mac_size); - int md_size = EVP_MD_meth_get_result_size(EVP_MD_CTX_md(ctx)); - memcpy(md, mac, min(md_size, c->dgst_size)); + memcpy(md, mac, c->dgst_size); return 1; } @@ -86,6 +98,7 @@ int omac_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) c_to->dgst_size = c_from->dgst_size; c_to->cipher_nid = c_from->cipher_nid; c_to->key_set = c_from->key_set; + memcpy(c_to->key, c_from->key, 32); } else { return 0; } @@ -119,6 +132,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); @@ -143,6 +157,7 @@ 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; + int ret = 0; if (c->cipher_nid == NID_undef) { switch (EVP_MD_nid(md)) { @@ -174,15 +189,20 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) if (arg == 0) { struct gost_mac_key *key = (struct gost_mac_key *)ptr; - return omac_key(c, cipher, key->key, 32); - + ret = omac_key(c, cipher, key->key, 32); + if (ret > 0) + memcpy(c->key, key->key, 32); + return ret; } else if (arg == 32) { - return omac_key(c, cipher, ptr, 32); + ret = omac_key(c, cipher, ptr, 32); + if (ret > 0) + memcpy(c->key, ptr, 32); + return ret; } GOSTerr(GOST_F_OMAC_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_SIZE); 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) { @@ -205,72 +225,68 @@ int omac_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) } return 1; } - +#ifdef EVP_MD_CTRL_TLSTREE + case EVP_MD_CTRL_TLSTREE: + { + 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; + } + 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; +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, +}; EVP_MD *magma_omac(void) { - if (_hidden_magma_mac_md == NULL) { - EVP_MD *md; - - if ((md = EVP_MD_meth_new(NID_magma_mac, NID_undef)) == NULL - || !EVP_MD_meth_set_result_size(md, 4) - || !EVP_MD_meth_set_input_blocksize(md, 8) - || !EVP_MD_meth_set_app_datasize(md, sizeof(OMAC_CTX)) - || !EVP_MD_meth_set_flags(md, 0) - || !EVP_MD_meth_set_init(md, magma_imit_init) - || !EVP_MD_meth_set_update(md, omac_imit_update) - || !EVP_MD_meth_set_final(md, omac_imit_final) - || !EVP_MD_meth_set_copy(md, omac_imit_copy) - || !EVP_MD_meth_set_cleanup(md, omac_imit_cleanup) - || !EVP_MD_meth_set_ctrl(md, omac_imit_ctrl)) { - EVP_MD_meth_free(md); - md = NULL; - } - _hidden_magma_mac_md = md; - } - return _hidden_magma_mac_md; + return GOST_init_digest(&magma_mac_digest); } void magma_omac_destroy(void) { - EVP_MD_meth_free(_hidden_magma_mac_md); - _hidden_magma_mac_md = NULL; + GOST_deinit_digest(&magma_mac_digest); } -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, 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, 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; + return GOST_init_digest(&grasshopper_mac_digest); } void grasshopper_omac_destroy(void) { - EVP_MD_meth_free(_hidden_grasshopper_mac_md); - _hidden_grasshopper_mac_md = NULL; + GOST_deinit_digest(&grasshopper_mac_digest); }