Add a function to derive an EC key from some input secret.

Chrome sync folks need to do this. Add a function for it. There doesn't
seem to be a standard way to do it, so pick something arbitrary.

Bug: chromium:1010968
Change-Id: Ib55456e4af5849cd9da33f397e8f12deb6f02917
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/38144
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h
index be0faaf8..1bc6d30 100644
--- a/include/openssl/ec_key.h
+++ b/include/openssl/ec_key.h
@@ -130,7 +130,7 @@
 // EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns
 // one on success and zero otherwise. |key| must already have had a group
 // configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|).
-OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv);
+OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv);
 
 // EC_KEY_get0_public_key returns a pointer to the public key point inside
 // |key|.
@@ -195,6 +195,20 @@
 // additional checks for FIPS compliance.
 OPENSSL_EXPORT int EC_KEY_generate_key_fips(EC_KEY *key);
 
+// EC_KEY_derive_from_secret deterministically derives a private key for |group|
+// from an input secret using HKDF-SHA256. It returns a newly-allocated |EC_KEY|
+// on success or NULL on error. |secret| must not be used in any other
+// algorithm. If using a base secret for multiple operations, derive separate
+// values with a KDF such as HKDF first.
+//
+// Note this function implements an arbitrary derivation scheme, rather than any
+// particular standard one. New protocols are recommended to use X25519 and
+// Ed25519, which have standard byte import functions. See
+// |X25519_public_from_private| and |ED25519_keypair_from_seed|.
+OPENSSL_EXPORT EC_KEY *EC_KEY_derive_from_secret(const EC_GROUP *group,
+                                                 const uint8_t *secret,
+                                                 size_t secret_len);
+
 
 // Serialisation.