Convert EC_KEY_derive_from_secret to scopers

I had this this lying around my checkout. Flushing it to Gerrit.

Bug: 394340436
Change-Id: Ifed5dd3a8b53e5fe9398f68bafeccfc7d0ec0056
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/78987
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Auto-Submit: David Benjamin <davidben@google.com>
diff --git a/crypto/ec/ec_derive.cc b/crypto/ec/ec_derive.cc
index 8bea9c9..2d88ac6 100644
--- a/crypto/ec/ec_derive.cc
+++ b/crypto/ec/ec_derive.cc
@@ -31,7 +31,7 @@
   const char *name = EC_curve_nid2nist(EC_GROUP_get_curve_name(group));
   if (name == NULL || strlen(name) > EC_KEY_DERIVE_MAX_NAME_LEN) {
     OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
-    return NULL;
+    return nullptr;
   }
 
   // Assemble a label string to provide some key separation in case |secret| is
@@ -51,7 +51,7 @@
     // (The actual bound is a bit tighter, but our curves are much larger than
     // 128-bit.)
     OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-    return NULL;
+    return nullptr;
   }
 
   uint8_t derived[EC_KEY_DERIVE_EXTRA_BYTES + EC_MAX_BYTES];
@@ -59,38 +59,35 @@
       BN_num_bytes(EC_GROUP_get0_order(group)) + EC_KEY_DERIVE_EXTRA_BYTES;
   assert(derived_len <= sizeof(derived));
   if (!HKDF(derived, derived_len, EVP_sha256(), secret, secret_len,
-            /*salt=*/NULL, /*salt_len=*/0, (const uint8_t *)info,
+            /*salt=*/nullptr, /*salt_len=*/0, (const uint8_t *)info,
             strlen(info))) {
-    return NULL;
+    return nullptr;
   }
 
-  EC_KEY *key = EC_KEY_new();
-  BN_CTX *ctx = BN_CTX_new();
-  BIGNUM *priv = BN_bin2bn(derived, derived_len, NULL);
-  EC_POINT *pub = EC_POINT_new(group);
-  if (key == NULL || ctx == NULL || priv == NULL || pub == NULL ||
+  bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
+  bssl::UniquePtr<BIGNUM> priv(BN_bin2bn(derived, derived_len, nullptr));
+  bssl::UniquePtr<EC_POINT> pub(EC_POINT_new(group));
+  if (key == nullptr || ctx == nullptr || priv == nullptr || pub == nullptr ||
       // Reduce |priv| with Montgomery reduction. First, convert "from"
       // Montgomery form to compute |priv| * R^-1 mod |order|. This requires
       // |priv| be under order * R, which is true if the group order is large
       // enough. 2^(num_bytes(order)) < 2^8 * order, so:
       //
       //    priv < 2^8 * order * 2^128 < order * order < order * R
-      !BN_from_montgomery(priv, priv, &group->order, ctx) ||
+      !BN_from_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) ||
       // Multiply by R^2 and do another Montgomery reduction to compute
       // priv * R^-1 * R^2 * R^-1 = priv mod order.
-      !BN_to_montgomery(priv, priv, &group->order, ctx) ||
-      !EC_POINT_mul(group, pub, priv, NULL, NULL, ctx) ||
-      !EC_KEY_set_group(key, group) || !EC_KEY_set_public_key(key, pub) ||
-      !EC_KEY_set_private_key(key, priv)) {
-    EC_KEY_free(key);
-    key = NULL;
-    goto err;
+      !BN_to_montgomery(priv.get(), priv.get(), &group->order, ctx.get()) ||
+      !EC_POINT_mul(group, pub.get(), priv.get(), nullptr, nullptr,
+                    ctx.get()) ||
+      !EC_KEY_set_group(key.get(), group) ||
+      !EC_KEY_set_public_key(key.get(), pub.get()) ||
+      !EC_KEY_set_private_key(key.get(), priv.get())) {
+    OPENSSL_cleanse(derived, sizeof(derived));
+    return nullptr;
   }
 
-err:
   OPENSSL_cleanse(derived, sizeof(derived));
-  BN_CTX_free(ctx);
-  BN_free(priv);
-  EC_POINT_free(pub);
-  return key;
+  return key.release();
 }