+ case EVP_PKEY_CTRL_EC_PARAM_ENC:
+ if (!dctx->gen_group)
+ {
+ ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET);
+ return 0;
+ }
+ EC_GROUP_set_asn1_flag(dctx->gen_group, p1);
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_ECDH_COFACTOR:
+ if (p1 == -2)
+ {
+ if (dctx->cofactor_mode != -1)
+ return dctx->cofactor_mode;
+ else
+ {
+ EC_KEY *ec_key = ctx->pkey->pkey.ec;
+ return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
+ }
+ }
+ else if (p1 < -1 || p1 > 1)
+ return -2;
+ dctx->cofactor_mode = p1;
+ if (p1 != -1)
+ {
+ EC_KEY *ec_key = ctx->pkey->pkey.ec;
+ if (!ec_key->group)
+ return -2;
+ /* If cofactor is 1 cofactor mode does nothing */
+ if (BN_is_one(&ec_key->group->cofactor))
+ return 1;
+ if (!dctx->co_key)
+ {
+ dctx->co_key = EC_KEY_dup(ec_key);
+ if (!dctx->co_key)
+ return 0;
+ }
+ if (p1)
+ EC_KEY_set_flags(dctx->co_key,
+ EC_FLAG_COFACTOR_ECDH);
+ else
+ EC_KEY_clear_flags(dctx->co_key,
+ EC_FLAG_COFACTOR_ECDH);
+ }
+ else if (dctx->co_key)
+ {
+ EC_KEY_free(dctx->co_key);
+ dctx->co_key = NULL;
+ }
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_KDF_TYPE:
+ if (p1 == -2)
+ return dctx->kdf_type;
+ if (p1 != EVP_PKEY_ECDH_KDF_NONE &&
+ p1 != EVP_PKEY_ECDH_KDF_X9_62)
+ return -2;
+ dctx->kdf_type = p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_KDF_MD:
+ dctx->kdf_md = p2;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_EC_KDF_MD:
+ *(const EVP_MD **)p2 = dctx->kdf_md;
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_KDF_OUTLEN:
+ if (p1 <= 0)
+ return -2;
+ dctx->kdf_outlen = (size_t)p1;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN:
+ *(int *)p2 = dctx->kdf_outlen;
+ return 1;
+
+ case EVP_PKEY_CTRL_EC_KDF_UKM:
+ if (dctx->kdf_ukm)
+ OPENSSL_free(dctx->kdf_ukm);
+ dctx->kdf_ukm = p2;
+ if (p2)
+ dctx->kdf_ukmlen = p1;
+ else
+ dctx->kdf_ukmlen = 0;
+ return 1;
+
+ case EVP_PKEY_CTRL_GET_EC_KDF_UKM:
+ *(unsigned char **)p2 = dctx->kdf_ukm;
+ return dctx->kdf_ukmlen;
+