Disallow Ed448 signature malleability
[openssl.git] / crypto / ec / ec_key.c
index 01faa621631fa3f1b799fdc05f151ccc8b35c3e8..637ba141ab2cbbdee202aad865af4e76f4125066 100644 (file)
@@ -1,21 +1,17 @@
 /*
- * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright (c) 2002, Oracle and/or its affiliates. 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
  */
 
-/* ====================================================================
- * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
- * Portions originally developed by SUN MICROSYSTEMS, INC., and
- * contributed to the OpenSSL project.
- */
-
-#include <internal/cryptlib.h>
+#include "internal/cryptlib.h"
 #include <string.h>
 #include "ec_lcl.h"
+#include "internal/refcount.h"
 #include <openssl/err.h>
 #include <openssl/engine.h>
 
@@ -49,13 +45,13 @@ void EC_KEY_free(EC_KEY *r)
     if (r == NULL)
         return;
 
-    CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+    CRYPTO_DOWN_REF(&r->references, &i, r->lock);
     REF_PRINT_COUNT("EC_KEY", r);
     if (i > 0)
         return;
     REF_ASSERT_ISNT(i < 0);
 
-    if (r->meth->finish != NULL)
+    if (r->meth != NULL && r->meth->finish != NULL)
         r->meth->finish(r);
 
 #ifndef OPENSSL_NO_ENGINE
@@ -74,7 +70,7 @@ void EC_KEY_free(EC_KEY *r)
     OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
 }
 
-EC_KEY *EC_KEY_copy(EC_KEY *dest, EC_KEY *src)
+EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src)
 {
     if (dest == NULL || src == NULL) {
         ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER);
@@ -151,7 +147,7 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, EC_KEY *src)
     return dest;
 }
 
-EC_KEY *EC_KEY_dup(EC_KEY *ec_key)
+EC_KEY *EC_KEY_dup(const EC_KEY *ec_key)
 {
     EC_KEY *ret = EC_KEY_new_method(ec_key->engine);
 
@@ -169,7 +165,7 @@ int EC_KEY_up_ref(EC_KEY *r)
 {
     int i;
 
-    if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+    if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
         return 0;
 
     REF_PRINT_COUNT("EC_KEY", r);
@@ -177,6 +173,11 @@ int EC_KEY_up_ref(EC_KEY *r)
     return ((i > 1) ? 1 : 0);
 }
 
+ENGINE *EC_KEY_get0_engine(const EC_KEY *eckey)
+{
+    return eckey->engine;
+}
+
 int EC_KEY_generate_key(EC_KEY *eckey)
 {
     if (eckey == NULL || eckey->group == NULL) {
@@ -191,7 +192,6 @@ int EC_KEY_generate_key(EC_KEY *eckey)
 
 int ossl_ec_key_gen(EC_KEY *eckey)
 {
-    OPENSSL_assert(eckey->group->meth->keygen != NULL);
     return eckey->group->meth->keygen(eckey);
 }
 
@@ -218,7 +218,7 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
         goto err;
 
     do
-        if (!BN_rand_range(priv_key, order))
+        if (!BN_priv_rand_range(priv_key, order))
             goto err;
     while (BN_is_zero(priv_key)) ;
 
@@ -341,9 +341,6 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
     BIGNUM *tx, *ty;
     EC_POINT *point = NULL;
     int ok = 0;
-#ifndef OPENSSL_NO_EC2M
-    int tmp_nid, is_char_two = 0;
-#endif
 
     if (key == NULL || key->group == NULL || x == NULL || y == NULL) {
         ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES,
@@ -365,29 +362,11 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
     if (ty == NULL)
         goto err;
 
-#ifndef OPENSSL_NO_EC2M
-    tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group));
-
-    if (tmp_nid == NID_X9_62_characteristic_two_field)
-        is_char_two = 1;
+    if (!EC_POINT_set_affine_coordinates(key->group, point, x, y, ctx))
+        goto err;
+    if (!EC_POINT_get_affine_coordinates(key->group, point, tx, ty, ctx))
+        goto err;
 
-    if (is_char_two) {
-        if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point,
-                                                  x, y, ctx))
-            goto err;
-        if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point,
-                                                  tx, ty, ctx))
-            goto err;
-    } else
-#endif
-    {
-        if (!EC_POINT_set_affine_coordinates_GFp(key->group, point,
-                                                 x, y, ctx))
-            goto err;
-        if (!EC_POINT_get_affine_coordinates_GFp(key->group, point,
-                                                 tx, ty, ctx))
-            goto err;
-    }
     /*
      * Check if retrieved coordinates match originals and are less than field
      * order: if not values are out of range.
@@ -546,7 +525,7 @@ int EC_KEY_oct2key(EC_KEY *key, const unsigned char *buf, size_t len,
     return 1;
 }
 
-size_t EC_KEY_priv2oct(const EC_KEY *eckey, 
+size_t EC_KEY_priv2oct(const EC_KEY *eckey,
                        unsigned char *buf, size_t len)
 {
     if (eckey->group == NULL || eckey->group->meth == NULL)
@@ -613,12 +592,14 @@ size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf)
 {
     size_t len;
     unsigned char *buf;
+
     len = EC_KEY_priv2oct(eckey, NULL, 0);
     if (len == 0)
         return 0;
-    buf = OPENSSL_malloc(len);
-    if (buf == NULL)
+    if ((buf = OPENSSL_malloc(len)) == NULL) {
+        ECerr(EC_F_EC_KEY_PRIV2BUF, ERR_R_MALLOC_FAILURE);
         return 0;
+    }
     len = EC_KEY_priv2oct(eckey, buf, len);
     if (len == 0) {
         OPENSSL_free(buf);