operation_proto_handler.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*
  2. * Copyright (C) 2018 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #define LOG_TAG "KeystoreOperation"
  17. #include "operation_proto_handler.h"
  18. #include <android/os/DropBoxManager.h>
  19. #include <google/protobuf/message_lite.h>
  20. #include <keymasterV4_0/Keymaster.h>
  21. #include <keystore/keymaster_types.h>
  22. #include <keystore/keystore_hidl_support.h>
  23. #include <utils/String16.h>
  24. #include <utils/StrongPointer.h>
  25. using namespace std::chrono;
  26. namespace keystore {
  27. constexpr auto kCollectionTime = 1h;
  28. void determinePurpose(KeyPurpose purpose, OperationConfig* operationConfig) {
  29. switch (purpose) {
  30. case KeyPurpose::VERIFY:
  31. operationConfig->set_purpose("verify");
  32. break;
  33. case KeyPurpose::ENCRYPT:
  34. operationConfig->set_purpose("encrypt");
  35. break;
  36. case KeyPurpose::SIGN:
  37. operationConfig->set_purpose("sign");
  38. break;
  39. case KeyPurpose::DECRYPT:
  40. operationConfig->set_purpose("decrypt");
  41. break;
  42. case KeyPurpose::WRAP_KEY:
  43. operationConfig->set_purpose("wrap");
  44. break;
  45. default:
  46. break;
  47. }
  48. }
  49. void checkKeyCharacteristics(const hidl_vec<KeyParameter>& characteristics,
  50. OperationConfig* operationConfig) {
  51. for (auto& opParam : characteristics) {
  52. switch (opParam.tag) {
  53. case Tag::ALGORITHM:
  54. operationConfig->set_algorithm(toString(accessTagValue(TAG_ALGORITHM, opParam)));
  55. break;
  56. case Tag::KEY_SIZE:
  57. operationConfig->set_key_size(accessTagValue(TAG_KEY_SIZE, opParam));
  58. break;
  59. case Tag::EC_CURVE:
  60. operationConfig->set_ec_curve(toString(accessTagValue(TAG_EC_CURVE, opParam)));
  61. break;
  62. case Tag::AUTH_TIMEOUT:
  63. operationConfig->set_user_auth_key_timeout(accessTagValue(TAG_AUTH_TIMEOUT, opParam));
  64. break;
  65. case Tag::ORIGIN:
  66. operationConfig->set_origin(toString(accessTagValue(TAG_ORIGIN, opParam)));
  67. break;
  68. case Tag::BLOB_USAGE_REQUIREMENTS:
  69. operationConfig->set_key_blob_usage_reqs(
  70. toString(accessTagValue(TAG_BLOB_USAGE_REQUIREMENTS, opParam)));
  71. break;
  72. case Tag::USER_AUTH_TYPE:
  73. operationConfig->set_user_auth_type(
  74. toString(accessTagValue(TAG_USER_AUTH_TYPE, opParam)));
  75. break;
  76. default:
  77. break;
  78. }
  79. }
  80. }
  81. void checkOpCharacteristics(const hidl_vec<KeyParameter>& characteristics,
  82. OperationConfig* operationConfig) {
  83. for (auto& opParam : characteristics) {
  84. switch (opParam.tag) {
  85. case Tag::BLOCK_MODE:
  86. operationConfig->set_block_mode(toString(accessTagValue(TAG_BLOCK_MODE, opParam)));
  87. break;
  88. case Tag::PADDING:
  89. operationConfig->set_padding(toString(accessTagValue(TAG_PADDING, opParam)));
  90. break;
  91. case Tag::DIGEST:
  92. operationConfig->set_digest(toString(accessTagValue(TAG_DIGEST, opParam)));
  93. break;
  94. default:
  95. break;
  96. }
  97. }
  98. }
  99. void OperationProtoHandler::uploadOpAsProto(Operation& op, bool wasOpSuccessful) {
  100. std::lock_guard<std::mutex> lock(op_upload_mutex);
  101. OperationConfig operationConfig;
  102. determinePurpose(op.purpose, &operationConfig);
  103. checkKeyCharacteristics(op.characteristics.softwareEnforced, &operationConfig);
  104. checkKeyCharacteristics(op.characteristics.hardwareEnforced, &operationConfig);
  105. checkOpCharacteristics(op.params, &operationConfig);
  106. operationConfig.set_was_op_successful(wasOpSuccessful);
  107. // Only bother with counting an hour out when an operation entry is actually
  108. // added
  109. if (protoMap.empty()) {
  110. start_time = std::chrono::steady_clock::now();
  111. }
  112. auto cur_time = std::chrono::steady_clock::now();
  113. // Add operations to a map within the time duration of an hour. Deduplicate
  114. // repeated ops by incrementing the counter of the original one stored and
  115. // discarding the new one.
  116. protoMap[operationConfig.SerializeAsString()]++;
  117. if (cur_time - start_time >= kCollectionTime) {
  118. // Iterate through the unordered map and dump all the operation protos
  119. // accumulated over the hour into the holding list proto after setting
  120. // their counts.
  121. OperationConfigEvents opConfigEvents;
  122. for (auto elem : protoMap) {
  123. OperationConfigEvent* event = opConfigEvents.add_op_config_events();
  124. event->mutable_op_config()->ParseFromString(elem.first);
  125. event->set_count(elem.second);
  126. }
  127. android::sp<android::os::DropBoxManager> dropbox(new android::os::DropBoxManager);
  128. size_t size = opConfigEvents.ByteSize();
  129. auto data = std::make_unique<uint8_t[]>(size);
  130. opConfigEvents.SerializeWithCachedSizesToArray(data.get());
  131. dropbox->addData(android::String16("keymaster"), data.get(), size, 0);
  132. protoMap.clear();
  133. }
  134. }
  135. } // namespace keystore