diff options
author | Chad Brubaker <cbrubaker@google.com> | 2015-04-10 20:45:34 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-04-10 20:45:35 +0000 |
commit | 368a1f93381584fdd9ae0d59748cce5e4160acfb (patch) | |
tree | 3d0e2d9363705459fe32e7595a55feac0aa09053 | |
parent | c1e78258bb0b5ea1f761f21c3f5e7305aa4cc8ea (diff) | |
parent | ad6514ab7a57504aa3b04bcc383f60940b923710 (diff) | |
download | android_system_security-368a1f93381584fdd9ae0d59748cce5e4160acfb.tar.gz android_system_security-368a1f93381584fdd9ae0d59748cce5e4160acfb.tar.bz2 android_system_security-368a1f93381584fdd9ae0d59748cce5e4160acfb.zip |
Merge "Store the key characteristics for operations"
-rw-r--r-- | keystore/auth_token_table.h | 22 | ||||
-rw-r--r-- | keystore/keystore.cpp | 85 | ||||
-rw-r--r-- | keystore/operation.cpp | 27 | ||||
-rw-r--r-- | keystore/operation.h | 18 |
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; |