ECDH encryption module

Add a module for encrypting using ECDH, HKDF, and AES-GCM.
Also, add serialization of EC private keys, and remove derivation
from secrets; it turns out this is a better fit for the way
superencryption currently works.

Add a more thorough ECDH test in the crypto module, which simulates an
ephemeral key being used to send a message to a long-term key. The
high-level module has a similar test.

Bug: 163866361
Test: keystore2_crypto_test_rust, keystore2_test
Change-Id: I4c2bb1d8938de078ea37b930619918acc3c28fbe
diff --git a/keystore2/src/crypto/crypto.cpp b/keystore2/src/crypto/crypto.cpp
index 2e613fd..e4a1ac3 100644
--- a/keystore2/src/crypto/crypto.cpp
+++ b/keystore2/src/crypto/crypto.cpp
@@ -236,10 +236,28 @@
     return key;
 }
 
-EC_KEY* ECKEYDeriveFromSecret(const uint8_t* secret, size_t secret_len) {
+size_t ECKEYMarshalPrivateKey(const EC_KEY* priv_key, uint8_t* buf, size_t len) {
+    CBB cbb;
+    size_t out_len;
+    if (!CBB_init_fixed(&cbb, buf, len) ||
+        !EC_KEY_marshal_private_key(&cbb, priv_key, EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY) ||
+        !CBB_finish(&cbb, nullptr, &out_len)) {
+        return 0;
+    } else {
+        return out_len;
+    }
+}
+
+EC_KEY* ECKEYParsePrivateKey(const uint8_t* buf, size_t len) {
+    CBS cbs;
+    CBS_init(&cbs, buf, len);
     EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
-    auto result = EC_KEY_derive_from_secret(group, secret, secret_len);
+    auto result = EC_KEY_parse_private_key(&cbs, group);
     EC_GROUP_free(group);
+    if (result != nullptr && CBS_len(&cbs) != 0) {
+        EC_KEY_free(result);
+        return nullptr;
+    }
     return result;
 }