summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChad Brubaker <cbrubaker@google.com>2015-04-09 14:00:26 -0700
committerChad Brubaker <cbrubaker@google.com>2015-04-09 14:00:26 -0700
commitad6514ab7a57504aa3b04bcc383f60940b923710 (patch)
tree3d0e2d9363705459fe32e7595a55feac0aa09053
parentc1e78258bb0b5ea1f761f21c3f5e7305aa4cc8ea (diff)
downloadandroid_system_security-ad6514ab7a57504aa3b04bcc383f60940b923710.tar.gz
android_system_security-ad6514ab7a57504aa3b04bcc383f60940b923710.tar.bz2
android_system_security-ad6514ab7a57504aa3b04bcc383f60940b923710.zip
Store the key characteristics for operations
Instead of storing the key blob and parsing the characteristics out, which some implementations might not support, instead call get characteristics on begin and store that result for subsequent auth calls. Change-Id: I75e39ee28cc440e4ed411b2daaa2744085e1aa12
-rw-r--r--keystore/auth_token_table.h22
-rw-r--r--keystore/keystore.cpp85
-rw-r--r--keystore/operation.cpp27
-rw-r--r--keystore/operation.h18
4 files changed, 82 insertions, 70 deletions
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 7c18367..102e6e4 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -54,7 +54,6 @@ class AuthTokenTable {
// (e.g. new fingerprint enrolled).
OP_HANDLE_REQUIRED = -4, // The key requires auth per use but op_handle was zero.
AUTH_TOKEN_NOT_FOUND = -5,
- AUTH_BAD_PARAMS = -6,
};
/**
@@ -91,27 +90,6 @@ class AuthTokenTable {
}
/**
- * Find an authorization token that authorizes the operation specified by \p handle on
- * a key with the characteristics specified in \p blob.
- *
- * The table retains ownership of the returned object.
- */
- Error FindAuthorization(const keymaster_key_blob_t& blob, keymaster_operation_handle_t handle,
- const hw_auth_token_t** found) {
- KeyBlob key(blob);
- if (key.error()) {
- return AUTH_BAD_PARAMS;
- }
- AuthorizationSet auths(key.unenforced());
- for (auto param : key.enforced()) {
- auths.push_back(param);
- }
- return FindAuthorization(auths, handle, found);
-
- }
-
-
- /**
* Mark operation completed. This allows tokens associated with the specified operation to be
* superseded by new tokens.
*/
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index f1553cc..a65a34c 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -105,16 +105,6 @@ struct PKCS8_PRIV_KEY_INFO_Delete {
};
typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
-struct keymaster_key_blob_t_Delete {
- void operator()(keymaster_key_blob_t* blob) const {
- if (blob) {
- delete[] blob->key_material;
- }
- delete blob;
- }
-};
-typedef UniquePtr<keymaster_key_blob_t, keymaster_key_blob_t_Delete> Unique_keymaster_key_blob;
-
static int keymaster_device_initialize(keymaster0_device_t** dev) {
int rc;
@@ -2722,16 +2712,24 @@ public:
return true;
}
- int authorizeOperation(const keymaster_key_blob_t& key,
+ int authorizeOperation(const keymaster_key_characteristics_t& characteristics,
keymaster_operation_handle_t handle,
std::vector<keymaster_key_param_t>* params,
bool failOnTokenMissing=true) {
if (!checkAllowedOperationParams(*params)) {
return KM_ERROR_INVALID_ARGUMENT;
}
+ std::vector<keymaster_key_param_t> allCharacteristics;
+ for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
+ allCharacteristics.push_back(characteristics.sw_enforced.params[i]);
+ }
+ for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
+ allCharacteristics.push_back(characteristics.hw_enforced.params[i]);
+ }
// Check for auth token and add it to the param list if present.
const hw_auth_token_t* authToken;
- switch (mAuthTokenTable.FindAuthorization(key, handle, &authToken)) {
+ switch (mAuthTokenTable.FindAuthorization(allCharacteristics.data(),
+ allCharacteristics.size(), handle, &authToken)) {
case keymaster::AuthTokenTable::OK:
// Auth token found.
params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN,
@@ -2756,6 +2754,36 @@ public:
return KM_ERROR_OK;
}
+ keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key,
+ const keymaster1_device_t* dev,
+ const std::vector<keymaster_key_param_t>& params,
+ keymaster_key_characteristics_t* out) {
+ UniquePtr<keymaster_blob_t> appId;
+ UniquePtr<keymaster_blob_t> appData;
+ for (auto param : params) {
+ if (param.tag == KM_TAG_APPLICATION_ID) {
+ appId.reset(new keymaster_blob_t);
+ appId->data = param.blob.data;
+ appId->data_length = param.blob.data_length;
+ } else if (param.tag == KM_TAG_APPLICATION_DATA) {
+ appData.reset(new keymaster_blob_t);
+ appData->data = param.blob.data;
+ appData->data_length = param.blob.data_length;
+ }
+ }
+ keymaster_key_characteristics_t* result = NULL;
+ if (!dev->get_key_characteristics) {
+ return KM_ERROR_UNIMPLEMENTED;
+ }
+ keymaster_error_t error = dev->get_key_characteristics(dev, &key, appId.get(),
+ appData.get(), &result);
+ if (result) {
+ *out = *result;
+ free(result);
+ }
+ return error;
+ }
+
void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose,
bool pruneable, const KeymasterArguments& params, const uint8_t* entropy,
size_t entropyLength, KeymasterArguments* outParams, OperationResult* result) {
@@ -2786,10 +2814,17 @@ public:
keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
keymaster_error_t err = KM_ERROR_UNIMPLEMENTED;
std::vector<keymaster_key_param_t> opParams(params.params);
+ Unique_keymaster_key_characteristics characteristics;
+ characteristics.reset(new keymaster_key_characteristics_t);
+ err = getOperationCharacteristics(key, dev, opParams, characteristics.get());
+ if (err) {
+ result->resultCode = err;
+ return;
+ }
// Don't require an auth token for the call to begin, authentication can
// require an operation handle. Update and finish will require the token
// be present and valid.
- int32_t authResult = authorizeOperation(key, 0, &opParams,
+ int32_t authResult = authorizeOperation(*characteristics, 0, &opParams,
/*failOnTokenMissing*/ false);
if (authResult) {
result->resultCode = err;
@@ -2833,7 +2868,8 @@ public:
free(out);
}
- sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken, key,
+ sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken,
+ characteristics.release(),
pruneable);
result->resultCode = ::NO_ERROR;
result->token = operationToken;
@@ -2844,9 +2880,8 @@ public:
size_t dataLength, OperationResult* result) {
const keymaster1_device_t* dev;
keymaster_operation_handle_t handle;
- Unique_keymaster_key_blob key(new keymaster_key_blob_t);
- *key = {NULL, 0};
- if (!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+ const keymaster_key_characteristics_t* characteristics;
+ if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
return;
}
@@ -2854,7 +2889,7 @@ public:
size_t output_length = 0;
size_t consumed = 0;
std::vector<keymaster_key_param_t> opParams(params.params);
- int32_t authResult = authorizeOperation(*key, handle, &opParams);
+ int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
if (authResult) {
result->resultCode = authResult;
return;
@@ -2871,16 +2906,15 @@ public:
const uint8_t* signature, size_t signatureLength, OperationResult* result) {
const keymaster1_device_t* dev;
keymaster_operation_handle_t handle;
- Unique_keymaster_key_blob key(new keymaster_key_blob_t);
- *key = {NULL, 0};
- if (!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+ const keymaster_key_characteristics_t* characteristics;
+ if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
return;
}
uint8_t* output_buf = NULL;
size_t output_length = 0;
std::vector<keymaster_key_param_t> opParams(params.params);
- int32_t authResult = authorizeOperation(*key, handle, &opParams);
+ int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
if (authResult) {
result->resultCode = authResult;
return;
@@ -2919,13 +2953,12 @@ public:
bool isOperationAuthorized(const sp<IBinder>& token) {
const keymaster1_device_t* dev;
keymaster_operation_handle_t handle;
- Unique_keymaster_key_blob key(new keymaster_key_blob_t);
- *key = {NULL, 0};
- if(!mOperationMap.getOperation(token, &handle, &dev, key.get())) {
+ const keymaster_key_characteristics_t* characteristics;
+ if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
return false;
}
std::vector<keymaster_key_param_t> ignored;
- int32_t authResult = authorizeOperation(*key, handle, &ignored);
+ int32_t authResult = authorizeOperation(*characteristics, handle, &ignored);
return authResult == KM_ERROR_OK;
}
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 2fde0da..e871f83 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -27,9 +27,10 @@ OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle,
const keymaster1_device_t* dev,
sp<IBinder> appToken,
- const keymaster_key_blob_t& key, bool pruneable) {
+ keymaster_key_characteristics_t* characteristics,
+ bool pruneable) {
sp<IBinder> token = new BBinder();
- mMap[token] = Operation(handle, dev, key, appToken);
+ mMap[token] = std::move(Operation(handle, dev, characteristics, appToken));
if (pruneable) {
mLru.push_back(token);
}
@@ -42,7 +43,7 @@ sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle,
bool OperationMap::getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
const keymaster1_device_t** outDevice,
- keymaster_key_blob_t* key) {
+ const keymaster_key_characteristics_t** outCharacteristics) {
if (!outHandle || !outDevice) {
return false;
}
@@ -54,12 +55,8 @@ bool OperationMap::getOperation(sp<IBinder> token, keymaster_operation_handle_t*
*outHandle = entry->second.handle;
*outDevice = entry->second.device;
- if (key) {
- key->key_material_size = entry->second.key.key_material_size;
- uint8_t* material = new uint8_t[key->key_material_size];
- memcpy(reinterpret_cast<void*>(material), entry->second.key.key_material,
- key->key_material_size);
- key->key_material = material;
+ if (outCharacteristics) {
+ *outCharacteristics = entry->second.characteristics.get();
}
return true;
}
@@ -78,7 +75,6 @@ bool OperationMap::removeOperation(sp<IBinder> token) {
return false;
}
sp<IBinder> appToken = entry->second.appToken;
- delete[] entry->second.key.key_material;
mMap.erase(entry);
auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
if (lruEntry != mLru.end()) {
@@ -125,19 +121,14 @@ std::vector<sp<IBinder>> OperationMap::getOperationsForToken(sp<IBinder> appToke
OperationMap::Operation::Operation(keymaster_operation_handle_t handle_,
const keymaster1_device_t* device_,
- const keymaster_key_blob_t& key_,
+ keymaster_key_characteristics_t* characteristics_,
sp<IBinder> appToken_)
: handle(handle_),
device(device_),
+ characteristics(characteristics_),
appToken(appToken_) {
- uint8_t* material = new uint8_t[key_.key_material_size];
- memcpy(material, key_.key_material, key_.key_material_size);
- key.key_material = material;
- key.key_material_size = key_.key_material_size;
}
-OperationMap::Operation::Operation() : handle(0), device(NULL), appToken(NULL) {
- key.key_material = NULL;
- key.key_material_size = 0;
+OperationMap::Operation::Operation() : handle(0), device(NULL), characteristics(), appToken(NULL) {
}
} // namespace android
diff --git a/keystore/operation.h b/keystore/operation.h
index 6076836..a312528 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -27,6 +27,15 @@
namespace android {
+struct keymaster_key_characteristics_t_Delete {
+ void operator()(keymaster_key_characteristics_t* characteristics) const {
+ keymaster_free_characteristics(characteristics);
+ delete characteristics;
+ }
+};
+typedef std::unique_ptr<keymaster_key_characteristics_t, keymaster_key_characteristics_t_Delete>
+ Unique_keymaster_key_characteristics;
+
/**
* OperationMap handles the translation of keymaster_operation_handle_t's and
* keymaster1_device_t's to opaque binder tokens that can be used to reference
@@ -39,9 +48,10 @@ public:
OperationMap(IBinder::DeathRecipient* deathRecipient);
sp<IBinder> addOperation(keymaster_operation_handle_t handle,
const keymaster1_device_t* dev, sp<IBinder> appToken,
- const keymaster_key_blob_t& key, bool pruneable);
+ keymaster_key_characteristics_t* characteristics, bool pruneable);
bool getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
- const keymaster1_device_t** outDev, keymaster_key_blob_t* outKey);
+ const keymaster1_device_t** outDev,
+ const keymaster_key_characteristics_t** outCharacteristics);
bool removeOperation(sp<IBinder> token);
bool hasPruneableOperation();
sp<IBinder> getOldestPruneableOperation();
@@ -53,10 +63,10 @@ private:
struct Operation {
Operation();
Operation(keymaster_operation_handle_t handle, const keymaster1_device_t* device,
- const keymaster_key_blob_t& key, sp<IBinder> appToken);
+ keymaster_key_characteristics_t* characteristics, sp<IBinder> appToken);
keymaster_operation_handle_t handle;
const keymaster1_device_t* device;
- keymaster_key_blob_t key;
+ Unique_keymaster_key_characteristics characteristics;
sp<IBinder> appToken;
};
std::map<sp<IBinder>, struct Operation> mMap;