Port cryptfs to HILD keymaster HAL

Cryptfs uses keymaster for key derivation. Vold has a C++ abstraction
for Keymaster. However, cryptfs, being a pure C implementation, uses
its own abstraction of the keymaster HAL.

This patch expresses cryptfs' keymaster abstraction in terms of
vold's C++ Keymaster abstraction, consolidating the code base to a
single point where the actual keymaster HAL is beeing used.

Test: successfully upgrade bullhead/angler while using FDE and
      having a PIN set
      run vold_cryptfs_scrypt_hidlization_equivalence_test

Bug: 35028230
Bug: 32020919
Change-Id: Ic3b765720be0cf7899dda5005fa89347ffb59b9f
diff --git a/cryptfs.c b/cryptfs.c
index e2606ec..2797409 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -61,12 +61,9 @@
 #include "f2fs_sparseblock.h"
 #include "CheckBattery.h"
 #include "Process.h"
+#include "Keymaster.h"
 
 #include <bootloader_message/bootloader_message.h>
-#include <hardware/keymaster0.h>
-#include <hardware/keymaster1.h>
-
-#define UNUSED __attribute__((unused))
 
 #define UNUSED __attribute__((unused))
 
@@ -108,181 +105,32 @@
 static int  master_key_saved = 0;
 static struct crypt_persist_data *persist_data = NULL;
 
