Merge "Add JSON output to the RKP factory tool"
diff --git a/keystore2/src/crypto/crypto.cpp b/keystore2/src/crypto/crypto.cpp
index e4a1ac3..5d360a1 100644
--- a/keystore2/src/crypto/crypto.cpp
+++ b/keystore2/src/crypto/crypto.cpp
@@ -225,7 +225,7 @@
 
 EC_KEY* ECKEYGenerateKey() {
     EC_KEY* key = EC_KEY_new();
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     EC_KEY_set_group(key, group);
     auto result = EC_KEY_generate_key(key);
     if (result == 0) {
@@ -251,7 +251,7 @@
 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);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     auto result = EC_KEY_parse_private_key(&cbs, group);
     EC_GROUP_free(group);
     if (result != nullptr && CBS_len(&cbs) != 0) {
@@ -262,7 +262,7 @@
 }
 
 size_t ECPOINTPoint2Oct(const EC_POINT* point, uint8_t* buf, size_t len) {
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     point_conversion_form_t form = POINT_CONVERSION_UNCOMPRESSED;
     auto result = EC_POINT_point2oct(group, point, form, buf, len, nullptr);
     EC_GROUP_free(group);
@@ -270,7 +270,7 @@
 }
 
 EC_POINT* ECPOINTOct2Point(const uint8_t* buf, size_t len) {
-    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+    EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_secp521r1);
     EC_POINT* point = EC_POINT_new(group);
     auto result = EC_POINT_oct2point(group, point, buf, len, nullptr);
     EC_GROUP_free(group);
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
index db23d1f..5f8a2ef 100644
--- a/keystore2/src/crypto/lib.rs
+++ b/keystore2/src/crypto/lib.rs
@@ -346,7 +346,7 @@
 
 /// Calls the boringssl EC_KEY_marshal_private_key function.
 pub fn ec_key_marshal_private_key(key: &ECKey) -> Result<ZVec, Error> {
-    let len = 39; // Empirically observed length of private key
+    let len = 73; // Empirically observed length of private key
     let mut buf = ZVec::new(len)?;
     // Safety: the key is valid.
     // This will not write past the specified length of the buffer; if the
@@ -381,8 +381,8 @@
 
 /// Calls the boringssl EC_POINT_point2oct.
 pub fn ec_point_point_to_oct(point: &EC_POINT) -> Result<Vec<u8>, Error> {
-    // We fix the length to 65 (1 + 2 * field_elem_size), as we get an error if it's too small.
-    let len = 65;
+    // We fix the length to 133 (1 + 2 * field_elem_size), as we get an error if it's too small.
+    let len = 133;
     let mut buf = vec![0; len];
     // Safety: EC_POINT_point2oct writes at most len bytes. The point is valid.
     let result = unsafe { ECPOINTPoint2Oct(point, buf.as_mut_ptr(), len) };
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index 9fb267a..e02d9bc 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -68,8 +68,8 @@
 pub enum SuperEncryptionAlgorithm {
     /// Symmetric encryption with AES-256-GCM
     Aes256Gcm,
-    /// Public-key encryption with ECDH P-256
-    EcdhP256,
+    /// Public-key encryption with ECDH P-521
+    EcdhP521,
 }
 
 /// A particular user may have several superencryption keys in the database, each for a
@@ -96,9 +96,9 @@
 /// Key used for ScreenLockBound keys; the corresponding superencryption key is loaded in memory
 /// each time the user enters their LSKF, and cleared from memory each time the device is locked.
 /// Asymmetric, so keys can be encrypted when the device is locked.
-pub const USER_SCREEN_LOCK_BOUND_ECDH_KEY: SuperKeyType = SuperKeyType {
-    alias: "USER_SCREEN_LOCK_BOUND_ECDH_KEY",
-    algorithm: SuperEncryptionAlgorithm::EcdhP256,
+pub const USER_SCREEN_LOCK_BOUND_P521_KEY: SuperKeyType = SuperKeyType {
+    alias: "USER_SCREEN_LOCK_BOUND_P521_KEY",
+    algorithm: SuperEncryptionAlgorithm::EcdhP521,
 };
 
 /// Superencryption to apply to a new key.
@@ -468,7 +468,7 @@
                     tag.is_some(),
                 )),
             },
-            SuperEncryptionAlgorithm::EcdhP256 => {
+            SuperEncryptionAlgorithm::EcdhP521 => {
                 match (metadata.public_key(), metadata.salt(), metadata.iv(), metadata.aead_tag()) {
                     (Some(public_key), Some(salt), Some(iv), Some(aead_tag)) => {
                         ECDHPrivateKey::from_private_key(&key.key)
@@ -753,7 +753,7 @@
                 } else {
                     // Symmetric key is not available, use public key encryption
                     let loaded =
-                        db.load_super_key(&USER_SCREEN_LOCK_BOUND_ECDH_KEY, user_id).context(
+                        db.load_super_key(&USER_SCREEN_LOCK_BOUND_P521_KEY, user_id).context(
                             "In handle_super_encryption_on_key_init: load_super_key failed.",
                         )?;
                     let (key_id_guard, key_entry) = loaded.ok_or_else(Error::sys).context(
@@ -836,7 +836,7 @@
                         .context("In get_or_create_super_key: Failed to generate AES 256 key.")?,
                     None,
                 ),
-                SuperEncryptionAlgorithm::EcdhP256 => {
+                SuperEncryptionAlgorithm::EcdhP521 => {
                     let key = ECDHPrivateKey::generate()
                         .context("In get_or_create_super_key: Failed to generate ECDH key")?;
                     (
@@ -903,7 +903,7 @@
                 Self::get_or_create_super_key(
                     db,
                     user_id,
-                    &USER_SCREEN_LOCK_BOUND_ECDH_KEY,
+                    &USER_SCREEN_LOCK_BOUND_P521_KEY,
                     password,
                     Some(aes.clone()),
                 )