Add delete_all to keymaster API

In order to aid keymasters erase their memory efficiently, introduce new
delete_all API to tell keymasters to forget everything. This will be
triggered when keystore itself is told to reset.

Change-Id: I730375f1f32cd1ea0bf1fa38d5b1bec2f81ba492
diff --git a/include/hardware/keymaster.h b/include/hardware/keymaster.h
index 3c7799a..5a7a374 100644
--- a/include/hardware/keymaster.h
+++ b/include/hardware/keymaster.h
@@ -122,11 +122,27 @@
 
     /**
      * Deletes the key pair associated with the key blob.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
      */
     int (*delete_keypair)(const struct keymaster_device* dev,
             const uint8_t* key_blob, const size_t key_blob_length);
 
     /**
+     * Deletes all keys in the hardware keystore. Used when keystore is
+     * reset completely.
+     *
+     * This function is optional and should be set to NULL if it is not
+     * implemented.
+     *
+     * Returns 0 on success or an error code less than 0.
+     */
+    int (*delete_all)(const struct keymaster_device* dev);
+
+    /**
      * Signs data using a key-blob generated before. This can use either
      * an asymmetric key or a secret key.
      *
diff --git a/tests/keymaster/keymaster_test.cpp b/tests/keymaster/keymaster_test.cpp
index 98e9407..f4cfcd2 100644
--- a/tests/keymaster/keymaster_test.cpp
+++ b/tests/keymaster/keymaster_test.cpp
@@ -751,4 +751,43 @@
             << "Should fail on null signature";
 }
 
+TEST_F(KeymasterTest, EraseAll_Success) {
+    uint8_t *key1_blob, *key2_blob;
+    size_t key1_blob_length, key2_blob_length;
+
+    // Only test this if the device says it supports delete_all
+    if (sDevice->delete_all == NULL) {
+        return;
+    }
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1),
+                    &key1_blob, &key1_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key1(&sDevice, key1_blob, key1_blob_length);
+
+    ASSERT_EQ(0,
+            sDevice->import_keypair(sDevice, TEST_KEY_1, sizeof(TEST_KEY_1),
+                    &key2_blob, &key2_blob_length))
+            << "Should successfully import an RSA key";
+    UniqueKey key2(&sDevice, key2_blob, key2_blob_length);
+
+    EXPECT_EQ(0, sDevice->delete_all(sDevice))
+            << "Should erase all keys";
+
+    key1.reset();
+
+    uint8_t* x509_data;
+    size_t x509_data_length;
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key1_blob, key1_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key 1 successfully";
+
+    ASSERT_EQ(-1,
+            sDevice->get_keypair_public(sDevice, key2_blob, key2_blob_length,
+                    &x509_data, &x509_data_length))
+            << "Should be able to retrieve RSA public key 2 successfully";
+}
+
 }