diff --git a/HAL/Android.bp b/HAL/Android.bp index c705a012..69fead77 100644 --- a/HAL/Android.bp +++ b/HAL/Android.bp @@ -25,6 +25,7 @@ cc_library { "JavacardRemotelyProvisionedComponentDevice.cpp", "JavacardSecureElement.cpp", "JavacardSharedSecret.cpp", + "JavacardKeyMintUtils.cpp", "keymint_utils.cpp", ], cflags:["-O0",], @@ -32,7 +33,6 @@ cc_library { "android.hardware.security.keymint-V1-ndk", "android.hardware.security.secureclock-V1-ndk", "android.hardware.security.sharedsecret-V1-ndk", - "lib_android_keymaster_keymint_utils", "libbase", "libcppbor_external", "libkeymaster_portable", diff --git a/HAL/CborConverter.cpp b/HAL/CborConverter.cpp index 485fd8ee..e34c651c 100644 --- a/HAL/CborConverter.cpp +++ b/HAL/CborConverter.cpp @@ -16,7 +16,7 @@ */ #include "CborConverter.h" -#include +#include #include #include #include diff --git a/HAL/JavacardKeyMintDevice.cpp b/HAL/JavacardKeyMintDevice.cpp index 6b6932cf..584c75ed 100644 --- a/HAL/JavacardKeyMintDevice.cpp +++ b/HAL/JavacardKeyMintDevice.cpp @@ -18,7 +18,7 @@ #include "JavacardKeyMintDevice.h" #include "JavacardKeyMintOperation.h" #include "JavacardSharedSecret.h" -#include +#include #include #include #include diff --git a/HAL/JavacardKeyMintOperation.cpp b/HAL/JavacardKeyMintOperation.cpp index efbcd562..38cbb0b4 100644 --- a/HAL/JavacardKeyMintOperation.cpp +++ b/HAL/JavacardKeyMintOperation.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "javacard.strongbox.keymint.operation-impl" #include "JavacardKeyMintOperation.h" -#include +#include #include #include #include diff --git a/HAL/JavacardKeyMintUtils.cpp b/HAL/JavacardKeyMintUtils.cpp new file mode 100644 index 00000000..9860d407 --- /dev/null +++ b/HAL/JavacardKeyMintUtils.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2020 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. + */ + +#include "JavacardKeyMintUtils.h" +#include +#include + +namespace aidl::android::hardware::security::keymint::km_utils { + +keymaster_key_param_t kInvalidTag{.tag = KM_TAG_INVALID, .integer = 0}; + +KeyParameter kmEnumParam2Aidl(const keymaster_key_param_t& param) { + switch (param.tag) { + case KM_TAG_PURPOSE: + return KeyParameter{Tag::PURPOSE, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_ALGORITHM: + return KeyParameter{Tag::ALGORITHM, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_BLOCK_MODE: + return KeyParameter{Tag::BLOCK_MODE, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_DIGEST: + return KeyParameter{Tag::DIGEST, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_PADDING: + return KeyParameter{Tag::PADDING, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_EC_CURVE: + return KeyParameter{Tag::EC_CURVE, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_USER_AUTH_TYPE: + return KeyParameter{Tag::USER_AUTH_TYPE, + KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_ORIGIN: + return KeyParameter{Tag::ORIGIN, KeyParameterValue::make( + static_cast(param.enumerated))}; + case KM_TAG_BLOB_USAGE_REQUIREMENTS: + case KM_TAG_KDF: + default: + return KeyParameter{Tag::INVALID, false}; + } +} + + +KeyParameter kmParam2Aidl(const keymaster_key_param_t& param) { + auto tag = legacy_enum_conversion(param.tag); + switch (typeFromTag(param.tag)) { + case KM_ENUM: + case KM_ENUM_REP: + return kmEnumParam2Aidl(param); + break; + + case KM_UINT: + case KM_UINT_REP: + return KeyParameter{tag, + KeyParameterValue::make(param.integer)}; + + case KM_ULONG: + case KM_ULONG_REP: + return KeyParameter{ + tag, KeyParameterValue::make(param.long_integer)}; + break; + + case KM_DATE: + return KeyParameter{tag, + KeyParameterValue::make(param.date_time)}; + break; + + case KM_BOOL: + return KeyParameter{tag, param.boolean}; + break; + + case KM_BIGNUM: + case KM_BYTES: + return {tag, KeyParameterValue::make( + std::vector(param.blob.data, param.blob.data + param.blob.data_length))}; + break; + + case KM_INVALID: + default: + CHECK(false) << "Unknown or unused tag type: Something is broken"; + return KeyParameter{Tag::INVALID, false}; + break; + } +} + +vector kmParamSet2Aidl(const keymaster_key_param_set_t& set) { + vector result; + if (set.length == 0 || set.params == nullptr) return result; + + result.reserve(set.length); + for (size_t i = 0; i < set.length; ++i) { + result.push_back(kmParam2Aidl(set.params[i])); + } + return result; +} + +template +keymaster_key_param_t aidlEnumVal2Km(keymaster_tag_t km_tag, const KeyParameterValue& value) { + return value.getTag() == aidl_tag + ? keymaster_param_enum(km_tag, static_cast(value.get())) + : kInvalidTag; +} + +keymaster_key_param_t aidlEnumParam2Km(const KeyParameter& param) { + auto tag = legacy_enum_conversion(param.tag); + switch (tag) { + case KM_TAG_PURPOSE: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_ALGORITHM: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_BLOCK_MODE: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_DIGEST: + case KM_TAG_RSA_OAEP_MGF_DIGEST: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_PADDING: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_EC_CURVE: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_USER_AUTH_TYPE: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_ORIGIN: + return aidlEnumVal2Km(tag, param.value); + case KM_TAG_BLOB_USAGE_REQUIREMENTS: + case KM_TAG_KDF: + default: + CHECK(false) << "Unknown or unused enum tag: Something is broken"; + return keymaster_param_enum(tag, false); + } +} + + + +keymaster_error_t legacyHardwareAuthToken(const HardwareAuthToken& aidlToken, + LegacyHardwareAuthToken* legacyToken) { + legacyToken->challenge = aidlToken.challenge; + legacyToken->user_id = aidlToken.userId; + legacyToken->authenticator_id = aidlToken.authenticatorId; + legacyToken->authenticator_type = + static_cast(aidlToken.authenticatorType); + legacyToken->timestamp = aidlToken.timestamp.milliSeconds; + Vec2KmBlob(aidlToken.mac, &legacyToken->mac); + return KM_ERROR_OK; +} + +keymaster_error_t encodeTimestampToken(const TimeStampToken& timestampToken, + vector* encodedToken) { + cppbor::Array array; + ::keymaster::TimestampToken token; + array.add(static_cast(timestampToken.challenge)); + array.add(static_cast(timestampToken.timestamp.milliSeconds)); + array.add(timestampToken.mac); + *encodedToken = array.encode(); + return KM_ERROR_OK; +} + +keymaster_key_param_set_t aidlKeyParams2Km(const vector& keyParams) { + keymaster_key_param_set_t set; + + set.params = static_cast( + malloc(keyParams.size() * sizeof(keymaster_key_param_t))); + set.length = keyParams.size(); + + for (size_t i = 0; i < keyParams.size(); ++i) { + const auto& param = keyParams[i]; + auto tag = legacy_enum_conversion(param.tag); + switch (typeFromTag(tag)) { + + case KM_ENUM: + case KM_ENUM_REP: + set.params[i] = aidlEnumParam2Km(param); + break; + + case KM_UINT: + case KM_UINT_REP: + set.params[i] = + param.value.getTag() == KeyParameterValue::integer + ? keymaster_param_int(tag, param.value.get()) + : kInvalidTag; + break; + + case KM_ULONG: + case KM_ULONG_REP: + set.params[i] = + param.value.getTag() == KeyParameterValue::longInteger + ? keymaster_param_long(tag, param.value.get()) + : kInvalidTag; + break; + + case KM_DATE: + set.params[i] = + param.value.getTag() == KeyParameterValue::dateTime + ? keymaster_param_date(tag, param.value.get()) + : kInvalidTag; + break; + + case KM_BOOL: + set.params[i] = keymaster_param_bool(tag); + break; + + case KM_BIGNUM: + case KM_BYTES: + if (param.value.getTag() == KeyParameterValue::blob) { + const auto& value = param.value.get(); + uint8_t* copy = static_cast(malloc(value.size())); + std::copy(value.begin(), value.end(), copy); + set.params[i] = keymaster_param_blob(tag, copy, value.size()); + } else { + set.params[i] = kInvalidTag; + } + break; + + case KM_INVALID: + default: + CHECK(false) << "Invalid tag: Something is broken"; + set.params[i].tag = KM_TAG_INVALID; + /* just skip */ + break; + } + } + + return set; +} + +} // namespace aidl::android::hardware::security::keymint diff --git a/HAL/JavacardKeyMintUtils.h b/HAL/JavacardKeyMintUtils.h new file mode 100644 index 00000000..9b103ff1 --- /dev/null +++ b/HAL/JavacardKeyMintUtils.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2020 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. + */ + +#pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::security::keymint::km_utils { +using namespace ::keymaster; +using secureclock::TimeStampToken; +using ::ndk::ScopedAStatus; +using std::vector; +using LegacyHardwareAuthToken = ::keymaster::HardwareAuthToken; + +inline keymaster_tag_t legacy_enum_conversion(const Tag value) { + return static_cast(value); +} + +inline Tag legacy_enum_conversion(const keymaster_tag_t value) { + return static_cast(value); +} + +inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) { + return keymaster_tag_get_type(tag); +} + +inline void Vec2KmBlob(const vector& input, KeymasterBlob* blob) { + blob->Reset(input.size()); + memcpy(blob->writable_data(), input.data(), input.size()); +} + +inline vector kmBlob2vector(const keymaster_key_blob_t& blob) { + vector result(blob.key_material, blob.key_material + blob.key_material_size); + return result; +} + +inline vector kmBlob2vector(const keymaster_blob_t& blob) { + vector result(blob.data, blob.data + blob.data_length); + return result; +} + +keymaster_error_t legacyHardwareAuthToken(const HardwareAuthToken& aidlToken, + LegacyHardwareAuthToken* legacyToken); + +keymaster_error_t encodeTimestampToken(const TimeStampToken& timestampToken, + vector* encodedToken); + +inline ScopedAStatus kmError2ScopedAStatus(const keymaster_error_t value) { + return (value == KM_ERROR_OK + ? ScopedAStatus::ok() + : ScopedAStatus(AStatus_fromServiceSpecificError(static_cast(value)))); +} + +KeyParameter kmParam2Aidl(const keymaster_key_param_t& param); +vector kmParamSet2Aidl(const keymaster_key_param_set_t& set); +keymaster_key_param_set_t aidlKeyParams2Km(const vector& keyParams); + +class KmParamSet : public keymaster_key_param_set_t { + public: + explicit KmParamSet(const vector& keyParams) + : keymaster_key_param_set_t(aidlKeyParams2Km(keyParams)) {} + + KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} { + other.length = 0; + other.params = nullptr; + } + + KmParamSet(const KmParamSet&) = delete; + ~KmParamSet() { keymaster_free_param_set(this); } +}; + +} // namespace aidl::android::hardware::security::keymint diff --git a/HAL/JavacardRemotelyProvisionedComponentDevice.cpp b/HAL/JavacardRemotelyProvisionedComponentDevice.cpp index 5657f9e2..9055de94 100644 --- a/HAL/JavacardRemotelyProvisionedComponentDevice.cpp +++ b/HAL/JavacardRemotelyProvisionedComponentDevice.cpp @@ -17,7 +17,7 @@ #define LOG_TAG "javacard.keymint.device.rkp.strongbox-impl" #include #include -#include +#include #include #include #include diff --git a/HAL/JavacardSharedSecret.cpp b/HAL/JavacardSharedSecret.cpp index cc83eabd..2f4dfe4b 100644 --- a/HAL/JavacardSharedSecret.cpp +++ b/HAL/JavacardSharedSecret.cpp @@ -2,7 +2,7 @@ #include #include "JavacardSharedSecret.h" -#include +#include namespace aidl::android::hardware::security::sharedsecret { using namespace ::keymint::javacard;