OSDN Git Service

Merge "Removed HW encryption build flags and related code." am: bf8518056d am: 95dc63...
[android-x86/system-vold.git] / cryptfs.c
index 6dd56cb..067c025 100644 (file)
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -38,7 +38,8 @@
 #include <openssl/evp.h>
 #include <openssl/sha.h>
 #include <errno.h>
-#include <ext4.h>
+#include <ext4_utils/ext4.h>
+#include <ext4_utils/ext4_utils.h>
 #include <linux/kdev_t.h>
 #include <fs_mgr.h>
 #include <time.h>
 #include "VoldUtil.h"
 #include "crypto_scrypt.h"
 #include "Ext4Crypt.h"
-#include "ext4_utils.h"
 #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))
-
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-#include "cryptfs_hw.h"
-#endif
-
 #define DM_CRYPT_BUF_SIZE 4096
 
 #define HASH_COUNT 2000
@@ -108,181 +101,32 @@ static char *saved_mount_point;
 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");
-        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;
+    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;
         }
-    } 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;
+        SLOGE("Failed to generate keypair");
+        return -1;
     }
-
-    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 +136,6 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
                                  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 +167,10 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
             break;
         default:
             SLOGE("Unknown KDF type %d", ftr->kdf_type);
-            rc = -1;
-            goto out;
-    }
-
-    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;
+            return -1;
     }
-
-    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.
@@ -1081,16 +835,7 @@ static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr,
   tgt->status = 0;
   tgt->sector_start = 0;
   tgt->length = crypt_ftr->fs_size;
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-  if (!strcmp((char *)crypt_ftr->crypto_type_name, "aes-xts")) {
-    strlcpy(tgt->target_type, "req-crypt", DM_MAX_TYPE_NAME);
-  }
-  else {
-    strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME);
-  }
-#else
   strlcpy(tgt->target_type, "crypt", DM_MAX_TYPE_NAME);
-#endif
 
   crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
   convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
@@ -1138,11 +883,7 @@ static int get_dm_crypt_version(int fd, const char *name,  int *version)
      */
     v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)];
     while (v->next) {
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-        if (! strcmp(v->name, "crypt") || ! strcmp(v->name, "req-crypt")) {
-#else
         if (! strcmp(v->name, "crypt")) {
-#endif
             /* We found the crypt driver, return the version, and get out */
             version[0] = v->version[0];
             version[1] = v->version[1];
@@ -1859,14 +1600,6 @@ static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
 
   fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
 
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-  if (!strcmp((char *)crypt_ftr->crypto_type_name, "aes-xts")) {
-    if(!set_hw_device_encryption_key(passwd, (char*) crypt_ftr->crypto_type_name)) {
-      SLOGE("Hardware encryption key does not match");
-    }
-  }
-#endif
-
   // Create crypto block device - all (non fatal) code paths
   // need it
   if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
@@ -2194,6 +1927,19 @@ static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
     int rc = -1;
 
     if (type == EXT4_FS) {
+#ifdef TARGET_USES_MKE2FS
+        args[0] = "/system/bin/mke2fs";
+        args[1] = "-M";
+        args[2] = "/data";
+        args[3] = "-b";
+        args[4] = "4096";
+        args[5] = "-t";
+        args[6] = "ext4";
+        args[7] = crypto_blkdev;
+        snprintf(size_str, sizeof(size_str), "%" PRId64, size / (4096 / 512));
+        args[8] = size_str;
+        num_args = 9;
+#else
         args[0] = "/system/bin/make_ext4fs";
         args[1] = "-a";
         args[2] = "/data";
@@ -2202,6 +1948,7 @@ static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
         args[4] = size_str;
         args[5] = crypto_blkdev;
         num_args = 6;
+#endif
         SLOGI("Making empty filesystem with command %s %s %s %s %s %s\n",
               args[0], args[1], args[2], args[3], args[4], args[5]);
     } else if (type == F2FS_FS) {
@@ -2247,11 +1994,7 @@ static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
 /* aligned 32K writes tends to make flash happy.
  * SD card association recommends it.
  */
-#ifndef CONFIG_HW_DISK_ENCRYPTION
 #define BLOCKS_AT_A_TIME 8
-#else
-#define BLOCKS_AT_A_TIME 1024
-#endif
 
 struct encryptGroupsData
 {
@@ -3118,23 +2861,7 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
             crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
         }
         crypt_ftr.crypt_type = crypt_type;
-#ifndef CONFIG_HW_DISK_ENCRYPTION
         strlcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN);
-#else
-        strlcpy((char *)crypt_ftr.crypto_type_name, "aes-xts", MAX_CRYPTO_TYPE_NAME_LEN);
-
-        rc = clear_hw_device_encryption_key();
-        if (!rc) {
-          SLOGE("Error clearing device encryption hardware key. rc = %d", rc);
-        }
-
-        rc = set_hw_device_encryption_key(passwd,
-                                          (char*) crypt_ftr.crypto_type_name);
-        if (!rc) {
-          SLOGE("Error initializing device encryption hardware key. rc = %d", rc);
-          goto error_shutting_down;
-        }
-#endif
 
         /* Make an encrypted master key */
         if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd,
@@ -3368,21 +3095,6 @@ int cryptfs_changepw(int crypt_type, const char *newpw)
     /* save the key */
     put_crypt_ftr_and_key(&crypt_ftr);
 
-#ifdef CONFIG_HW_DISK_ENCRYPTION
-    if (!strcmp((char *)crypt_ftr.crypto_type_name, "aes-xts")) {
-        if (crypt_type == CRYPT_TYPE_DEFAULT) {
-            int rc = update_hw_device_encryption_key(DEFAULT_PASSWORD, (char*) crypt_ftr.crypto_type_name);
-            SLOGD("Update hardware encryption key to default for crypt_type: %d. rc = %d", crypt_type, rc);
-            if (!rc)
-                return -1;
-        } else {
-            int rc = update_hw_device_encryption_key(newpw, (char*) crypt_ftr.crypto_type_name);
-            SLOGD("Update hardware encryption key for crypt_type: %d. rc = %d", crypt_type, rc);
-            if (!rc)
-                return -1;
-        }
-    }
-#endif
     return 0;
 }
 
@@ -3865,8 +3577,9 @@ int cryptfs_set_password(struct crypt_mnt_ftr* ftr, const char* password,
                               ftr);
 }
 
-const char* cryptfs_get_file_encryption_mode()
+void cryptfs_get_file_encryption_modes(const char **contents_mode_ret,
+                                       const char **filenames_mode_ret)
 {
     struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
-    return fs_mgr_get_file_encryption_mode(rec);
+    fs_mgr_get_file_encryption_modes(rec, contents_mode_ret, filenames_mode_ret);
 }