+ const char *name, const char *value)
+{
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED);
+ return -2;
+ }
+ if (strcmp(name, "digest") == 0)
+ return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD,
+ value);
+ return ctx->pmeth->ctrl_str(ctx, name, value);
+}
+
+/* Utility functions to send a string of hex string to a ctrl */
+
+int EVP_PKEY_CTX_str2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *str)
+{
+ size_t len;
+
+ len = strlen(str);
+ if (len > INT_MAX)
+ return -1;
+ return ctx->pmeth->ctrl(ctx, cmd, len, (void *)str);
+}
+
+int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
+{
+ unsigned char *bin;
+ long binlen;
+ int rv = -1;
+
+ bin = OPENSSL_hexstr2buf(hex, &binlen);
+ if (bin == NULL)
+ return 0;
+ if (binlen <= INT_MAX)
+ rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
+ OPENSSL_free(bin);
+ return rv;
+}
+
+/* Pass a message digest to a ctrl */
+int EVP_PKEY_CTX_md(EVP_PKEY_CTX *ctx, int optype, int cmd, const char *md)
+{
+ const EVP_MD *m;
+
+ if (md == NULL || (m = EVP_get_digestbyname(md)) == NULL) {
+ EVPerr(EVP_F_EVP_PKEY_CTX_MD, EVP_R_INVALID_DIGEST);
+ return 0;
+ }
+ return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, 0, (void *)m);
+}
+
+int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx)
+{
+ return ctx->operation;
+}
+
+void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen)
+{
+ ctx->keygen_info = dat;
+ ctx->keygen_info_count = datlen;
+}
+
+void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
+{
+ ctx->data = data;
+}
+
+void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
+{
+ return ctx->data;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx)
+{
+ return ctx->pkey;
+}
+
+EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx)
+{
+ return ctx->peerkey;
+}
+
+void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
+{
+ ctx->app_data = data;
+}
+
+void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
+{
+ return ctx->app_data;
+}
+
+void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth,
+ int (*init) (EVP_PKEY_CTX *ctx))
+{
+ pmeth->init = init;
+}
+
+void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth,
+ int (*copy) (EVP_PKEY_CTX *dst,
+ EVP_PKEY_CTX *src))
+{
+ pmeth->copy = copy;
+}
+
+void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth,
+ void (*cleanup) (EVP_PKEY_CTX *ctx))
+{
+ pmeth->cleanup = cleanup;
+}
+
+void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth,
+ int (*paramgen_init) (EVP_PKEY_CTX *ctx),
+ int (*paramgen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ pmeth->paramgen_init = paramgen_init;
+ pmeth->paramgen = paramgen;
+}
+
+void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth,
+ int (*keygen_init) (EVP_PKEY_CTX *ctx),
+ int (*keygen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ pmeth->keygen_init = keygen_init;
+ pmeth->keygen = keygen;
+}
+
+void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth,
+ int (*sign_init) (EVP_PKEY_CTX *ctx),
+ int (*sign) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ pmeth->sign_init = sign_init;
+ pmeth->sign = sign;
+}
+
+void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth,
+ int (*verify_init) (EVP_PKEY_CTX *ctx),
+ int (*verify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ pmeth->verify_init = verify_init;
+ pmeth->verify = verify;
+}
+
+void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth,
+ int (*verify_recover_init) (EVP_PKEY_CTX
+ *ctx),
+ int (*verify_recover) (EVP_PKEY_CTX
+ *ctx,
+ unsigned char
+ *sig,
+ size_t *siglen,
+ const unsigned
+ char *tbs,
+ size_t tbslen))
+{
+ pmeth->verify_recover_init = verify_recover_init;
+ pmeth->verify_recover = verify_recover;
+}
+
+void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth,
+ int (*signctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*signctx) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig,
+ size_t *siglen,
+ EVP_MD_CTX *mctx))
+{
+ pmeth->signctx_init = signctx_init;
+ pmeth->signctx = signctx;
+}
+
+void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth,
+ int (*verifyctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (*verifyctx) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ int siglen,
+ EVP_MD_CTX *mctx))
+{
+ pmeth->verifyctx_init = verifyctx_init;
+ pmeth->verifyctx = verifyctx;
+}
+
+void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth,
+ int (*encrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*encryptfn) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ pmeth->encrypt_init = encrypt_init;
+ pmeth->encrypt = encryptfn;
+}
+
+void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth,
+ int (*decrypt_init) (EVP_PKEY_CTX *ctx),
+ int (*decrypt) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ pmeth->decrypt_init = decrypt_init;
+ pmeth->decrypt = decrypt;
+}
+
+void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth,
+ int (*derive_init) (EVP_PKEY_CTX *ctx),
+ int (*derive) (EVP_PKEY_CTX *ctx,
+ unsigned char *key,
+ size_t *keylen))
+{
+ pmeth->derive_init = derive_init;
+ pmeth->derive = derive;
+}
+
+void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
+ int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+ void *p2),
+ int (*ctrl_str) (EVP_PKEY_CTX *ctx,
+ const char *type,
+ const char *value))
+{
+ pmeth->ctrl = ctrl;
+ pmeth->ctrl_str = ctrl_str;
+}
+
+void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
+ int (*check) (EVP_PKEY *pkey))
+{
+ pmeth->check = check;
+}
+
+void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
+ int (*check) (EVP_PKEY *pkey))
+{
+ pmeth->public_check = check;
+}
+
+void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
+ int (*check) (EVP_PKEY *pkey))
+{
+ pmeth->param_check = check;
+}
+
+void EVP_PKEY_meth_get_init(const EVP_PKEY_METHOD *pmeth,
+ int (**pinit) (EVP_PKEY_CTX *ctx))
+{
+ *pinit = pmeth->init;
+}
+
+void EVP_PKEY_meth_get_copy(const EVP_PKEY_METHOD *pmeth,
+ int (**pcopy) (EVP_PKEY_CTX *dst,
+ EVP_PKEY_CTX *src))
+{
+ *pcopy = pmeth->copy;
+}
+
+void EVP_PKEY_meth_get_cleanup(const EVP_PKEY_METHOD *pmeth,
+ void (**pcleanup) (EVP_PKEY_CTX *ctx))
+{
+ *pcleanup = pmeth->cleanup;
+}
+
+void EVP_PKEY_meth_get_paramgen(const EVP_PKEY_METHOD *pmeth,
+ int (**pparamgen_init) (EVP_PKEY_CTX *ctx),
+ int (**pparamgen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ if (pparamgen_init)
+ *pparamgen_init = pmeth->paramgen_init;
+ if (pparamgen)
+ *pparamgen = pmeth->paramgen;
+}
+
+void EVP_PKEY_meth_get_keygen(const EVP_PKEY_METHOD *pmeth,
+ int (**pkeygen_init) (EVP_PKEY_CTX *ctx),
+ int (**pkeygen) (EVP_PKEY_CTX *ctx,
+ EVP_PKEY *pkey))
+{
+ if (pkeygen_init)
+ *pkeygen_init = pmeth->keygen_init;
+ if (pkeygen)
+ *pkeygen = pmeth->keygen;
+}
+
+void EVP_PKEY_meth_get_sign(const EVP_PKEY_METHOD *pmeth,
+ int (**psign_init) (EVP_PKEY_CTX *ctx),
+ int (**psign) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig, size_t *siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ if (psign_init)
+ *psign_init = pmeth->sign_init;
+ if (psign)
+ *psign = pmeth->sign;
+}
+
+void EVP_PKEY_meth_get_verify(const EVP_PKEY_METHOD *pmeth,
+ int (**pverify_init) (EVP_PKEY_CTX *ctx),
+ int (**pverify) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ size_t siglen,
+ const unsigned char *tbs,
+ size_t tbslen))
+{
+ if (pverify_init)
+ *pverify_init = pmeth->verify_init;
+ if (pverify)
+ *pverify = pmeth->verify;
+}
+
+void EVP_PKEY_meth_get_verify_recover(const EVP_PKEY_METHOD *pmeth,
+ int (**pverify_recover_init) (EVP_PKEY_CTX
+ *ctx),
+ int (**pverify_recover) (EVP_PKEY_CTX
+ *ctx,
+ unsigned char
+ *sig,
+ size_t *siglen,
+ const unsigned
+ char *tbs,
+ size_t tbslen))
+{
+ if (pverify_recover_init)
+ *pverify_recover_init = pmeth->verify_recover_init;
+ if (pverify_recover)
+ *pverify_recover = pmeth->verify_recover;
+}
+
+void EVP_PKEY_meth_get_signctx(const EVP_PKEY_METHOD *pmeth,
+ int (**psignctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (**psignctx) (EVP_PKEY_CTX *ctx,
+ unsigned char *sig,
+ size_t *siglen,
+ EVP_MD_CTX *mctx))
+{
+ if (psignctx_init)
+ *psignctx_init = pmeth->signctx_init;
+ if (psignctx)
+ *psignctx = pmeth->signctx;
+}
+
+void EVP_PKEY_meth_get_verifyctx(const EVP_PKEY_METHOD *pmeth,
+ int (**pverifyctx_init) (EVP_PKEY_CTX *ctx,
+ EVP_MD_CTX *mctx),
+ int (**pverifyctx) (EVP_PKEY_CTX *ctx,
+ const unsigned char *sig,
+ int siglen,
+ EVP_MD_CTX *mctx))
+{
+ if (pverifyctx_init)
+ *pverifyctx_init = pmeth->verifyctx_init;
+ if (pverifyctx)
+ *pverifyctx = pmeth->verifyctx;
+}
+
+void EVP_PKEY_meth_get_encrypt(const EVP_PKEY_METHOD *pmeth,
+ int (**pencrypt_init) (EVP_PKEY_CTX *ctx),
+ int (**pencryptfn) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ if (pencrypt_init)
+ *pencrypt_init = pmeth->encrypt_init;
+ if (pencryptfn)
+ *pencryptfn = pmeth->encrypt;
+}
+
+void EVP_PKEY_meth_get_decrypt(const EVP_PKEY_METHOD *pmeth,
+ int (**pdecrypt_init) (EVP_PKEY_CTX *ctx),
+ int (**pdecrypt) (EVP_PKEY_CTX *ctx,
+ unsigned char *out,
+ size_t *outlen,
+ const unsigned char *in,
+ size_t inlen))
+{
+ if (pdecrypt_init)
+ *pdecrypt_init = pmeth->decrypt_init;
+ if (pdecrypt)
+ *pdecrypt = pmeth->decrypt;
+}
+
+void EVP_PKEY_meth_get_derive(const EVP_PKEY_METHOD *pmeth,
+ int (**pderive_init) (EVP_PKEY_CTX *ctx),
+ int (**pderive) (EVP_PKEY_CTX *ctx,
+ unsigned char *key,
+ size_t *keylen))
+{
+ if (pderive_init)
+ *pderive_init = pmeth->derive_init;
+ if (pderive)
+ *pderive = pmeth->derive;
+}
+
+void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth,
+ int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1,
+ void *p2),
+ int (**pctrl_str) (EVP_PKEY_CTX *ctx,
+ const char *type,
+ const char *value))
+{
+ if (pctrl)
+ *pctrl = pmeth->ctrl;
+ if (pctrl_str)
+ *pctrl_str = pmeth->ctrl_str;
+}
+
+void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth,
+ int (**pcheck) (EVP_PKEY *pkey))
+{
+ if (*pcheck)
+ *pcheck = pmeth->check;
+}
+
+void EVP_PKEY_meth_get_public_check(const EVP_PKEY_METHOD *pmeth,
+ int (**pcheck) (EVP_PKEY *pkey))
+{
+ if (*pcheck)
+ *pcheck = pmeth->public_check;
+}
+
+void EVP_PKEY_meth_get_param_check(const EVP_PKEY_METHOD *pmeth,
+ int (**pcheck) (EVP_PKEY *pkey))
+{
+ if (*pcheck)
+ *pcheck = pmeth->param_check;
+}