summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/dh/dh_pmeth.c2
-rw-r--r--crypto/dsa/dsa_pmeth.c2
-rw-r--r--crypto/evp/evp.h2
-rw-r--r--crypto/evp/evp_err.c2
-rw-r--r--crypto/evp/evp_locl.h5
-rw-r--r--crypto/evp/pmeth_fn.c35
-rw-r--r--crypto/evp/pmeth_lib.c1
-rw-r--r--crypto/rsa/rsa_pmeth.c2
8 files changed, 51 insertions, 0 deletions
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index 28624ccd64..d2e6aaff1e 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -209,6 +209,8 @@ const EVP_PKEY_METHOD dh_pkey_meth =
0,0,
+ 0,0,
+
pkey_dh_ctrl,
pkey_dh_ctrl_str
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 364ba15a12..306af267bb 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -245,6 +245,8 @@ const EVP_PKEY_METHOD dsa_pkey_meth =
0,0,
+ 0,0,
+
pkey_dsa_ctrl,
pkey_dsa_ctrl_str
diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
index bb2d815f2d..d60781696a 100644
--- a/crypto/evp/evp.h
+++ b/crypto/evp/evp.h
@@ -1016,6 +1016,8 @@ void ERR_load_EVP_strings(void);
#define EVP_F_EVP_PKEY_DECRYPT 104
#define EVP_F_EVP_PKEY_DECRYPT_INIT 138
#define EVP_F_EVP_PKEY_DECRYPT_OLD 151
+#define EVP_F_EVP_PKEY_DERIVE 153
+#define EVP_F_EVP_PKEY_DERIVE_INIT 154
#define EVP_F_EVP_PKEY_ENCRYPT 105
#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139
#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152
diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
index 97e5996a5f..50d5a71276 100644
--- a/crypto/evp/evp_err.c
+++ b/crypto/evp/evp_err.c
@@ -95,6 +95,8 @@ static ERR_STRING_DATA EVP_str_functs[]=
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"},
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"},
{ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_DERIVE"},
+{ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_DERIVE_INIT"},
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"},
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"},
{ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"},
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 3edfd9949f..fb1ebf4c80 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -241,6 +241,8 @@ struct evp_pkey_ctx_st
const EVP_PKEY_METHOD *pmeth;
/* Key: may be NULL */
EVP_PKEY *pkey;
+ /* Peer key for key agreement, may be NULL */
+ EVP_PKEY *peerkey;
/* Actual operation */
int operation;
/* Algorithm specific data */
@@ -297,6 +299,9 @@ struct evp_pkey_method_st
int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, int *outlen,
const unsigned char *in, int inlen);
+ int (*derive_init)(EVP_PKEY_CTX *ctx);
+ int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, int *keylen);
+
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);
diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c
index c7e21485e9..0ad8098718 100644
--- a/crypto/evp/pmeth_fn.c
+++ b/crypto/evp/pmeth_fn.c
@@ -243,3 +243,38 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
}
+
+int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx)
+ {
+ int ret;
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+ {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ ctx->operation = EVP_PKEY_OP_DERIVE;
+ if (!ctx->pmeth->derive_init)
+ return 1;
+ ret = ctx->pmeth->derive_init(ctx);
+ if (ret <= 0)
+ ctx->operation = EVP_PKEY_OP_UNDEFINED;
+ return ret;
+ }
+
+int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, int *pkeylen)
+ {
+ if (!ctx || !ctx->pmeth || !ctx->pmeth->derive)
+ {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE,
+ EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ return -2;
+ }
+ if (ctx->operation != EVP_PKEY_OP_DERIVE)
+ {
+ EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED);
+ return -1;
+ }
+ return ctx->pmeth->derive(ctx, key, pkeylen);
+ }
+
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index d54dd4e966..95b1e4ed3c 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -120,6 +120,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
ret->pmeth = pmeth;
ret->operation = EVP_PKEY_OP_UNDEFINED;
ret->pkey = pkey;
+ ret->peerkey = NULL;
if (pkey)
CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
ret->data = NULL;
diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c
index 3eebdf58bf..5f357b98c6 100644
--- a/crypto/rsa/rsa_pmeth.c
+++ b/crypto/rsa/rsa_pmeth.c
@@ -524,6 +524,8 @@ const EVP_PKEY_METHOD rsa_pkey_meth =
0,
pkey_rsa_decrypt,
+ 0,0,
+
pkey_rsa_ctrl,
pkey_rsa_ctrl_str