cryptfs: add support for keymaster 2

Change-Id: I1c4f06551897c8964ac2d40c9e785d527cc83847
This commit is contained in:
Peter Cai
2019-11-02 20:04:34 +08:00
committed by bigbiff
parent 6443cefc69
commit 8d7d4aed04
+90 -4
View File
@@ -74,6 +74,7 @@
#include <openssl/sha.h>
#include <hardware/keymaster0.h>
#include <hardware/keymaster1.h>
#include <hardware/keymaster2.h>
#endif
//#include "android-base/properties.h"
//#include <bootloader_message/bootloader_message.h>
@@ -176,7 +177,8 @@ out:
}
#else //TW_KEYMASTER_MAX_API == 0
static int keymaster_init(keymaster0_device_t **keymaster0_dev,
keymaster1_device_t **keymaster1_dev)
keymaster1_device_t **keymaster1_dev,
keymaster2_device_t **keymaster2_dev)
{
int rc;
@@ -192,7 +194,11 @@ static int keymaster_init(keymaster0_device_t **keymaster0_dev,
*keymaster0_dev = NULL;
*keymaster1_dev = NULL;
if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
*keymaster2_dev = NULL;
if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
printf("Found keymaster2 module, using keymaster2 API.\n");
rc = keymaster2_open(mod, keymaster2_dev);
} else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
printf("Found keymaster1 module, using keymaster1 API.\n");
rc = keymaster1_open(mod, keymaster1_dev);
} else {
@@ -211,6 +217,7 @@ static int keymaster_init(keymaster0_device_t **keymaster0_dev,
err:
*keymaster0_dev = NULL;
*keymaster1_dev = NULL;
*keymaster2_dev = NULL;
return rc;
}
#endif //TW_KEYMASTER_MAX_API == 0
@@ -424,7 +431,8 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
#if TW_KEYMASTER_MAX_API >= 1
keymaster0_device_t *keymaster0_dev = 0;
keymaster1_device_t *keymaster1_dev = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
keymaster2_device_t *keymaster2_dev = 0;
if (keymaster_init(&keymaster0_dev, &keymaster1_dev, &keymaster2_dev)) {
#else
keymaster_device_t *keymaster0_dev = 0;
if (keymaster_init(&keymaster0_dev)) {
@@ -500,6 +508,82 @@ static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
goto out;
}
*signature = (uint8_t*)tmp_sig.data;
*signature_size = tmp_sig.data_length;
rc = 0;
}
else if (keymaster2_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_key_param_t config_params[] = {
// Set these to crazy values so we don't need to synchronize
// the recovery with system updates.
// key upgrades will be required; it will be upgraded in-memory
keymaster_param_int(KM_TAG_OS_VERSION, 999999),
keymaster_param_int(KM_TAG_OS_PATCHLEVEL, 209912),
};
keymaster_key_param_set_t config_param_set = { config_params, sizeof(config_params)/sizeof(*config_params) };
keymaster2_dev->configure(keymaster2_dev, &config_param_set);
keymaster_error_t error = keymaster2_dev->begin(keymaster2_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 = keymaster2_dev->begin(keymaster2_dev, KM_PURPOSE_SIGN, &key,
&param_set, NULL /* out_params */,
&op_handle);
}
if (error == KM_ERROR_KEY_REQUIRES_UPGRADE) {
// Upgrade key in-memory if required
// Do not actually write it back; just keep it in memory
const keymaster_key_blob_t key_to_upd = key;
keymaster2_dev->upgrade_key(keymaster2_dev, &key_to_upd, &config_param_set, &key);
error = keymaster2_dev->begin(keymaster2_dev, KM_PURPOSE_SIGN, &key,
&param_set, NULL /* out_params */,
&op_handle);
}
if (error != KM_ERROR_OK) {
printf("Error starting keymaster signature transaction: %d\n", error);
rc = -1;
goto out;
}
keymaster_blob_t input = { to_sign, to_sign_size };
size_t input_consumed;
error = keymaster2_dev->update(keymaster2_dev, op_handle, NULL /* in_params */,
&input, &input_consumed, NULL /* out_params */,
NULL /* output */);
if (error != KM_ERROR_OK) {
printf("Error sending data to keymaster signature transaction: %d\n", 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.
printf("Keymaster update() did not consume all data.\n");
keymaster2_dev->abort(keymaster2_dev, op_handle);
rc = -1;
goto out;
}
keymaster_blob_t tmp_sig;
error = keymaster2_dev->finish(keymaster2_dev, op_handle, NULL /* in_params */,
NULL, NULL /* verify signature */, NULL /* out_params */,
&tmp_sig);
if (error != KM_ERROR_OK) {
printf("Error finishing keymaster signature transaction: %d\n", error);
rc = -1;
goto out;
}
*signature = (uint8_t*)tmp_sig.data;
*signature_size = tmp_sig.data_length;
rc = 0;
@@ -949,7 +1033,9 @@ static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr,
tgt->next = crypt_params - buffer;
for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
if (! ioctl(fd, DM_TABLE_LOAD, io)) {
int ret = ioctl(fd, DM_TABLE_LOAD, io);
if (!ret) {
SLOGI("ioctl err: %d", ret);
break;
}
usleep(500000);