summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Bires <jbires@google.com>2018-02-23 10:53:10 -0800
committerMax Bires <jbires@google.com>2018-04-25 21:46:08 +0000
commit33aac2dda210791b4ba155d204ceff56b77a28a9 (patch)
tree8ec2e99594b9bf9fa74eecb05153252bdc275fe8
parentcf91dcdee36775965938f5535480d6345821b459 (diff)
downloadsecurity-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.bp6
-rw-r--r--keystore/include/keystore/keymaster_types.h2
-rw-r--r--keystore/key_config.proto62
-rw-r--r--keystore/key_proto_handler.cpp86
-rw-r--r--keystore/key_proto_handler.h29
-rw-r--r--keystore/key_store_service.cpp23
-rw-r--r--keystore/operation.cpp20
-rw-r--r--keystore/operation.h27
-rw-r--r--keystore/operation_config.proto63
-rw-r--r--keystore/operation_proto_handler.cpp120
-rw-r--r--keystore/operation_proto_handler.h31
-rw-r--r--keystore/operation_struct.h58
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