Following the license change, modify the boilerplates in crypto/ec/
[openssl.git] / crypto / ec / ecx_meth.c
index 272dfc6b2b20b128b65ffd66c0dcc535971d25ab..fbe972722c9630aa00cde7e9bcb39b6455a7bf9b 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
  *
- * Licensed under the OpenSSL license (the "License").  You may not use
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
  * in the file LICENSE in the source distribution or at
  * https://www.openssl.org/source/license.html
@@ -331,8 +331,18 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
         }
         return 0;
 
+    default:
+        return -2;
+
+    }
+}
+
+static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
-        *(int *)arg2 = NID_sha256;
+        /* We currently only support Pure EdDSA which takes no digest */
+        *(int *)arg2 = NID_undef;
         return 2;
 
     default:
@@ -341,6 +351,60 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
     }
 }
 
+static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
+                            size_t len)
+{
+    return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
+                       KEY_OP_PRIVATE);
+}
+
+static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
+{
+    return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
+                      KEY_OP_PUBLIC);
+}
+
+static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
+                            size_t *len)
+{
+    const ECX_KEY *key = pkey->pkey.ecx;
+
+    if (priv == NULL) {
+        *len = KEYLENID(pkey->ameth->pkey_id);
+        return 1;
+    }
+
+    if (key == NULL
+            || key->privkey == NULL
+            || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
+        return 0;
+
+    *len = KEYLENID(pkey->ameth->pkey_id);
+    memcpy(priv, key->privkey, *len);
+
+    return 1;
+}
+
+static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
+                           size_t *len)
+{
+    const ECX_KEY *key = pkey->pkey.ecx;
+
+    if (pub == NULL) {
+        *len = KEYLENID(pkey->ameth->pkey_id);
+        return 1;
+    }
+
+    if (key == NULL
+            || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
+        return 0;
+
+    *len = KEYLENID(pkey->ameth->pkey_id);
+    memcpy(pub, key->pubkey, *len);
+
+    return 1;
+}
+
 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
     EVP_PKEY_X25519,
     EVP_PKEY_X25519,
@@ -368,7 +432,20 @@ const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
     ecx_free,
     ecx_ctrl,
     NULL,
-    NULL
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
+    ecx_get_priv_key,
+    ecx_get_pub_key,
 };
 
 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
@@ -398,7 +475,20 @@ const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
     ecx_free,
     ecx_ctrl,
     NULL,
-    NULL
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
+    ecx_get_priv_key,
+    ecx_get_pub_key,
 };
 
 static int ecd_size25519(const EVP_PKEY *pkey)
@@ -499,12 +589,21 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
     0, 0,
 
     ecx_free,
-    0,
+    ecd_ctrl,
     NULL,
     NULL,
     ecd_item_verify,
     ecd_item_sign25519,
-    ecd_sig_info_set25519
+    ecd_sig_info_set25519,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
+    ecx_get_priv_key,
+    ecx_get_pub_key,
 };
 
 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
@@ -532,12 +631,21 @@ const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
     0, 0,
 
     ecx_free,
-    0,
+    ecd_ctrl,
     NULL,
     NULL,
     ecd_item_verify,
     ecd_item_sign448,
-    ecd_sig_info_set448
+    ecd_sig_info_set448,
+
+    NULL,
+    NULL,
+    NULL,
+
+    ecx_set_priv_key,
+    ecx_set_pub_key,
+    ecx_get_priv_key,
+    ecx_get_pub_key,
 };
 
 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
@@ -698,7 +806,7 @@ static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
     switch (type) {
     case EVP_PKEY_CTRL_MD:
         /* Only NULL allowed as digest */
-        if (p2 == NULL)
+        if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
             return 1;
         ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
         return 0;