-static int keymaster_init(keymaster0_device_t **keymaster0_dev,
-                          keymaster1_device_t **keymaster1_dev)
-{
-    int rc;
-
-    const hw_module_t* mod;
-    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
-    if (rc) {
-        ALOGE("could not find any keystore module");
-        goto err;
-    }
-
-    SLOGI("keymaster module name is %s", mod->name);
-    SLOGI("keymaster version is %d", mod->module_api_version);
-
-    *keymaster0_dev = NULL;
-    *keymaster1_dev = NULL;
-    if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
-        SLOGI("Found keymaster1 module, using keymaster1 API.");
-        rc = keymaster1_open(mod, keymaster1_dev);
-    } else {
-        SLOGI("Found keymaster0 module, using keymaster0 API.");
-        rc = keymaster0_open(mod, keymaster0_dev);
-    }
-
-    if (rc) {
-        ALOGE("could not open keymaster device in %s (%s)",
-              KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
-        goto err;
-    }
-
-    return 0;
-
-err:
-    *keymaster0_dev = NULL;
-    *keymaster1_dev = NULL;
-    return rc;
-}
-
 /* Should we use keymaster? */
 static int keymaster_check_compatibility()
 {
-    keymaster0_device_t *keymaster0_dev = 0;
-    keymaster1_device_t *keymaster1_dev = 0;
-    int rc = 0;
-
-    if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
-        SLOGE("Failed to init keymaster");
-        rc = -1;
-        goto out;
-    }
-
-    if (keymaster1_dev) {
-        rc = 1;
-        goto out;
-    }
-
-    if (!keymaster0_dev || !keymaster0_dev->common.module) {
-        rc = -1;
-        goto out;
-    }
-
-    // TODO(swillden): Check to see if there's any reason to require v0.3.  I think v0.1 and v0.2
-    // should work.
-    if (keymaster0_dev->common.module->module_api_version
-            < KEYMASTER_MODULE_API_VERSION_0_3) {
-        rc = 0;
-        goto out;
-    }
-
-    if (!(keymaster0_dev->flags & KEYMASTER_SOFTWARE_ONLY) &&
-        (keymaster0_dev->flags & KEYMASTER_BLOBS_ARE_STANDALONE)) {
-        rc = 1;
-    }
-
-out:
-    if (keymaster1_dev) {
-        keymaster1_close(keymaster1_dev);
-    }
-    if (keymaster0_dev) {
-        keymaster0_close(keymaster0_dev);
-    }
-    return rc;
+    return keymaster_compatibility_cryptfs_scrypt();
 }
 
 /* Create a new keymaster key and store it in this footer */
 static int keymaster_create_key(struct crypt_mnt_ftr *ftr)
 {
-    uint8_t* key = 0;
-    keymaster0_device_t *keymaster0_dev = 0;
-    keymaster1_device_t *keymaster1_dev = 0;
-
     if (ftr->keymaster_blob_size) {
         SLOGI("Already have key");
         return 0;
     }
 
-    if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
-        SLOGE("Failed to init keymaster");
+    int rc = keymaster_create_key_for_cryptfs_scrypt(RSA_KEY_SIZE, RSA_EXPONENT,
+            KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob, KEYMASTER_BLOB_SIZE,
+            &ftr->keymaster_blob_size);
+    if (rc) {
+        if (ftr->keymaster_blob_size > KEYMASTER_BLOB_SIZE) {
+            SLOGE("Keymaster key blob to large)");
+            ftr->keymaster_blob_size = 0;
+        }
+        SLOGE("Failed to generate keypair");
         return -1;
     }
-
-    int rc = 0;
-    size_t key_size = 0;
-    if (keymaster1_dev) {
-        keymaster_key_param_t params[] = {
-            /* Algorithm & size specifications.  Stick with RSA for now.  Switch to AES later. */
-            keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA),
-            keymaster_param_int(KM_TAG_KEY_SIZE, RSA_KEY_SIZE),
-            keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, RSA_EXPONENT),
-
-	    /* The only allowed purpose for this key is signing. */
-	    keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN),
-
-            /* Padding & digest specifications. */
-            keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
-            keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
-
-            /* Require that the key be usable in standalone mode.  File system isn't available. */
-            keymaster_param_enum(KM_TAG_BLOB_USAGE_REQUIREMENTS, KM_BLOB_STANDALONE),
-
-            /* No auth requirements, because cryptfs is not yet integrated with gatekeeper. */
-            keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED),
-
-            /* Rate-limit key usage attempts, to rate-limit brute force */
-            keymaster_param_int(KM_TAG_MIN_SECONDS_BETWEEN_OPS, KEYMASTER_CRYPTFS_RATE_LIMIT),
-        };
-        keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
-        keymaster_key_blob_t key_blob;
-        keymaster_error_t error = keymaster1_dev->generate_key(keymaster1_dev, &param_set,
-                                                               &key_blob,
-                                                               NULL /* characteristics */);
-        if (error != KM_ERROR_OK) {
-            SLOGE("Failed to generate keymaster1 key, error %d", error);
-            rc = -1;
-            goto out;
-        }
-
-        key = (uint8_t*)key_blob.key_material;
-        key_size = key_blob.key_material_size;
-    }
-    else if (keymaster0_dev) {
-        keymaster_rsa_keygen_params_t params;
-        memset(&params, '\0', sizeof(params));
-        params.public_exponent = RSA_EXPONENT;
-        params.modulus_size = RSA_KEY_SIZE;
-
-        if (keymaster0_dev->generate_keypair(keymaster0_dev, TYPE_RSA, &params,
-                                             &key, &key_size)) {
-            SLOGE("Failed to generate keypair");
-            rc = -1;
-            goto out;
-        }
-    } else {
-        SLOGE("Cryptfs bug: keymaster_init succeeded but didn't initialize a device");
-        rc = -1;
-        goto out;
-    }
-
-    if (key_size > KEYMASTER_BLOB_SIZE) {
-        SLOGE("Keymaster key too large for crypto footer");
-        rc = -1;
-        goto out;
-    }
-
-    memcpy(ftr->keymaster_blob, key, key_size);
-    ftr->keymaster_blob_size = key_size;
-
-out:
-    if (keymaster0_dev)
-        keymaster0_close(keymaster0_dev);
-    if (keymaster1_dev)
-        keymaster1_close(keymaster1_dev);
-    free(key);
-    return rc;
+    return 0;
 }
 
 /* This signs the given object using the keymaster key. */
