cryptfs: add support for keymaster 2
Change-Id: I1c4f06551897c8964ac2d40c9e785d527cc83847
This commit is contained in:
+90
-4
@@ -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,
|
||||
¶m_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,
|
||||
¶m_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,
|
||||
¶m_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);
|
||||
|
||||
Reference in New Issue
Block a user