diff options
Diffstat (limited to 'keystore')
-rw-r--r-- | keystore/Android.bp | 4 | ||||
-rw-r--r-- | keystore/key_config.proto | 62 | ||||
-rw-r--r-- | keystore/key_creation_log_handler.cpp | 211 | ||||
-rw-r--r-- | keystore/key_creation_log_handler.h | 71 | ||||
-rw-r--r-- | keystore/key_proto_handler.cpp | 87 | ||||
-rw-r--r-- | keystore/key_proto_handler.h | 29 | ||||
-rw-r--r-- | keystore/key_store_service.cpp | 1 | ||||
-rw-r--r-- | keystore/keymaster_worker.cpp | 22 |
8 files changed, 298 insertions, 189 deletions
diff --git a/keystore/Android.bp b/keystore/Android.bp index b8817577..b41ad183 100644 --- a/keystore/Android.bp +++ b/keystore/Android.bp @@ -34,8 +34,7 @@ cc_binary { "blob.cpp", "confirmation_manager.cpp", "grant_store.cpp", - "key_config.proto", - "key_proto_handler.cpp", + "key_creation_log_handler.cpp", "key_store_service.cpp", "keyblob_utils.cpp", "keymaster_enforcement.cpp", @@ -74,6 +73,7 @@ cc_binary { "libservices", "libsoftkeymasterdevice", "libutils", + "libstatslog", ], init_rc: ["keystore.rc"], aidl: { diff --git a/keystore/key_config.proto b/keystore/key_config.proto deleted file mode 100644 index 0b1a3980..00000000 --- a/keystore/key_config.proto +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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_creation_log_handler.cpp b/keystore/key_creation_log_handler.cpp new file mode 100644 index 00000000..d8462576 --- /dev/null +++ b/keystore/key_creation_log_handler.cpp @@ -0,0 +1,211 @@ +/* + * 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_creation_log_handler.h" +#include <statslog.h> + +namespace keystore { + +template <typename Tag> +int32_t getEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) { + auto tagValue = authorization_set.GetTagValue(tag); + if (tagValue.isOk()) { + static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t), + "Tag type value will be truncated, if cast to int32_t"); + return static_cast<int32_t>(tagValue.value()); + } + // Usually, if the value is not present, 0 is set. However, since 0 is a valid + // enum value, -1 is set for single enum fields. + return -1; +} + +int32_t generateBitMapForPaddingModeValues(const AuthorizationSet& authorization_set) { + int32_t bitMap = 0; + int32_t tagValueCount = authorization_set.GetTagCount(TAG_PADDING); + if (tagValueCount == 0) { + // unlike in the single enum fields, if no value is provided, + // 0 is set for the bitmap + return bitMap; + } + int current_offset = -1; + while (tagValueCount > 0) { + current_offset = authorization_set.find(TAG_PADDING, current_offset); + KeyParameter keyParam = authorization_set[current_offset]; + auto tagValue = accessTagValue(TAG_PADDING, keyParam); + switch (tagValue) { + case PaddingMode::NONE: + bitMap |= (1 << NONE_BIT_POS); + break; + case PaddingMode::RSA_OAEP: + bitMap |= (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS); + break; + case PaddingMode::RSA_PSS: + bitMap |= (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS); + break; + case PaddingMode::RSA_PKCS1_1_5_ENCRYPT: + bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS); + break; + case PaddingMode::RSA_PKCS1_1_5_SIGN: + bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS); + break; + case PaddingMode::PKCS7: + bitMap |= (1 << PaddingModeBitPosition::PKCS7_BIT_POS); + break; + default: + break; + } + tagValueCount -= 1; + } + return bitMap; +} + +int32_t generateBitMapForDigestValues(const AuthorizationSet& authorization_set) { + int32_t bitMap = 0; + int32_t tagValueCount = authorization_set.GetTagCount(TAG_DIGEST); + if (tagValueCount == 0) { + // unlike in the single enum fields, if no value is provided, + // 0 is set for the bitmap + return bitMap; + } + int current_offset = -1; + while (tagValueCount > 0) { + current_offset = authorization_set.find(TAG_DIGEST, current_offset); + KeyParameter keyParam = authorization_set[current_offset]; + auto tagValue = accessTagValue(TAG_DIGEST, keyParam); + switch (tagValue) { + case Digest::NONE: + bitMap |= (1 << NONE_BIT_POS); + break; + case Digest::MD5: + bitMap |= (1 << DigestBitPosition::MD5_BIT_POS); + break; + case Digest::SHA1: + bitMap |= (1 << DigestBitPosition::SHA1_BIT_POS); + break; + case Digest::SHA_2_224: + bitMap |= (1 << DigestBitPosition::SHA_2_224_BIT_POS); + break; + case Digest::SHA_2_256: + bitMap |= (1 << DigestBitPosition::SHA_2_256_BIT_POS); + break; + case Digest::SHA_2_384: + bitMap |= (1 << DigestBitPosition::SHA_2_384_BIT_POS); + break; + case Digest::SHA_2_512: + bitMap |= (1 << DigestBitPosition::SHA_2_512_BIT_POS); + break; + default: + break; + } + tagValueCount -= 1; + } + return bitMap; +} + +int32_t generateBitMapForBlockModeValues(const AuthorizationSet& authorization_set) { + int32_t bitMap = 0; + int32_t tagValueCount = authorization_set.GetTagCount(TAG_BLOCK_MODE); + if (tagValueCount == 0) { + // unlike in the single enum fields, if no value is provided, + // 0 is set for the bitmap + return bitMap; + } + int current_offset = -1; + while (tagValueCount > 0) { + current_offset = authorization_set.find(TAG_BLOCK_MODE, current_offset); + KeyParameter keyParam = authorization_set[current_offset]; + auto tagValue = accessTagValue(TAG_BLOCK_MODE, keyParam); + switch (tagValue) { + case BlockMode::ECB: + bitMap |= (1 << BlockModeBitPosition::ECB_BIT_POS); + break; + case BlockMode::CBC: + bitMap |= (1 << BlockModeBitPosition::CBC_BIT_POS); + break; + case BlockMode::CTR: + bitMap |= (1 << BlockModeBitPosition::CTR_BIT_POS); + break; + case BlockMode::GCM: + bitMap |= (1 << BlockModeBitPosition::GCM_BIT_POS); + break; + default: + break; + } + tagValueCount -= 1; + } + return bitMap; +} + +int32_t generateBitMapForKeyPurposeValues(const AuthorizationSet& authorization_set) { + int32_t bitMap = 0; + int32_t tagValueCount = authorization_set.GetTagCount(TAG_PURPOSE); + if (tagValueCount == 0) { + // unlike in the single enum fields, if no value is provided, + // 0 is set for the bitmap + return bitMap; + } + int current_offset = -1; + while (tagValueCount > 0) { + current_offset = authorization_set.find(TAG_PURPOSE, current_offset); + KeyParameter keyParam = authorization_set[current_offset]; + auto tagValue = accessTagValue(TAG_PURPOSE, keyParam); + switch (tagValue) { + case KeyPurpose::ENCRYPT: + bitMap |= (1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS); + break; + case KeyPurpose::DECRYPT: + bitMap |= (1 << KeyPurposeBitPosition::DECRYPT_BIT_POS); + break; + case KeyPurpose::SIGN: + bitMap |= (1 << KeyPurposeBitPosition::SIGN_BIT_POS); + break; + case KeyPurpose::VERIFY: + bitMap |= (1 << KeyPurposeBitPosition::VERIFY_BIT_POS); + break; + case KeyPurpose::WRAP_KEY: + bitMap |= (1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS); + break; + default: + break; + } + tagValueCount -= 1; + } + return bitMap; +} + +void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams, + bool wasCreationSuccessful, int32_t errorCode) { + AuthorizationSet authorization_set(keyParams); + authorization_set.Deduplicate(); + + android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED, + getEnumTagValue(authorization_set, TAG_ALGORITHM), + getEnumTagValue(authorization_set, TAG_KEY_SIZE), + getEnumTagValue(authorization_set, TAG_ORIGIN), + getEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE), + getEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT), + generateBitMapForPaddingModeValues(authorization_set), + generateBitMapForDigestValues(authorization_set), + generateBitMapForBlockModeValues(authorization_set), + generateBitMapForKeyPurposeValues(authorization_set), + getEnumTagValue(authorization_set, TAG_EC_CURVE), + getEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS), + android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_CREATION, + wasCreationSuccessful, errorCode); +} + +} // namespace keystore diff --git a/keystore/key_creation_log_handler.h b/keystore/key_creation_log_handler.h new file mode 100644 index 00000000..a314eb11 --- /dev/null +++ b/keystore/key_creation_log_handler.h @@ -0,0 +1,71 @@ +/* + * 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 KEY_CREATION_LOG_HANDLER_H_ +#define KEY_CREATION_LOG_HANDLER_H_ + +#include <keystore/keystore_hidl_support.h> + +namespace keystore { + +/** + * Following enums are defined as a part of the workaround to log the repeated + * values of ENUM_REP type. The workaround is to represent the repeated values + * of ENUM_REP type as a bitmap and the following enums define their positions + * in the bitmap. + */ + +enum PaddingModeBitPosition : int32_t { + RSA_OAEP_BIT_POS = 1, + RSA_PSS_BIT_POS = 2, + RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3, + RSA_PKCS1_1_5_SIGN_BIT_POS = 4, + PKCS7_BIT_POS = 5, +}; + +enum DigestBitPosition : int32_t { + MD5_BIT_POS = 1, + SHA1_BIT_POS = 2, + SHA_2_224_BIT_POS = 3, + SHA_2_256_BIT_POS = 4, + SHA_2_384_BIT_POS = 5, + SHA_2_512_BIT_POS = 6, +}; + +enum BlockModeBitPosition : int32_t { + ECB_BIT_POS = 1, + CBC_BIT_POS = 2, + CTR_BIT_POS = 3, + GCM_BIT_POS = 4, +}; + +enum KeyPurposeBitPosition : int32_t { + ENCRYPT_BIT_POS = 1, + DECRYPT_BIT_POS = 2, + SIGN_BIT_POS = 3, + VERIFY_BIT_POS = 4, + WRAP_KEY_BIT_POS = 5, +}; + +// None is an enum value for digest and a deprecated value for padding mode +const int32_t NONE_BIT_POS = 0; + +void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams, + bool wasCreationSuccessful, int32_t errorCode); + +} // namespace keystore + +#endif // KEY_CREATION_LOG_HANDLER_H_ diff --git a/keystore/key_proto_handler.cpp b/keystore/key_proto_handler.cpp deleted file mode 100644 index f8400af6..00000000 --- a/keystore/key_proto_handler.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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_1/Keymaster.h> -#include <keystore/keymaster_types.h> -#include <utils/String16.h> -#include <utils/StrongPointer.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); - android::sp<android::os::DropBoxManager> dropbox(new 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 deleted file mode 100644 index a2f6a243..00000000 --- a/keystore/key_proto_handler.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 583f5b6e..8501cdf8 100644 --- a/keystore/key_store_service.cpp +++ b/keystore/key_store_service.cpp @@ -41,7 +41,6 @@ #include <keymasterV4_0/keymaster_utils.h> #include "defaults.h" -#include "key_proto_handler.h" #include "keystore_keymaster_enforcement.h" #include "keystore_utils.h" #include <keystore/keystore_attestation_id.h> diff --git a/keystore/keymaster_worker.cpp b/keystore/keymaster_worker.cpp index 911815e0..e7fcf96a 100644 --- a/keystore/keymaster_worker.cpp +++ b/keystore/keymaster_worker.cpp @@ -29,7 +29,7 @@ #include "KeyStore.h" #include "keymaster_enforcement.h" -#include "key_proto_handler.h" +#include "key_creation_log_handler.h" #include "keystore_utils.h" #include <chrono> @@ -800,8 +800,10 @@ void KeymasterWorker::generateKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPa // by KeyStore::getFallbackDevice() bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT; - Finalize logOnFail( - [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); }); + Finalize logOnFail([&] { + logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/, + rc.getErrorCode()); + }); KeyCharacteristics outCharacteristics; KeyStoreServiceReturnCode error; @@ -870,7 +872,8 @@ void KeymasterWorker::generateKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPa // log on success logOnFail.release(); - uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */); + logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/, + error.getErrorCode()); return worker_cb(error, std::move(outCharacteristics)); }); @@ -904,11 +907,13 @@ void KeymasterWorker::importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPara // by KeyStore::getFallbackDevice() bool consider_fallback = securityLevel == SecurityLevel::TRUSTED_ENVIRONMENT; - Finalize logOnFail( - [&] { uploadKeyCharacteristicsAsProto(keyParams, false /* wasCreationSuccessful */); }); + KeyStoreServiceReturnCode error; + Finalize logOnFail([&] { + logKeystoreKeyCreationEvent(keyParams, false /*wasCreationSuccessful*/, + error.getErrorCode()); + }); KeyCharacteristics outCharacteristics; - KeyStoreServiceReturnCode error; auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob, const KeyCharacteristics& keyCharacteristics) { keymasterDevice_->logIfKeymasterVendorError(ret); @@ -975,7 +980,8 @@ void KeymasterWorker::importKey(LockedKeyBlobEntry lockedEntry, hidl_vec<KeyPara // log on success logOnFail.release(); - uploadKeyCharacteristicsAsProto(keyParams, true /* wasCreationSuccessful */); + logKeystoreKeyCreationEvent(keyParams, true /*wasCreationSuccessful*/, + error.getErrorCode()); return worker_cb(error, std::move(outCharacteristics)); }); |