X-Git-Url: http://wagner.pp.ru/gitweb/?a=blobdiff_plain;f=gost_pmeth.c;h=166cf856055187c74bfad9e890a1657ed086b65c;hb=00769333ead1e655d61f1ba38819b98600888474;hp=e87c5197d7e997a7885fd63651b56eecc3d7a533;hpb=cba16944bff9d8c5dcf37be641822cd3de6d2ec1;p=openssl-gost%2Fengine.git diff --git a/gost_pmeth.c b/gost_pmeth.c index e87c519..166cf85 100644 --- a/gost_pmeth.c +++ b/gost_pmeth.c @@ -10,11 +10,11 @@ #include #include #include +#include #include /* For string_to_hex */ #include #include #include -#include "gost_params.h" #include "gost_lcl.h" #include "e_gost_err.h" @@ -24,28 +24,25 @@ static int pkey_gost_init(EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); + + data = OPENSSL_malloc(sizeof(*data)); if (!data) return 0; - memset(data, 0, sizeof(struct gost_pmeth_data)); + memset(data, 0, sizeof(*data)); if (pkey && EVP_PKEY_get0(pkey)) { - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey)); - break; - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2012_256: - case NID_id_GostR3410_2012_512: + int id = (EVP_PKEY_base_id(pkey)); + if (id == NID_id_GostR3410_2001 || + id == NID_gost2012_256 || + id == NID_gost2012_512) { const EC_GROUP *group = EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey)); if (group != NULL) { data->sign_param_nid = EC_GROUP_get_curve_name(group); - break; } - /* else */ } - default: + else + { OPENSSL_free(data); return 0; } @@ -79,8 +76,7 @@ static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx) struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); if (!data) return; - if (data->shared_ukm) - OPENSSL_free(data->shared_ukm); + OPENSSL_free(data->shared_ukm); OPENSSL_free(data); } @@ -100,28 +96,23 @@ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) OPENSSL_assert(p2 != NULL); - switch (EVP_MD_type((const EVP_MD *)p2)) { - case NID_id_GostR3411_94: + int md_type = EVP_MD_type((const EVP_MD *)p2); + if (md_type == NID_id_GostR3411_94) { if (pkey_nid == NID_id_GostR3410_2001 || pkey_nid == NID_id_GostR3410_94) { pctx->md = (EVP_MD *)p2; return 1; } - break; - - case NID_id_GostR3411_2012_256: - if (pkey_nid == NID_id_GostR3410_2012_256) { + } else if (md_type == NID_md_gost12_256) { + if (pkey_nid == NID_gost2012_256) { pctx->md = (EVP_MD *)p2; return 1; } - break; - - case NID_id_GostR3411_2012_512: - if (pkey_nid == NID_id_GostR3410_2012_512) { + } else if ( md_type == NID_md_gost12_512) { + if (pkey_nid == NID_gost2012_512) { pctx->md = (EVP_MD *)p2; return 1; } - break; } GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); @@ -167,73 +158,12 @@ static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return -2; } -static int pkey_gost94_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { - if (!value) { - return 0; - } - if (strlen(value) == 1) { - switch (toupper((unsigned char)value[0])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet; - break; - case 'D': - param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet; - break; - default: - return 0; - } - } else if ((strlen(value) == 2) - && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper((unsigned char)value[1])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet; - break; - default: - return 0; - } - } else { - R3410_params *p = R3410_paramset; - param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { - return 0; - } - for (; p->nid != NID_undef; p++) { - if (p->nid == param_nid) - break; - } - if (p->nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST94_CTRL_STR, GOST_R_INVALID_PARAMSET); - return 0; - } - } - - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, NULL); - } - return -2; -} - static int pkey_gost_ec_ctrl_str_256(EVP_PKEY_CTX *ctx, const char *type, const char *value) { int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { + + if (strcmp(type, param_ctrl_string) == 0) { if (!value) { return 0; } @@ -339,23 +269,6 @@ static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) return 1; } -static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - DSA *dsa = NULL; - if (!data || data->sign_param_nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET); - return 0; - } - dsa = DSA_new(); - if (!fill_GOST94_params(dsa, data->sign_param_nid) - || !EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) { - DSA_free(dsa); - return 0; - } - return 1; -} - static int pkey_gost2001_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); @@ -392,25 +305,19 @@ static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return 0; } - switch (data->sign_param_nid) { - case NID_id_tc26_gost_3410_2012_512_paramSetA: - case NID_id_tc26_gost_3410_2012_512_paramSetB: + if (data->sign_param_nid == NID_id_tc26_gost_3410_2012_512_paramSetA || + data->sign_param_nid == NID_id_tc26_gost_3410_2012_512_paramSetB) { result = - (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_512, ec)) ? 1 : 0; - break; - - case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: - case NID_id_GostR3410_2001_CryptoPro_B_ParamSet: - case NID_id_GostR3410_2001_CryptoPro_C_ParamSet: - case NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet: - case NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet: - case NID_id_GostR3410_2001_TestParamSet: + (EVP_PKEY_assign(pkey, NID_gost2012_512, ec)) ? 1 : 0; + } else + if (data->sign_param_nid == NID_id_GostR3410_2001_CryptoPro_A_ParamSet || + data->sign_param_nid == NID_id_GostR3410_2001_CryptoPro_B_ParamSet || + data->sign_param_nid == NID_id_GostR3410_2001_CryptoPro_C_ParamSet || + data->sign_param_nid == NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet || + data->sign_param_nid == NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet || + data->sign_param_nid == NID_id_GostR3410_2001_TestParamSet) { result = - (EVP_PKEY_assign(pkey, NID_id_GostR3410_2012_256, ec)) ? 1 : 0; - break; - default: - result = 0; - break; + (EVP_PKEY_assign(pkey, NID_gost2012_256, ec)) ? 1 : 0; } if (result == 0) @@ -420,17 +327,6 @@ static int pkey_gost2012_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) } /* ----------- keygen callbacks --------------------------------------*/ -/* Generates Gost_R3410_94_cp key */ -static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DSA *dsa; - if (!pkey_gost94_paramgen(ctx, pkey)) - return 0; - dsa = EVP_PKEY_get0(pkey); - gost_sign_keygen(dsa); - return 1; -} - /* Generates GOST_R3410 2001 key and assigns it using specified type */ static int pkey_gost2001cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { @@ -453,24 +349,18 @@ static int pkey_gost2012cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) } /* ----------- sign callbacks --------------------------------------*/ - -static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbs_len) +/* + * Packs signature according to Cryptopro rules + * and frees up DSA_SIG structure + */ +int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) { - DSA_SIG *unpacked_sig = NULL; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!siglen) - return 0; - if (!sig) { - *siglen = 64; /* better to check size of pkey->pkey.dsa-q */ - return 1; - } - unpacked_sig = gost_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { - return 0; - } - return pack_sign_cp(unpacked_sig, 32, sig, siglen); + *siglen = 2 * order; + memset(sig, 0, *siglen); + store_bignum(s->s, sig, order); + store_bignum(s->r, sig + order, order); + DSA_SIG_free(s); + return 1; } static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, @@ -480,21 +370,18 @@ static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, DSA_SIG *unpacked_sig = NULL; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); int order = 0; - + int id = EVP_PKEY_base_id(pkey); if (!siglen) return 0; if (!pkey) return 0; - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2012_256: + if (id == NID_id_GostR3410_2001 || + id == NID_gost2012_256) { order = 64; - break; - case NID_id_GostR3410_2012_512: + } else if (id == NID_gost2012_512) { order = 128; - break; - default: + } else { return 0; } @@ -510,20 +397,19 @@ static int pkey_gost_ec_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, } /* ------------------- verify callbacks ---------------------------*/ - -static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) +/* Unpack signature according to cryptopro rules */ +DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen) { - int ok = 0; - EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s = (sig) ? unpack_cp_signature(sig, siglen) : NULL; - if (!s) - return 0; - if (pub_key) - ok = gost_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); - DSA_SIG_free(s); - return ok; + DSA_SIG *s; + + s = DSA_SIG_new(); + if (s == NULL) { + GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, ERR_R_MALLOC_FAILURE); + return NULL; + } + s->s = BN_bin2bn(sig, siglen / 2, NULL); + s->r = BN_bin2bn(sig + siglen / 2, siglen / 2, NULL); + return s; } static int pkey_gost_ec_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, @@ -564,11 +450,12 @@ static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) { - struct gost_mac_pmeth_data *data; - data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); + struct gost_mac_pmeth_data *data = OPENSSL_malloc(sizeof(*data)); + if (!data) return 0; - memset(data, 0, sizeof(struct gost_mac_pmeth_data)); + memset(data, 0, sizeof(*data)); + data->mac_size = 4; EVP_PKEY_CTX_set_data(ctx, data); return 1; } @@ -612,7 +499,6 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) data->md = (EVP_MD *)p2; return 1; } - break; case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = data->md; @@ -653,6 +539,17 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) } return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key); } + case EVP_PKEY_CTRL_MAC_LEN: + { + if (p1<1 || p1>8) + { + + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL,GOST_R_INVALID_MAC_SIZE); + return 0; + } + data->mac_size = p1; + return 1; + } } return -2; } @@ -660,7 +557,7 @@ static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) { - if (!strcmp(type, key_ctrl_string)) { + if (strcmp(type, key_ctrl_string) == 0) { if (strlen(value) != 32) { GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, GOST_R_INVALID_MAC_KEY_LENGTH); @@ -669,8 +566,8 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, (char *)value); } - if (!strcmp(type, hexkey_ctrl_string)) { - long keylen = 0; + if (strcmp(type, hexkey_ctrl_string) == 0) { + long keylen; int ret; unsigned char *keybuf = string_to_hex(value, &keylen); if (!keybuf || keylen != 32) { @@ -684,6 +581,16 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, return ret; } + if (!strcmp(type,maclen_ctrl_string)) { + char *endptr; + long size=strtol(value,&endptr,10); + if (*endptr!='\0') { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_SIZE); + return 0; + } + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_MAC_LEN,size,NULL); + } return -2; } @@ -697,7 +604,7 @@ static int pkey_gost_mac_keygen_base(EVP_PKEY_CTX *ctx, return 0; } keydata = OPENSSL_malloc(32); - if (!keydata) + if (keydata == NULL) return 0; memcpy(keydata, data->key, 32); EVP_PKEY_assign(pkey, mac_nid, keydata); @@ -724,6 +631,7 @@ static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, { unsigned int tmpsiglen; int ret; + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); if (!siglen) return 0; @@ -731,11 +639,13 @@ static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, * sizeof(size_t) */ if (!sig) { - *siglen = 4; + *siglen = data->mac_size; return 1; } + + mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_MAC_LEN, data->mac_size, NULL); ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen); - *siglen = tmpsiglen; + *siglen = data->mac_size; return ret; } @@ -746,22 +656,7 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) if (!*pmeth) return 0; - switch (id) { - case NID_id_GostR3410_94: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost94_ctrl_str); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost94cp_keygen); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify); - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, - pkey_GOST94cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); - EVP_PKEY_meth_set_derive(*pmeth, - pkey_gost_derive_init, pkey_gost94_derive); - EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, - pkey_gost94_paramgen); - break; - case NID_id_GostR3410_2001: + if (id == NID_id_GostR3410_2001) { EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256); EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); @@ -777,8 +672,7 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) pkey_gost_derive_init, pkey_gost_ec_derive); EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, pkey_gost2001_paramgen); - break; - case NID_id_GostR3410_2012_256: + } else if (id == NID_gost2012_256) { EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ec_ctrl_str_256); EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); @@ -795,8 +689,7 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, pkey_gost2012_paramgen); - break; - case NID_id_GostR3410_2012_512: + } else if (id == NID_gost2012_512 ) { EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ec_ctrl_str_512); EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost_ec_cp_sign); @@ -813,8 +706,7 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, pkey_gost2012_paramgen); - break; - case NID_id_Gost28147_89_MAC: + } else if (id == NID_id_Gost28147_89_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, @@ -823,8 +715,8 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_init(*pmeth, pkey_gost_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_gost_mac_12: + return 1; + } else if (id == NID_gost_mac_12) { 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, @@ -833,8 +725,9 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) EVP_PKEY_meth_set_init(*pmeth, pkey_gost_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 1; + } else { + /* Unsupported method */ return 0; } EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init);