123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /*
- * 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 <utils/StrongPointer.h>
- using namespace std::chrono;
- namespace keystore {
- constexpr auto kCollectionTime = 1h;
- 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 OperationProtoHandler::uploadOpAsProto(Operation& op, bool wasOpSuccessful) {
- std::lock_guard<std::mutex> lock(op_upload_mutex);
- OperationConfig operationConfig;
- determinePurpose(op.purpose, &operationConfig);
- checkKeyCharacteristics(op.characteristics.softwareEnforced, &operationConfig);
- checkKeyCharacteristics(op.characteristics.hardwareEnforced, &operationConfig);
- checkOpCharacteristics(op.params, &operationConfig);
- operationConfig.set_was_op_successful(wasOpSuccessful);
- // Only bother with counting an hour out when an operation entry is actually
- // added
- if (protoMap.empty()) {
- start_time = std::chrono::steady_clock::now();
- }
- auto cur_time = std::chrono::steady_clock::now();
- // Add operations to a map within the time duration of an hour. Deduplicate
- // repeated ops by incrementing the counter of the original one stored and
- // discarding the new one.
- protoMap[operationConfig.SerializeAsString()]++;
- if (cur_time - start_time >= kCollectionTime) {
- // Iterate through the unordered map and dump all the operation protos
- // accumulated over the hour into the holding list proto after setting
- // their counts.
- OperationConfigEvents opConfigEvents;
- for (auto elem : protoMap) {
- OperationConfigEvent* event = opConfigEvents.add_op_config_events();
- event->mutable_op_config()->ParseFromString(elem.first);
- event->set_count(elem.second);
- }
- android::sp<android::os::DropBoxManager> dropbox(new android::os::DropBoxManager);
- size_t size = opConfigEvents.ByteSize();
- auto data = std::make_unique<uint8_t[]>(size);
- opConfigEvents.SerializeWithCachedSizesToArray(data.get());
- dropbox->addData(android::String16("keymaster"), data.get(), size, 0);
- protoMap.clear();
- }
- }
- } // namespace keystore
|