@@ -292,15 +140,6 @@
                                  unsigned char **signature,
                                  size_t *signature_size)
 {
-    int rc = 0;
-    keymaster0_device_t *keymaster0_dev = 0;
-    keymaster1_device_t *keymaster1_dev = 0;
-    if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
-        SLOGE("Failed to init keymaster");
-        rc = -1;
-        goto out;
-    }
-
     unsigned char to_sign[RSA_KEY_SIZE_BYTES];
     size_t to_sign_size = sizeof(to_sign);
     memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
@@ -332,91 +171,10 @@
             break;
         default:
             SLOGE("Unknown KDF type %d", ftr->kdf_type);
-            rc = -1;
-            goto out;
+            return -1;
     }
-
-    if (keymaster0_dev) {
-        keymaster_rsa_sign_params_t params;
-        params.digest_type = DIGEST_NONE;
-        params.padding_type = PADDING_NONE;
-
-        rc = keymaster0_dev->sign_data(keymaster0_dev,
-                                      &params,
-                                      ftr->keymaster_blob,
-                                      ftr->keymaster_blob_size,
-                                      to_sign,
-                                      to_sign_size,
-                                      signature,
-                                      signature_size);
-        goto out;
-    } else if (keymaster1_dev) {
-        keymaster_key_blob_t key = { ftr->keymaster_blob, ftr->keymaster_blob_size };
-        keymaster_key_param_t params[] = {
-            keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE),
-            keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE),
-        };
-        keymaster_key_param_set_t param_set = { params, sizeof(params)/sizeof(*params) };
-        keymaster_operation_handle_t op_handle;
-        keymaster_error_t error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
-                                                        &param_set, NULL /* out_params */,
-                                                        &op_handle);
-        if (error == KM_ERROR_KEY_RATE_LIMIT_EXCEEDED) {
-            // Key usage has been rate-limited.  Wait a bit and try again.
-            sleep(KEYMASTER_CRYPTFS_RATE_LIMIT);
-            error = keymaster1_dev->begin(keymaster1_dev, KM_PURPOSE_SIGN, &key,
-                                          &param_set, NULL /* out_params */,
-                                          &op_handle);
-        }
-        if (error != KM_ERROR_OK) {
-            SLOGE("Error starting keymaster signature transaction: %d", error);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t input = { to_sign, to_sign_size };
-        size_t input_consumed;
-        error = keymaster1_dev->update(keymaster1_dev, op_handle, NULL /* in_params */,
-                                       &input, &input_consumed, NULL /* out_params */,
-                                       NULL /* output */);
-        if (error != KM_ERROR_OK) {
-            SLOGE("Error sending data to keymaster signature transaction: %d", error);
-            rc = -1;
-            goto out;
-        }
-        if (input_consumed != to_sign_size) {
-            // This should never happen.  If it does, it's a bug in the keymaster implementation.
-            SLOGE("Keymaster update() did not consume all data.");
-            keymaster1_dev->abort(keymaster1_dev, op_handle);
-            rc = -1;
-            goto out;
-        }
-
-        keymaster_blob_t tmp_sig;
-        error = keymaster1_dev->finish(keymaster1_dev, op_handle, NULL /* in_params */,
-                                       NULL /* verify signature */, NULL /* out_params */,
-                                       &tmp_sig);
-        if (error != KM_ERROR_OK) {
-            SLOGE("Error finishing keymaster signature transaction: %d", error);
-            rc = -1;
-            goto out;
-        }
-
-        *signature = (uint8_t*)tmp_sig.data;
-        *signature_size = tmp_sig.data_length;
-    } else {
-        SLOGE("Cryptfs bug: keymaster_init succeded but didn't initialize a device.");
-        rc = -1;
-        goto out;
-    }
-
-    out:
-        if (keymaster1_dev)
-            keymaster1_close(keymaster1_dev);
-        if (keymaster0_dev)
-            keymaster0_close(keymaster0_dev);
-
-        return rc;
+    return keymaster_sign_object_for_cryptfs_scrypt(ftr->keymaster_blob, ftr->keymaster_blob_size,
+            KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign, to_sign_size, signature, signature_size);
 }
 
 /* Store password when userdata is successfully decrypted and mounted.