Add point ctrls to X25519
authorDr. Stephen Henson <steve@openssl.org>
Wed, 10 Aug 2016 21:30:43 +0000 (22:30 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Sat, 13 Aug 2016 13:11:05 +0000 (14:11 +0100)
Add ctrl operations to set or retrieve encoded point in
EVP_PKEY structures containing X25519 keys.

Reviewed-by: Rich Salz <rsalz@openssl.org>
crypto/ec/ecx_meth.c
crypto/evp/p_lib.c
include/openssl/evp.h

index 271a477..354d387 100644 (file)
@@ -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)
 {
 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) {
 
     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) {
         }
 
         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)
 {
 
 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 = {
 }
 
 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
index 802f6dd..5b776ff 100644 (file)
@@ -451,10 +451,34 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
     return unsup_alg(out, pkey, indent, "Parameters");
 }
 
     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 -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;
 }
 }
index 84df8a0..46a2e26 100644 (file)
@@ -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_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 */
 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_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);
 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);