X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=engines%2Fccgost%2Fgost_pmeth.c;h=f91c9b193908e2aee93af6ffec319195d93a3f5b;hb=174b07be935b934ef60474fa447ca1abc662c4fe;hp=621c209b428bbd5727e7692f1a392c5e8454bb38;hpb=0aa08a2e34bd905d14e2f684df724d4fd925b43b;p=openssl.git diff --git a/engines/ccgost/gost_pmeth.c b/engines/ccgost/gost_pmeth.c index 621c209b42..f91c9b1939 100644 --- a/engines/ccgost/gost_pmeth.c +++ b/engines/ccgost/gost_pmeth.c @@ -22,9 +22,23 @@ 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)); if (!data) return 0; memset(data,0,sizeof(struct gost_pmeth_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: + data->sign_param_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)pkey))); + break; + default: + return 0; + } + } EVP_PKEY_CTX_set_data(ctx,data); return 1; } @@ -40,10 +54,9 @@ static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) src_data = EVP_PKEY_CTX_get_data(src); dst_data = EVP_PKEY_CTX_get_data(dst); *dst_data = *src_data; - if (src_data -> eph_seckey) - { - dst_data ->eph_seckey = NULL; - } + if (src_data -> shared_ukm) { + dst_data->shared_ukm=NULL; + } return 1; } @@ -51,12 +64,12 @@ static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) static void pkey_gost_cleanup (EVP_PKEY_CTX *ctx) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey); + if (data->shared_ukm) OPENSSL_free(data->shared_ukm); OPENSSL_free(data); } /* --------------------- control functions ------------------------------*/ -static int pkey_gost_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_pmeth_data *pctx = (struct gost_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); switch (type) @@ -76,38 +89,33 @@ static int pkey_gost_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2) case EVP_PKEY_CTRL_PKCS7_ENCRYPT: case EVP_PKEY_CTRL_PKCS7_DECRYPT: case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_DIGESTINIT: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: +#endif return 1; case EVP_PKEY_CTRL_GOST_PARAMSET: pctx->sign_param_nid = (int)p1; return 1; - - } - return -2; - } - -static int pkey_gost_ctrl94cc_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) - { - if(!strcmp(type, param_ctrl_string)) - { - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - NID_id_GostR3410_94_CryptoPro_A_ParamSet, - NULL); + case EVP_PKEY_CTRL_SET_IV: + pctx->shared_ukm=OPENSSL_malloc((int)p1); + memcpy(pctx->shared_ukm,p2,(int) p1); + return 1; + case EVP_PKEY_CTRL_PEER_KEY: + if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ + return 1; + if (p1 == 2) /* TLS: peer key used? */ + return pctx->peer_key_used; + if (p1 == 3) /* TLS: peer key used! */ + return (pctx->peer_key_used = 1); + return -2; } return -2; } -static int pkey_gost_ctrl01cc_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) - { - if(!strcmp(type, param_ctrl_string)) - { - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - NID_id_GostR3410_2001_ParamSet_cc,NULL); - } - return -2; - } static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, const char *type, const char *value) @@ -121,7 +129,7 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, } if (strlen(value) == 1) { - switch(toupper(value[0])) + switch(toupper((unsigned char)value[0])) { case 'A': param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; @@ -140,9 +148,9 @@ static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, break; } } - else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper(value[1])) + switch (toupper((unsigned char)value[1])) { case 'A': param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; @@ -196,7 +204,7 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, } if (strlen(value) == 1) { - switch(toupper(value[0])) + switch(toupper((unsigned char)value[0])) { case 'A': param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet; @@ -215,9 +223,9 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, break; } } - else if ((strlen(value) == 2) && (toupper(value[0]) == 'X')) + else if ((strlen(value) == 2) && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper(value[1])) + switch (toupper((unsigned char)value[1])) { case 'A': param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet; @@ -257,23 +265,19 @@ static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, } /* --------------------- key generation --------------------------------*/ -/* Generates GOST 94 key and assigns it setting specified type */ -static int pkey_gost94_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type) + +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->sign_param_nid == NID_undef) { - if (type== NID_id_GostR3410_94_cc) - { - data->sign_param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - } - else - { - GOSTerr(GOST_F_PKEY_GOST94_KEYGEN, + 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)) @@ -281,83 +285,54 @@ static int pkey_gost94_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type) DSA_free(dsa); return 0; } - gost_sign_keygen(dsa); - EVP_PKEY_assign(pkey,type,dsa); + EVP_PKEY_assign(pkey,NID_id_GostR3410_94,dsa); return 1; } - -/* Generates Gost_R3410_94_cc key */ -static int pkey_gost94cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) - { - return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94_cc); - } - -/* Generates Gost_R3410_94_cp key */ -static int pkey_gost94cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) - { - return pkey_gost94_keygen(ctx,pkey,NID_id_GostR3410_94); - } - -/* Generates GOST_R3410 2001 key and assigns it using specified type */ -static int pkey_gost01_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey,int type) +static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); EC_KEY *ec=NULL; + if (data->sign_param_nid == NID_undef) { - if (type == NID_id_GostR3410_2001_cc) - { - data->sign_param_nid = NID_id_GostR3410_2001_ParamSet_cc; - } - else { - GOSTerr(GOST_F_PKEY_GOST01_KEYGEN, + GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); return 0; - } } - ec = EC_KEY_new(); + if (!ec) + ec = EC_KEY_new(); if (!fill_GOST2001_params(ec,data->sign_param_nid)) { EC_KEY_free(ec); return 0; } - gost2001_keygen(ec); - - EVP_PKEY_assign(pkey,type,ec); + EVP_PKEY_assign(pkey,NID_id_GostR3410_2001,ec); return 1; } -/* Generates GOST R3410 2001_cc key */ -static int pkey_gost01cc_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +/* Generates Gost_R3410_94_cp key */ +static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001_cc); + 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_cp key */ -static int pkey_gost01cp_keygen (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +/* Generates GOST_R3410 2001 key and assigns it using specified type */ +static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - return pkey_gost01_keygen(ctx,pkey,NID_id_GostR3410_2001); + EC_KEY *ec; + if (!pkey_gost01_paramgen(ctx,pkey)) return 0; + ec = EVP_PKEY_get0(pkey); + gost2001_keygen(ec); + return 1; } + + /* ----------- sign callbacks --------------------------------------*/ -static int pkey_gost94_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbs_len) - { - 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_cc(unpacked_sig,32,sig,siglen); - } static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbs_len) @@ -378,25 +353,6 @@ static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si return pack_sign_cp(unpacked_sig,32,sig,siglen); } -static int pkey_gost01_cc_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbs_len) - { - 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 curve order*/ - return 1; - } - unpacked_sig = gost2001_do_sign(tbs,tbs_len,EVP_PKEY_get0(pkey)); - if (!unpacked_sig) - { - return 0; - } - return pack_sign_cc(unpacked_sig,32,sig,siglen); - } - static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbs_len) { @@ -417,17 +373,6 @@ static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *si } /* ------------------- verify callbacks ---------------------------*/ -static int pkey_gost94_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, size_t tbs_len) - { - int ok = 0; - EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s=unpack_cc_signature(sig,siglen); - 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; - } 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) @@ -441,24 +386,6 @@ static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, return ok; } -static int pkey_gost01_cc_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, size_t tbs_len) - { - int ok = 0; - EVP_PKEY* pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s=unpack_cc_signature(sig,siglen); -#ifdef DEBUG_SIGN - fprintf(stderr,"R="); - BN_print_fp(stderr,s->r); - fprintf(stderr,"\nS="); - BN_print_fp(stderr,s->s); - fprintf(stderr,"\n"); -#endif - if (!s) return 0; - if (pub_key) ok = gost2001_do_verify(tbs,tbs_len,s,EVP_PKEY_get0(pub_key)); - DSA_SIG_free(s); - return ok; - } static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, size_t tbs_len) @@ -483,31 +410,13 @@ static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, /* Generates ephermeral key */ static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) { - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - EVP_PKEY *eph_key = EVP_PKEY_new(); - EVP_PKEY *old_key =EVP_PKEY_CTX_get0_pkey(ctx); - - if (data->eph_seckey) EVP_PKEY_free(data->eph_seckey); - EVP_PKEY_assign(eph_key,EVP_PKEY_base_id(old_key),NULL); - if (!EVP_PKEY_copy_parameters(eph_key,old_key)) return 0; - switch (EVP_PKEY_base_id(old_key)) - { - case NID_id_GostR3410_2001: - case NID_id_GostR3410_2001_cc: - gost2001_keygen(EVP_PKEY_get0(eph_key)); - break; - case NID_id_GostR3410_94: - case NID_id_GostR3410_94_cc: - gost_sign_keygen(EVP_PKEY_get0(eph_key)); - break; - - - } - - - data->eph_seckey=eph_key; return 1; } +/* --------------- Derive init ------------------------------------*/ +static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) +{ + return 1; +} /* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) { @@ -536,7 +445,7 @@ static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) return 1; } -static int pkey_gost_mac_ctrl (EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { struct gost_mac_pmeth_data *data = (struct gost_mac_pmeth_data*)EVP_PKEY_CTX_get_data(ctx); @@ -618,6 +527,7 @@ static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, { GOSTerr(GOST_F_PKEY_GOST_MAC_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, @@ -670,15 +580,6 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) switch (id) { - case NID_id_GostR3410_94_cc: - EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94cc_str); - EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cc_keygen); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cc_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cc_verify); - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, pkey_GOST94cc_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cc_decrypt); - break; case NID_id_GostR3410_94: EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl94_str); EVP_PKEY_meth_set_keygen(*pmeth,NULL,pkey_gost94cp_keygen); @@ -687,21 +588,10 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, pkey_GOST94cp_encrypt); EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); - - - break; - case NID_id_GostR3410_2001_cc: - EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01cc_str); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cc_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cc_verify); - - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cc_keygen); - - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, pkey_GOST01cc_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cc_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; - /* There is intentionally no break here */ case NID_id_GostR3410_2001: EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_ctrl, pkey_gost_ctrl01_str); EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign); @@ -712,6 +602,9 @@ int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth,int flags) EVP_PKEY_meth_set_encrypt(*pmeth, pkey_gost_encrypt_init, pkey_GOST01cp_encrypt); EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost2001_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init,pkey_gost01_paramgen); break; case NID_id_Gost28147_89_MAC: EVP_PKEY_meth_set_ctrl(*pmeth,pkey_gost_mac_ctrl, pkey_gost_mac_ctrl_str);