diff options
author | Max Bires <jbires@google.com> | 2018-02-23 10:53:10 -0800 |
---|---|---|
committer | Max Bires <jbires@google.com> | 2018-04-25 21:46:08 +0000 |
commit | 33aac2dda210791b4ba155d204ceff56b77a28a9 (patch) | |
tree | 8ec2e99594b9bf9fa74eecb05153252bdc275fe8 | |
parent | cf91dcdee36775965938f5535480d6345821b459 (diff) | |
download | security-33aac2dda210791b4ba155d204ceff56b77a28a9.tar.gz |
Adding DropBox logging support for keystore functionality
This will allow us to track the actual usage patterns of keystore
functions and error occurences.
Bug: 36549319
Test: DropBox logging works for keystore tags
Change-Id: Iadfba3afebaa0be753212b1111b68f50b77f9978
(cherry picked from commit d6d8952b346f08b4b74199adc1215579f4faeeff)
-rw-r--r-- | keystore/Android.bp | 6 | ||||
-rw-r--r-- | keystore/include/keystore/keymaster_types.h | 2 | ||||
-rw-r--r-- | keystore/key_config.proto | 62 | ||||
-rw-r--r-- | keystore/key_proto_handler.cpp | 86 | ||||
-rw-r--r-- | keystore/key_proto_handler.h | 29 | ||||
-rw-r--r-- | keystore/key_store_service.cpp | 23 | ||||
-rw-r--r-- | keystore/operation.cpp | 20 | ||||
-rw-r--r-- | keystore/operation.h | 27 | ||||
-rw-r--r-- | keystore/operation_config.proto | 63 | ||||
-rw-r--r-- | keystore/operation_proto_handler.cpp | 120 | ||||
-rw-r--r-- | keystore/operation_proto_handler.h | 31 | ||||
-rw-r--r-- | keystore/operation_struct.h | 58 |
12 files changed, 488 insertions, 39 deletions
diff --git a/keystore/Android.bp b/keystore/Android.bp index c98b78f1..8af87172 100644 --- a/keystore/Android.bp +++ b/keystore/Android.bp @@ -27,6 +27,8 @@ cc_binary { "confirmation_manager.cpp", "entropy.cpp", "grant_store.cpp", + "key_config.proto", + "key_proto_handler.cpp", "key_store_service.cpp", "keyblob_utils.cpp", "keymaster_enforcement.cpp", @@ -35,6 +37,8 @@ cc_binary { "keystore_utils.cpp", "legacy_keymaster_device_wrapper.cpp", "operation.cpp", + "operation_config.proto", + "operation_proto_handler.cpp", "permissions.cpp", "user_state.cpp", ], @@ -57,7 +61,9 @@ cc_binary { "libkeystore_binder", "libkeystore_parcelables", "liblog", + "libprotobuf-cpp-lite", "libselinux", + "libservices", "libsoftkeymasterdevice", "libutils", "libwifikeystorehal", diff --git a/keystore/include/keystore/keymaster_types.h b/keystore/include/keystore/keymaster_types.h index bd612940..f3c69079 100644 --- a/keystore/include/keystore/keymaster_types.h +++ b/keystore/include/keystore/keymaster_types.h @@ -66,6 +66,7 @@ using keymaster::TAG_APPLICATION_DATA; using keymaster::TAG_APPLICATION_ID; using keymaster::TAG_ATTESTATION_APPLICATION_ID; using keymaster::TAG_AUTH_TIMEOUT; +using keymaster::TAG_BLOB_USAGE_REQUIREMENTS; using keymaster::TAG_BLOCK_MODE; using keymaster::TAG_DIGEST; using keymaster::TAG_EC_CURVE; @@ -76,6 +77,7 @@ using keymaster::TAG_MIN_MAC_LENGTH; using keymaster::TAG_MIN_SECONDS_BETWEEN_OPS; using keymaster::TAG_NO_AUTH_REQUIRED; using keymaster::TAG_NONCE; +using keymaster::TAG_ORIGIN; using keymaster::TAG_ORIGINATION_EXPIRE_DATETIME; using keymaster::TAG_PADDING; using keymaster::TAG_PURPOSE; diff --git a/keystore/key_config.proto b/keystore/key_config.proto new file mode 100644 index 00000000..0b1a3980 --- /dev/null +++ b/keystore/key_config.proto @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; + +package keystore; + +option optimize_for = LITE_RUNTIME; + +message KeyConfig { + // What type of encryption algorithm is this key being generated/imported for + // e.g. AES, RSA, etc + optional string algorithm = 1; + + // Size of the key being generated/imported + optional int32 key_size = 2; + + // Log whether the key was generated, imported, securely imported, or derived. + optional string origin = 3; + + // What auth types does this key require? If none, then no auth required. + optional string user_auth_type = 4; + + // If user authentication is required, is the requirement time based? If it + // is not time based then this field will not be used and the key is per + // operation. Per operation keys must be user authenticated on each usage. + optional int32 user_auth_key_timeout = 5; + + // Track which padding modes this key supports. + repeated string padding = 6; + + // Track which digests this key supports + repeated string digest = 7; + + // Check what block mode is being used depending on the mode of encryption + repeated string block_mode = 8; + + // Was the key generated/imported successfully? + optional bool was_creation_successful = 9; + + // What purposes can this key be used for? + repeated string purpose = 10; + + // Which ec curve was selected if elliptic curve cryptography is in use + optional string ec_curve = 11; + + // Standalone or is a file system required + optional string key_blob_usage_reqs = 12; +} diff --git a/keystore/key_proto_handler.cpp b/keystore/key_proto_handler.cpp new file mode 100644 index 00000000..3bf8c060 --- /dev/null +++ b/keystore/key_proto_handler.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "KeystoreOperation" + +#include "key_proto_handler.h" + +#include <android/os/DropBoxManager.h> +#include <google/protobuf/message_lite.h> +#include <keymasterV4_0/Keymaster.h> +#include <keystore/keymaster_types.h> +#include <utils/String16.h> + +#include "key_config.pb.h" + +namespace keystore { + +void checkEnforcedCharacteristics(const hidl_vec<KeyParameter>& keyParams, KeyConfig* keyConfig) { + for (auto& keyParam : keyParams) { + switch (keyParam.tag) { + case Tag::PURPOSE: + keyConfig->add_purpose(toString(accessTagValue(TAG_PURPOSE, keyParam))); + break; + case Tag::ALGORITHM: + keyConfig->set_algorithm(toString(accessTagValue(TAG_ALGORITHM, keyParam))); + break; + case Tag::KEY_SIZE: + keyConfig->set_key_size(accessTagValue(TAG_KEY_SIZE, keyParam)); + break; + case Tag::BLOCK_MODE: + keyConfig->add_block_mode(toString(accessTagValue(TAG_BLOCK_MODE, keyParam))); + break; + case Tag::PADDING: + keyConfig->add_padding(toString(accessTagValue(TAG_PADDING, keyParam))); + break; + case Tag::DIGEST: + keyConfig->add_digest(toString(accessTagValue(TAG_DIGEST, keyParam))); + break; + case Tag::EC_CURVE: + keyConfig->set_ec_curve(toString(accessTagValue(TAG_EC_CURVE, keyParam))); + break; + case Tag::AUTH_TIMEOUT: + keyConfig->set_user_auth_key_timeout(accessTagValue(TAG_AUTH_TIMEOUT, keyParam)); + break; + case Tag::ORIGIN: + keyConfig->set_origin(toString(accessTagValue(TAG_ORIGIN, keyParam))); + break; + case Tag::BLOB_USAGE_REQUIREMENTS: + keyConfig->set_key_blob_usage_reqs( + toString(accessTagValue(TAG_BLOB_USAGE_REQUIREMENTS, keyParam))); + break; + case Tag::USER_AUTH_TYPE: + keyConfig->set_user_auth_type(toString(accessTagValue(TAG_USER_AUTH_TYPE, keyParam))); + break; + default: + break; + } + } +} + +void uploadKeyCharacteristicsAsProto(const hidl_vec<KeyParameter>& keyParams, + bool wasCreationSuccessful) { + KeyConfig keyConfig; + checkEnforcedCharacteristics(keyParams, &keyConfig); + auto dropbox = std::make_unique<android::os::DropBoxManager>(); + keyConfig.set_was_creation_successful(wasCreationSuccessful); + + size_t size = keyConfig.ByteSize(); + auto data = std::make_unique<uint8_t[]>(size); + keyConfig.SerializeWithCachedSizesToArray(data.get()); + dropbox->addData(android::String16("keymaster"), data.get(), size, 0); +} + +} // namespace keystore diff --git a/keystore/key_proto_handler.h b/keystore/key_proto_handler.h new file mode 100644 index 00000000..a2f6a243 --- /dev/null +++ b/keystore/key_proto_handler.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KEYSTORE_KEY_PROTO_HANDLER_H_ +#define KEYSTORE_KEY_PROTO_HANDLER_H_ + +#include <keystore/keystore_hidl_support.h> + +namespace keystore { + +void uploadKeyCharacteristicsAsProto(const hidl_vec<KeyParameter>& keyParams, + bool wasCreationSuccessful); + +} // namespace keystore + +#endif // KEYSTORE_KEY_PROTO_HANDLER_H_ diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp index 22524c91..87dccafa 100644 --- a/keystore/key_store_service.cpp +++ b/keystore/key_store_service.cpp @@ -38,6 +38,7 @@ #include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h> #include "defaults.h" +#include "key_proto_handler.h" #include "keystore_attestation_id.h" #include "keystore_keymaster_enforcement.h" #include "keystore_utils.h" @@ -822,6 +823,7 @@ KeyStoreService::generateKey(const String16& name, const KeymasterArguments& par } if (!error.isOk()) { ALOGE("Failed to generate key -> falling back to software keymaster"); + uploadKeyCharacteristicsAsProto(params.getParameters(), false /* wasCreationSuccessful */); securityLevel = SecurityLevel::SOFTWARE; // No fall back for 3DES @@ -847,6 +849,8 @@ KeyStoreService::generateKey(const String16& name, const KeymasterArguments& par *aidl_return = static_cast<int32_t>(error); return Status::ok(); } + } else { + uploadKeyCharacteristicsAsProto(params.getParameters(), true /* wasCreationSuccessful */); } if (!containsTag(params.getParameters(), Tag::USER_ID)) { @@ -1053,6 +1057,7 @@ KeyStoreService::importKey(const String16& name, const KeymasterArguments& param // now check error from callback if (!error.isOk()) { ALOGE("Failed to import key -> falling back to software keymaster"); + uploadKeyCharacteristicsAsProto(params.getParameters(), false /* wasCreationSuccessful */); securityLevel = SecurityLevel::SOFTWARE; // No fall back for 3DES @@ -1081,6 +1086,8 @@ KeyStoreService::importKey(const String16& name, const KeymasterArguments& param *aidl_return = static_cast<int32_t>(error); return Status::ok(); } + } else { + uploadKeyCharacteristicsAsProto(params.getParameters(), true /* wasCreationSuccessful */); } // Write the characteristics: @@ -1338,8 +1345,9 @@ Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, // Note: The operation map takes possession of the contents of "characteristics". // It is safe to use characteristics after the following line but it will be empty. - sp<IBinder> operationToken = mOperationMap.addOperation( - result->handle, keyid, keyPurpose, dev, appToken, std::move(characteristics), pruneable); + sp<IBinder> operationToken = + mOperationMap.addOperation(result->handle, keyid, keyPurpose, dev, appToken, + std::move(characteristics), params.getParameters(), pruneable); assert(characteristics.hardwareEnforced.size() == 0); assert(characteristics.softwareEnforced.size() == 0); result->token = operationToken; @@ -1478,20 +1486,23 @@ Status KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArgument op.device->finish(op.handle, inParams, ::std::vector<uint8_t>() /* TODO(swillden): wire up input to finish() */, signature, authToken, VerificationToken(), hidlCb)); - // removeOperation() will free the memory 'op' used, so the order is important - mAuthTokenTable.MarkCompleted(op.handle); - mOperationMap.removeOperation(token); + bool wasOpSuccessful = true; // just a reminder: on success result->resultCode was set in the callback. So we only overwrite // it if there was a communication error indicated by the ErrorCode. if (!rc.isOk()) { result->resultCode = rc; + wasOpSuccessful = false; } + + // removeOperation() will free the memory 'op' used, so the order is important + mAuthTokenTable.MarkCompleted(op.handle); + mOperationMap.removeOperation(token, wasOpSuccessful); return Status::ok(); } Status KeyStoreService::abort(const sp<IBinder>& token, int32_t* aidl_return) { - auto getOpResult = mOperationMap.removeOperation(token); + auto getOpResult = mOperationMap.removeOperation(token, false /* wasOpSuccessful */); if (!getOpResult.isOk()) { *aidl_return = static_cast<int32_t>(ErrorCode::INVALID_OPERATION_HANDLE); return Status::ok(); diff --git a/keystore/operation.cpp b/keystore/operation.cpp index e09d5151..93b1e923 100644 --- a/keystore/operation.cpp +++ b/keystore/operation.cpp @@ -26,18 +26,18 @@ OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient) sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const sp<Keymaster>& dev, const sp<IBinder>& appToken, - KeyCharacteristics&& characteristics, bool pruneable) { + KeyCharacteristics&& characteristics, + const hidl_vec<KeyParameter>& params, bool pruneable) { sp<IBinder> token = new ::android::BBinder(); - mMap.emplace(token, - Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken)); + mMap.emplace(token, Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken, + params)); if (pruneable) mLru.push_back(token); if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient); mAppTokenMap[appToken].push_back(token); - return token; } -NullOr<const OperationMap::Operation&> OperationMap::getOperation(const sp<IBinder>& token) { +NullOr<const Operation&> OperationMap::getOperation(const sp<IBinder>& token) { auto entry = mMap.find(token); if (entry == mMap.end()) return {}; @@ -53,17 +53,17 @@ void OperationMap::updateLru(const sp<IBinder>& token) { } } -NullOr<OperationMap::Operation> OperationMap::removeOperation(const sp<IBinder>& token) { +NullOr<Operation> OperationMap::removeOperation(const sp<IBinder>& token, bool wasSuccessful) { auto entry = mMap.find(token); if (entry == mMap.end()) return {}; Operation op = std::move(entry->second); + uploadOpAsProto(op, wasSuccessful); mMap.erase(entry); auto lruEntry = std::find(mLru.begin(), mLru.end(), token); if (lruEntry != mLru.end()) mLru.erase(lruEntry); removeOperationTracking(token, op.appToken); - return op; } @@ -109,10 +109,4 @@ std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& return appEntry->second; } -OperationMap::Operation::Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_, - const sp<Keymaster>& device_, - KeyCharacteristics&& characteristics_, sp<IBinder> appToken_) - : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_), - characteristics(characteristics_), appToken(appToken_) {} - } // namespace keystore diff --git a/keystore/operation.h b/keystore/operation.h index 0acb70c5..2d81f9ca 100644 --- a/keystore/operation.h +++ b/keystore/operation.h @@ -26,6 +26,10 @@ #include <utils/StrongPointer.h> #include <keystore/keymaster_types.h> +#include <keystore/keystore_hidl_support.h> + +#include "operation_proto_handler.h" +#include "operation_struct.h" namespace keystore { @@ -42,30 +46,13 @@ using keymaster::support::Keymaster; class OperationMap { public: - struct Operation { - Operation() = default; - Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const sp<Keymaster>& device, - KeyCharacteristics&& characteristics, sp<IBinder> appToken); - Operation(Operation&&) = default; - Operation(const Operation&) = delete; - - bool hasAuthToken() const { return authToken.mac.size() != 0; } - - uint64_t handle; - uint64_t keyid; - KeyPurpose purpose; - sp<Keymaster> device; - KeyCharacteristics characteristics; - sp<IBinder> appToken; - HardwareAuthToken authToken; - }; - explicit OperationMap(IBinder::DeathRecipient* deathRecipient); sp<IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const sp<Keymaster>& dev, const sp<IBinder>& appToken, - KeyCharacteristics&& characteristics, bool pruneable); + KeyCharacteristics&& characteristics, + const hidl_vec<KeyParameter>& params, bool pruneable); NullOr<const Operation&> getOperation(const sp<IBinder>& token); - NullOr<Operation> removeOperation(const sp<IBinder>& token); + NullOr<Operation> removeOperation(const sp<IBinder>& token, bool wasSuccessful); bool hasPruneableOperation() const; size_t getOperationCount() const { return mMap.size(); } size_t getPruneableOperationCount() const; diff --git a/keystore/operation_config.proto b/keystore/operation_config.proto new file mode 100644 index 00000000..37b4cbba --- /dev/null +++ b/keystore/operation_config.proto @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; + +package keystore; + +option optimize_for = LITE_RUNTIME; + +message OperationConfig { + // What type of encryption algorithm is the key being used in the op for. + optional string algorithm = 1; + + // Size of the key being used in this op + optional int32 key_size = 2; + + // Log whether the key in this op was generated, imported, + // securely imported, or derived. + optional string origin = 3; + + // What auth types does this op require? If none, then no auth required. + optional string user_auth_type = 4; + + // If user authentication is required, is the requirement time based? If it + // is not time based then this field will not be used and the key is per + // operation. Per operation keys must be user authenticated on each usage. + optional int32 user_auth_key_timeout = 5; + + // Track which padding mode was used for this operation. + optional string padding = 6; + + // Keep track of the digest algorithm being used. + optional string digest = 7; + + // Check what block mode is being used depending on the mode of encryption + optional string block_mode = 8; + + // Did the operation succeed? If it didn't, this represents bugs or + // error cases occurring. + optional bool was_op_successful = 9; + + // What purpose is this operation serving? Encrypt, decrypt, sign verify? + optional string purpose = 10; + + // Which ec curve was selected if elliptic curve cryptography is in use + optional string ec_curve = 11; + + // Standalone or is a file system required + optional string key_blob_usage_reqs = 12; +} diff --git a/keystore/operation_proto_handler.cpp b/keystore/operation_proto_handler.cpp new file mode 100644 index 00000000..77e1b73c --- /dev/null +++ b/keystore/operation_proto_handler.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "KeystoreOperation" + +#include "operation_proto_handler.h" + +#include <android/os/DropBoxManager.h> +#include <google/protobuf/message_lite.h> +#include <keymasterV4_0/Keymaster.h> +#include <keystore/keymaster_types.h> +#include <keystore/keystore_hidl_support.h> +#include <utils/String16.h> + +#include "operation_config.pb.h" + +namespace keystore { + +void determinePurpose(KeyPurpose purpose, OperationConfig* operationConfig) { + switch (purpose) { + case KeyPurpose::VERIFY: + operationConfig->set_purpose("verify"); + break; + case KeyPurpose::ENCRYPT: + operationConfig->set_purpose("encrypt"); + break; + case KeyPurpose::SIGN: + operationConfig->set_purpose("sign"); + break; + case KeyPurpose::DECRYPT: + operationConfig->set_purpose("decrypt"); + break; + case KeyPurpose::WRAP_KEY: + operationConfig->set_purpose("wrap"); + break; + default: + break; + } +} + +void checkKeyCharacteristics(const hidl_vec<KeyParameter>& characteristics, + OperationConfig* operationConfig) { + for (auto& opParam : characteristics) { + switch (opParam.tag) { + case Tag::ALGORITHM: + operationConfig->set_algorithm(toString(accessTagValue(TAG_ALGORITHM, opParam))); + break; + case Tag::KEY_SIZE: + operationConfig->set_key_size(accessTagValue(TAG_KEY_SIZE, opParam)); + break; + case Tag::EC_CURVE: + operationConfig->set_ec_curve(toString(accessTagValue(TAG_EC_CURVE, opParam))); + break; + case Tag::AUTH_TIMEOUT: + operationConfig->set_user_auth_key_timeout(accessTagValue(TAG_AUTH_TIMEOUT, opParam)); + break; + case Tag::ORIGIN: + operationConfig->set_origin(toString(accessTagValue(TAG_ORIGIN, opParam))); + break; + case Tag::BLOB_USAGE_REQUIREMENTS: + operationConfig->set_key_blob_usage_reqs( + toString(accessTagValue(TAG_BLOB_USAGE_REQUIREMENTS, opParam))); + break; + case Tag::USER_AUTH_TYPE: + operationConfig->set_user_auth_type( + toString(accessTagValue(TAG_USER_AUTH_TYPE, opParam))); + break; + default: + break; + } + } +} + +void checkOpCharacteristics(const hidl_vec<KeyParameter>& characteristics, + OperationConfig* operationConfig) { + for (auto& opParam : characteristics) { + switch (opParam.tag) { + case Tag::BLOCK_MODE: + operationConfig->set_block_mode(toString(accessTagValue(TAG_BLOCK_MODE, opParam))); + break; + case Tag::PADDING: + operationConfig->set_padding(toString(accessTagValue(TAG_PADDING, opParam))); + break; + case Tag::DIGEST: + operationConfig->set_digest(toString(accessTagValue(TAG_DIGEST, opParam))); + break; + default: + break; + } + } +} + +void uploadOpAsProto(Operation& op, bool wasOpSuccessful) { + OperationConfig operationConfig; + determinePurpose(op.purpose, &operationConfig); + checkKeyCharacteristics(op.characteristics.softwareEnforced, &operationConfig); + checkKeyCharacteristics(op.characteristics.hardwareEnforced, &operationConfig); + checkOpCharacteristics(op.params, &operationConfig); + auto dropbox = std::make_unique<android::os::DropBoxManager>(); + operationConfig.set_was_op_successful(wasOpSuccessful); + + size_t size = operationConfig.ByteSize(); + auto data = std::make_unique<uint8_t[]>(size); + operationConfig.SerializeWithCachedSizesToArray(data.get()); + dropbox->addData(android::String16("keymaster"), data.get(), size, 0); +} + +} // namespace keystore diff --git a/keystore/operation_proto_handler.h b/keystore/operation_proto_handler.h new file mode 100644 index 00000000..bf461b48 --- /dev/null +++ b/keystore/operation_proto_handler.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KEYSTORE_OPERATION_PROTO_HANDLER_H_ +#define KEYSTORE_OPERATION_PROTO_HANDLER_H_ + +#include "operation_struct.h" + +namespace keystore { + +using ::android::IBinder; +using keymaster::support::Keymaster; + +void uploadOpAsProto(Operation& op, bool wasOpSuccessful); + +} // namespace keystore + +#endif // KEYSTORE_OPERATION_PROTO_HANDLER_H_ diff --git a/keystore/operation_struct.h b/keystore/operation_struct.h new file mode 100644 index 00000000..ea8a908d --- /dev/null +++ b/keystore/operation_struct.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KEYSTORE_OPERATION_STRUCT_H_ +#define KEYSTORE_OPERATION_STRUCT_H_ + +#include <binder/Binder.h> +#include <binder/IBinder.h> +#include <keymasterV4_0/Keymaster.h> +#include <utils/StrongPointer.h> + +#include <keystore/keymaster_types.h> +#include <keystore/keystore_hidl_support.h> + +namespace keystore { + +using ::android::IBinder; +using ::android::sp; +using keymaster::support::Keymaster; + +struct Operation { + Operation() = default; + Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_, const sp<Keymaster>& device_, + KeyCharacteristics&& characteristics_, sp<IBinder> appToken_, + const hidl_vec<KeyParameter> params_) + : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_), + characteristics(characteristics_), appToken(appToken_), params(params_) {} + Operation(Operation&&) = default; + Operation(const Operation&) = delete; + + bool hasAuthToken() const { return authToken.mac.size() != 0; } + + uint64_t handle; + uint64_t keyid; + KeyPurpose purpose; + sp<Keymaster> device; + KeyCharacteristics characteristics; + sp<IBinder> appToken; + HardwareAuthToken authToken; + const hidl_vec<KeyParameter> params; +}; + +} // namespace keystore + +#endif |