Change KeyParameters to use a union.
This CL updates AndroidKeyMintDevice to use the new unionized
KeyParameters.
Test: VtsAidlKeyMintTargetTest
Change-Id: I2be1a192d26d44c99a33a8daf41937264ba5ab63
diff --git a/ng/KeyMintUtils.cpp b/ng/KeyMintUtils.cpp
index 5238f6e..c5a2d63 100644
--- a/ng/KeyMintUtils.cpp
+++ b/ng/KeyMintUtils.cpp
@@ -14,12 +14,89 @@
* limitations under the License.
*/
+#define LOG_TAG "android.hardware.security.keymint-impl"
+#include <android-base/logging.h>
+
#include "KeyMintUtils.h"
-namespace aidl::android::hardware::security::keymint {
+namespace aidl::android::hardware::security::keymint::km_utils {
using namespace ::keymaster;
+namespace {
+
+KeyParameter kmEnumParam2Aidl(const keymaster_key_param_t& param) {
+ switch (param.tag) {
+ case KM_TAG_PURPOSE:
+ return KeyParameter{Tag::PURPOSE, KeyParameterValue::make<KeyParameterValue::keyPurpose>(
+ static_cast<KeyPurpose>(param.enumerated))};
+ case KM_TAG_ALGORITHM:
+ return KeyParameter{Tag::ALGORITHM, KeyParameterValue::make<KeyParameterValue::algorithm>(
+ static_cast<Algorithm>(param.enumerated))};
+ case KM_TAG_BLOCK_MODE:
+ return KeyParameter{Tag::BLOCK_MODE, KeyParameterValue::make<KeyParameterValue::blockMode>(
+ static_cast<BlockMode>(param.enumerated))};
+ case KM_TAG_DIGEST:
+ return KeyParameter{Tag::DIGEST, KeyParameterValue::make<KeyParameterValue::digest>(
+ static_cast<Digest>(param.enumerated))};
+ case KM_TAG_PADDING:
+ return KeyParameter{Tag::PADDING, KeyParameterValue::make<KeyParameterValue::paddingMode>(
+ static_cast<PaddingMode>(param.enumerated))};
+ case KM_TAG_EC_CURVE:
+ return KeyParameter{Tag::EC_CURVE, KeyParameterValue::make<KeyParameterValue::ecCurve>(
+ static_cast<EcCurve>(param.enumerated))};
+ case KM_TAG_USER_AUTH_TYPE:
+ return KeyParameter{Tag::USER_AUTH_TYPE,
+ KeyParameterValue::make<KeyParameterValue::hardwareAuthenticatorType>(
+ static_cast<HardwareAuthenticatorType>(param.enumerated))};
+ case KM_TAG_ORIGIN:
+ return KeyParameter{Tag::ORIGIN, KeyParameterValue::make<KeyParameterValue::origin>(
+ static_cast<KeyOrigin>(param.enumerated))};
+ case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+ case KM_TAG_KDF:
+ default:
+ return KeyParameter{Tag::INVALID, false};
+ }
+}
+
+keymaster_key_param_t kInvalidTag{.tag = KM_TAG_INVALID, .integer = 0};
+
+template <KeyParameterValue::Tag aidl_tag>
+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<uint32_t>(value.get<aidl_tag>()))
+ : kInvalidTag;
+}
+
+keymaster_key_param_t aidlEnumParam2Km(const KeyParameter& param) {
+ auto tag = km_utils::legacy_enum_conversion(param.tag);
+ switch (tag) {
+ case KM_TAG_PURPOSE:
+ return aidlEnumVal2Km<KeyParameterValue::keyPurpose>(tag, param.value);
+ case KM_TAG_ALGORITHM:
+ return aidlEnumVal2Km<KeyParameterValue::algorithm>(tag, param.value);
+ case KM_TAG_BLOCK_MODE:
+ return aidlEnumVal2Km<KeyParameterValue::blockMode>(tag, param.value);
+ case KM_TAG_DIGEST:
+ return aidlEnumVal2Km<KeyParameterValue::digest>(tag, param.value);
+ case KM_TAG_PADDING:
+ return aidlEnumVal2Km<KeyParameterValue::paddingMode>(tag, param.value);
+ case KM_TAG_EC_CURVE:
+ return aidlEnumVal2Km<KeyParameterValue::ecCurve>(tag, param.value);
+ case KM_TAG_USER_AUTH_TYPE:
+ return aidlEnumVal2Km<KeyParameterValue::hardwareAuthenticatorType>(tag, param.value);
+ case KM_TAG_ORIGIN:
+ return aidlEnumVal2Km<KeyParameterValue::origin>(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);
+ }
+}
+
+} // namespace
+
vector<uint8_t> authToken2AidlVec(const HardwareAuthToken& token) {
static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
@@ -44,90 +121,112 @@
return result;
}
-// TODO(seleneh): This needs to be modified depends on how aidl support for union came out to
-// be.
vector<KeyParameter> kmParamSet2Aidl(const keymaster_key_param_set_t& set) {
vector<KeyParameter> result;
if (set.length == 0 || set.params == nullptr) return result;
- result.resize(set.length);
+ result.reserve(set.length);
keymaster_key_param_t* params = set.params;
for (size_t i = 0; i < set.length; ++i) {
- auto tag = params[i].tag;
- result[i].tag = legacy_enum_conversion(tag);
- switch (typeFromTag(tag)) {
+ auto tag = legacy_enum_conversion(params[i].tag);
+ switch (typeFromTag(params[i].tag)) {
case KM_ENUM:
case KM_ENUM_REP:
- result[i].integer = params[i].enumerated;
+ result.push_back(kmEnumParam2Aidl(params[i]));
break;
case KM_UINT:
case KM_UINT_REP:
- result[i].integer = params[i].integer;
+ result.push_back(KeyParameter{
+ tag, KeyParameterValue::make<KeyParameterValue::integer>(params[i].integer)});
break;
case KM_ULONG:
case KM_ULONG_REP:
- result[i].longInteger = params[i].long_integer;
+ result.push_back(KeyParameter{
+ tag,
+ KeyParameterValue::make<KeyParameterValue::longInteger>(params[i].long_integer)});
break;
case KM_DATE:
- result[i].longInteger = params[i].date_time;
+ result.push_back(KeyParameter{
+ tag, KeyParameterValue::make<KeyParameterValue::dateTime>(params[i].date_time)});
break;
case KM_BOOL:
- result[i].boolValue = params[i].boolean;
+ result.push_back(KeyParameter{tag, params[i].boolean});
break;
case KM_BIGNUM:
case KM_BYTES:
- result[i].blob.assign(params[i].blob.data,
- params[i].blob.data + params[i].blob.data_length);
+ result.push_back(
+ {tag, KeyParameterValue::make<KeyParameterValue::blob>(std::vector(
+ params[i].blob.data, params[i].blob.data + params[i].blob.data_length))});
break;
case KM_INVALID:
default:
- params[i].tag = KM_TAG_INVALID;
- /* just skip */
+ CHECK(false) << "Unknown or unused enum tag: Something is broken";
+ result.push_back(KeyParameter{tag, false});
break;
}
}
return result;
}
-// TODO(seleneh): This needs to be modified depends on how aidl support for union came out to
-// be.
keymaster_key_param_set_t aidlKeyParams2Km(const vector<KeyParameter>& keyParams) {
keymaster_key_param_set_t set;
- set.params = new keymaster_key_param_t[keyParams.size()];
+ set.params = static_cast<keymaster_key_param_t*>(
+ malloc(keyParams.size() * sizeof(keymaster_key_param_t)));
set.length = keyParams.size();
for (size_t i = 0; i < keyParams.size(); ++i) {
- auto tag = legacy_enum_conversion(keyParams[i].tag);
+ 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] = keymaster_param_enum(tag, keyParams[i].integer);
+ set.params[i] = aidlEnumParam2Km(param);
break;
+
case KM_UINT:
case KM_UINT_REP:
- set.params[i] = keymaster_param_int(tag, keyParams[i].integer);
+ set.params[i] =
+ param.value.getTag() == KeyParameterValue::integer
+ ? keymaster_param_int(tag, param.value.get<KeyParameterValue::integer>())
+ : kInvalidTag;
break;
+
case KM_ULONG:
case KM_ULONG_REP:
- set.params[i] = keymaster_param_long(tag, keyParams[i].longInteger);
+ set.params[i] =
+ param.value.getTag() == KeyParameterValue::longInteger
+ ? keymaster_param_long(tag, param.value.get<KeyParameterValue::longInteger>())
+ : kInvalidTag;
break;
+
case KM_DATE:
- set.params[i] = keymaster_param_date(tag, keyParams[i].longInteger);
+ set.params[i] =
+ param.value.getTag() == KeyParameterValue::dateTime
+ ? keymaster_param_date(tag, param.value.get<KeyParameterValue::dateTime>())
+ : kInvalidTag;
break;
+
case KM_BOOL:
- if (keyParams[i].boolValue)
- set.params[i] = keymaster_param_bool(tag);
- else
- set.params[i].tag = KM_TAG_INVALID;
+ set.params[i] = keymaster_param_bool(tag);
break;
+
case KM_BIGNUM:
case KM_BYTES:
- set.params[i] =
- keymaster_param_blob(tag, keyParams[i].blob.data(), keyParams[i].blob.size());
+ if (param.value.getTag() == KeyParameterValue::blob) {
+ const auto& value = param.value.get<KeyParameterValue::blob>();
+ uint8_t* copy = static_cast<uint8_t*>(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;
@@ -137,4 +236,4 @@
return set;
}
-} // namespace aidl::android::hardware::security::keymint
+} // namespace aidl::android::hardware::security::keymint::km_utils