From 5d6aaf8a9d0c5ad71a4cb5e4bfc3c2fc29f782ba Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Wed, 10 Aug 2016 22:30:43 +0100 Subject: [PATCH] Add point ctrls to X25519 Add ctrl operations to set or retrieve encoded point in EVP_PKEY structures containing X25519 keys. Reviewed-by: Rich Salz --- crypto/ec/ecx_meth.c | 41 +++++++++++++++++++++++++++++++++-------- crypto/evp/p_lib.c | 32 ++++++++++++++++++++++++++++---- include/openssl/evp.h | 7 +++++++ 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 271a4773cc..354d387946 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -35,15 +35,18 @@ typedef enum { static int ecx_key_op(EVP_PKEY *pkey, X509_ALGOR *palg, const unsigned char *p, int plen, ecx_key_op_t op) { - int ptype; - X25519_KEY *xkey = NULL; + X25519_KEY *xkey; if (op != X25519_KEYGEN) { - /* Algorithm parameters must be absent */ - X509_ALGOR_get0(NULL, &ptype, NULL, palg); - if (ptype != V_ASN1_UNDEF) { - ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING); - return 0; + if (palg != NULL) { + int ptype; + + /* Algorithm parameters must be absent */ + X509_ALGOR_get0(NULL, &ptype, NULL, palg); + if (ptype != V_ASN1_UNDEF) { + ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING); + return 0; + } } if (p == NULL || plen != X25519_KEYLEN) { @@ -266,7 +269,29 @@ static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { - return -2; + switch (op) { + + case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: + return ecx_key_op(pkey, NULL, arg2, arg1, X25519_PUBLIC); + + case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: + if (pkey->pkey.ptr != NULL) { + const X25519_KEY *xkey = pkey->pkey.ptr; + unsigned char **ppt = arg2; + *ppt = OPENSSL_memdup(xkey->pubkey, X25519_KEYLEN); + if (*ppt != NULL) + return X25519_KEYLEN; + } + return 0; + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha256; + return 2; + + default: + return -2; + + } } const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = { diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 802f6ddf09..5b776ff6d4 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -451,10 +451,34 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, return unsup_alg(out, pkey, indent, "Parameters"); } -int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) +static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2) { - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) return -2; - return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, - 0, pnid); + return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2); +} + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) +{ + return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid); +} + +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const unsigned char *pt, size_t ptlen) +{ + if (ptlen > INT_MAX) + return 0; + if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen, + (void *)pt) <= 0) + return 0; + return 1; +} + +size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) +{ + int rv; + rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt); + if (rv <= 0) + return 0; + return rv; } diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 84df8a09e7..46a2e263a2 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -959,6 +959,10 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); +int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, + const unsigned char *pt, size_t ptlen); +size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt); + int EVP_CIPHER_type(const EVP_CIPHER *ctx); /* calls methods */ @@ -1028,6 +1032,9 @@ int EVP_PBE_get(int *ptype, int *ppbe_nid, size_t num); # define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 # define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 +# define ASN1_PKEY_CTRL_SET1_TLS_ENCPT 0x9 +# define ASN1_PKEY_CTRL_GET1_TLS_ENCPT 0xa + int EVP_PKEY_asn1_get_count(void); const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); -- 2.34.1