From 6ee305aa55f793269627735081a1133265e91bfb Mon Sep 17 00:00:00 2001 From: Dmitry Belyavskiy Date: Thu, 14 Jun 2018 19:22:45 +0300 Subject: [PATCH] Finalizing OMAC --- e_gost_err.c | 6 ++ e_gost_err.h | 4 + gost.txt | 5 ++ gost_ameth.c | 30 ++++++- gost_pmeth.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 264 insertions(+), 16 deletions(-) diff --git a/e_gost_err.c b/e_gost_err.c index 4f2c709..c8804fa 100644 --- a/e_gost_err.c +++ b/e_gost_err.c @@ -51,12 +51,18 @@ static ERR_STRING_DATA GOST_str_functs[] = { {ERR_PACK(0, GOST_F_PKEY_GOST_EC_CTRL_STR_512, 0), "pkey_gost_ec_ctrl_str_512"}, {ERR_PACK(0, GOST_F_PKEY_GOST_EC_DERIVE, 0), "pkey_gost_ec_derive"}, + {ERR_PACK(0, GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, 0), + "pkey_gost_grasshopper_mac_signctx_init"}, {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_CTRL, 0), "pkey_gost_mac_ctrl"}, {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_CTRL_STR, 0), "pkey_gost_mac_ctrl_str"}, {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_KEYGEN_BASE, 0), "pkey_gost_mac_keygen_base"}, {ERR_PACK(0, GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT, 0), "pkey_gost_mac_signctx_init"}, + {ERR_PACK(0, GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, 0), + "pkey_gost_magma_mac_signctx_init"}, + {ERR_PACK(0, GOST_F_PKEY_GOST_OMAC_CTRL, 0), "pkey_gost_omac_ctrl"}, + {ERR_PACK(0, GOST_F_PKEY_GOST_OMAC_CTRL_STR, 0), "pkey_gost_omac_ctrl_str"}, {ERR_PACK(0, GOST_F_PRINT_GOST_EC_PUB, 0), "print_gost_ec_pub"}, {ERR_PACK(0, GOST_F_PRIV_DECODE_GOST, 0), "priv_decode_gost"}, {ERR_PACK(0, GOST_F_PUB_DECODE_GOST_EC, 0), "pub_decode_gost_ec"}, diff --git a/e_gost_err.h b/e_gost_err.h index 439ac90..b9ea379 100644 --- a/e_gost_err.h +++ b/e_gost_err.h @@ -56,10 +56,14 @@ void ERR_GOST_error(int function, int reason, char *file, int line); # define GOST_F_PKEY_GOST_EC_CTRL_STR_256 125 # define GOST_F_PKEY_GOST_EC_CTRL_STR_512 126 # define GOST_F_PKEY_GOST_EC_DERIVE 127 +# define GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT 141 # define GOST_F_PKEY_GOST_MAC_CTRL 128 # define GOST_F_PKEY_GOST_MAC_CTRL_STR 129 # define GOST_F_PKEY_GOST_MAC_KEYGEN_BASE 130 # define GOST_F_PKEY_GOST_MAC_SIGNCTX_INIT 131 +# define GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT 142 +# define GOST_F_PKEY_GOST_OMAC_CTRL 139 +# define GOST_F_PKEY_GOST_OMAC_CTRL_STR 140 # define GOST_F_PRINT_GOST_EC_PUB 132 # define GOST_F_PRIV_DECODE_GOST 133 # define GOST_F_PUB_DECODE_GOST_EC 134 diff --git a/gost.txt b/gost.txt index 2681911..4a515f9 100644 --- a/gost.txt +++ b/gost.txt @@ -36,10 +36,15 @@ 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 diff --git a/gost_ameth.c b/gost_ameth.c index 8ce4505..5089e2a 100644 --- a/gost_ameth.c +++ b/gost_ameth.c @@ -842,6 +842,30 @@ static int mac_ctrl_gost_12(EVP_PKEY *pkey, int op, long arg1, void *arg2) return -2; } +static int mac_ctrl_magma(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + if (arg2) { + *(int *)arg2 = NID_magma_mac; + return 2; + } + } + return -2; +} + +static int mac_ctrl_grasshopper(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + if (arg2) { + *(int *)arg2 = NID_grasshopper_mac; + return 2; + } + } + return -2; +} + static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) { int nid = @@ -922,16 +946,14 @@ int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12); break; -/* TODO case NID_magma_mac: EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); - EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); + EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_magma); break; case NID_grasshopper_mac: EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); - EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost_12); + EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_grasshopper); break; -*/ } return 1; } diff --git a/gost_pmeth.c b/gost_pmeth.c index a29e5f0..e615d01 100644 --- a/gost_pmeth.c +++ b/gost_pmeth.c @@ -492,6 +492,39 @@ static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) return 1; } +static int pkey_gost_omac_init(EVP_PKEY_CTX *ctx, size_t mac_size) +{ + struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data)); + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + + if (!data) + return 0; + memset(data, 0, sizeof(*data)); + data->mac_size = mac_size; + data->mac_param_nid = NID_undef; + + if (pkey) { + struct gost_mac_key *key = EVP_PKEY_get0(pkey); + if (key) { + data->mac_param_nid = key->mac_param_nid; + data->mac_size = key->mac_size; + } + } + + EVP_PKEY_CTX_set_data(ctx, data); + return 1; +} + +static int pkey_gost_magma_mac_init(EVP_PKEY_CTX *ctx) +{ + return pkey_gost_omac_init(ctx, 4); +} + +static int pkey_gost_grasshopper_mac_init(EVP_PKEY_CTX *ctx) +{ + return pkey_gost_omac_init(ctx, 8); +} + static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); @@ -582,6 +615,7 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) } case EVP_PKEY_CTRL_MAC_LEN: { + /*TODO*/ if (p1 < 1 || p1 > 8) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_SIZE); @@ -652,6 +686,141 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, return -2; } +static int pkey_gost_omac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2, size_t max_size) +{ + struct gost_mac_pmeth_data *data = + (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); + + switch (type) { + case EVP_PKEY_CTRL_MD: + { + int nid = EVP_MD_type((const EVP_MD *)p2); + if (nid != NID_magma_mac && nid != NID_grasshopper_mac) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, + GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + data->md = (EVP_MD *)p2; + return 1; + } + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = data->md; + return 1; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (p1 != 32) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + memcpy(data->key, p2, 32); + data->key_set = 1; + return 1; + case EVP_PKEY_CTRL_DIGESTINIT: + { + EVP_MD_CTX *mctx = p2; + struct gost_mac_key *key; + if (!data->key_set) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, + GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (!key) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, + GOST_R_MAC_KEY_NOT_SET); + return 0; + } + return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx)) + (mctx, EVP_MD_CTRL_SET_KEY, 0, key); + } else { + return EVP_MD_meth_get_ctrl(EVP_MD_CTX_md(mctx)) + (mctx, EVP_MD_CTRL_SET_KEY, 32, &(data->key)); + } + } + case EVP_PKEY_CTRL_MAC_LEN: + { + /*TODO*/ + if (p1 < 1 || p1 > 8) { + + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL, GOST_R_INVALID_MAC_SIZE); + return 0; + } + data->mac_size = p1; + return 1; + } + } + return -2; +} + +static int pkey_gost_magma_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + return pkey_gost_omac_ctrl(ctx, type, p1, p2, 8); +} + +static int pkey_gost_grasshopper_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + return pkey_gost_omac_ctrl(ctx, type, p1, p2, 16); +} + +static int pkey_gost_omac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value, size_t max_size) +{ + if (strcmp(type, key_ctrl_string) == 0) { + if (strlen(value) != 32) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32, (char *)value); + } + if (strcmp(type, hexkey_ctrl_string) == 0) { + long keylen; + int ret; + unsigned char *keybuf = string_to_hex(value, &keylen); + if (!keybuf || keylen != 32) { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + OPENSSL_free(keybuf); + return 0; + } + ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf); + OPENSSL_free(keybuf); + return ret; + + } + if (!strcmp(type, maclen_ctrl_string)) { + char *endptr; + long size = strtol(value, &endptr, 10); + if (*endptr != '\0') { + GOSTerr(GOST_F_PKEY_GOST_OMAC_CTRL_STR, GOST_R_INVALID_MAC_SIZE); + return 0; + } + return pkey_gost_omac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN, size, NULL, max_size); + } + return -2; +} + +static int pkey_gost_magma_mac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + return pkey_gost_omac_ctrl_str(ctx, type, value, 8); +} + +static int pkey_gost_grasshopper_mac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + return pkey_gost_omac_ctrl_str(ctx, type, value, 8); +} + static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey, int mac_nid) { @@ -681,6 +850,16 @@ static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return pkey_gost_mac_keygen_base(ctx, pkey, NID_id_Gost28147_89_MAC); } +static int pkey_gost_magma_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + return pkey_gost_mac_keygen_base(ctx, pkey, NID_magma_mac); +} + +static int pkey_gost_grasshopper_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + return pkey_gost_mac_keygen_base(ctx, pkey, NID_grasshopper_mac); +} + static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) { struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); @@ -698,6 +877,40 @@ static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) return 1; } +static int pkey_gost_magma_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + if (data == NULL) { + pkey_gost_omac_init(ctx, 4); + } + + data = EVP_PKEY_CTX_get_data(ctx); + if (!data) { + GOSTerr(GOST_F_PKEY_GOST_MAGMA_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + + return 1; +} + +static int pkey_gost_grasshopper_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + if (data == NULL) { + pkey_gost_omac_init(ctx, 8); + } + + data = EVP_PKEY_CTX_get_data(ctx); + if (!data) { + GOSTerr(GOST_F_PKEY_GOST_GRASSHOPPER_MAC_SIGNCTX_INIT, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + + return 1; +} + static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, EVP_MD_CTX *mctx) { @@ -803,28 +1016,26 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); return 1; -/* TODO case NID_magma_mac: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, - pkey_gost_mac_ctrl_str); - EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init, + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_magma_mac_ctrl, + pkey_gost_magma_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_magma_mac_signctx_init, pkey_gost_mac_signctx); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen_12); - EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_magma_mac_keygen); + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_magma_mac_init); EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); return 1; case NID_grasshopper_mac: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, - pkey_gost_mac_ctrl_str); - EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init, + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_grasshopper_mac_ctrl, + pkey_gost_grasshopper_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_grasshopper_mac_signctx_init, pkey_gost_mac_signctx); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen_12); - EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_grasshopper_mac_keygen); + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_grasshopper_mac_init); EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); return 1; -*/ default: /* Unsupported method */ return 0; } -- 2.39.2