From 83fa6413ac4e0d5af8782bb9e806f1fa02a56347 Mon Sep 17 00:00:00 2001 From: Shawn Willden Date: Mon, 7 Dec 2020 15:03:00 -0700 Subject: [PATCH] Change KeyParameters to use a union. AIDL now supports union types. This CL changes KeyParameter to use one. Test: VtsAidlKeyMintTargetTest Change-Id: I5112611b161e3de1ea86105ea3c7ed0912036a7b --- .../security/keymint/KeyParameter.aidl | 7 +- ...onFunction.aidl => KeyParameterValue.aidl} | 25 +++-- .../keymint/KeyDerivationFunction.aidl | 37 -------- .../security/keymint/KeyParameter.aidl | 30 +----- .../security/keymint/KeyParameterValue.aidl | 54 +++++++++++ .../include/keymint_support/keymint_tags.h | 95 ++++++++++--------- security/keymint/support/key_param_output.cpp | 32 +------ 7 files changed, 125 insertions(+), 155 deletions(-) rename security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/{KeyDerivationFunction.aidl => KeyParameterValue.aidl} (58%) delete mode 100644 security/keymint/aidl/android/hardware/security/keymint/KeyDerivationFunction.aidl create mode 100644 security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl index 91f83e4071..498576825c 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameter.aidl @@ -16,11 +16,8 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; -@VintfStability +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability parcelable KeyParameter { android.hardware.security.keymint.Tag tag; - boolean boolValue; - int integer; - long longInteger; - byte[] blob; + android.hardware.security.keymint.KeyParameterValue value; } diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyDerivationFunction.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl similarity index 58% rename from security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyDerivationFunction.aidl rename to security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl index 83b7e6e7ee..ecf20ad75b 100644 --- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyDerivationFunction.aidl +++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/KeyParameterValue.aidl @@ -16,12 +16,21 @@ // later when a module using the interface is updated, e.g., Mainline modules. package android.hardware.security.keymint; -@Backing(type="int") @VintfStability -enum KeyDerivationFunction { - NONE = 0, - RFC5869_SHA256 = 1, - ISO18033_2_KDF1_SHA1 = 2, - ISO18033_2_KDF1_SHA256 = 3, - ISO18033_2_KDF2_SHA1 = 4, - ISO18033_2_KDF2_SHA256 = 5, +@RustDerive(Clone=true, Eq=true, Hash=true, Ord=true, PartialEq=true, PartialOrd=true) @VintfStability +union KeyParameterValue { + int invalid; + android.hardware.security.keymint.Algorithm algorithm; + android.hardware.security.keymint.BlockMode blockMode; + android.hardware.security.keymint.PaddingMode paddingMode; + android.hardware.security.keymint.Digest digest; + android.hardware.security.keymint.EcCurve ecCurve; + android.hardware.security.keymint.KeyOrigin origin; + android.hardware.security.keymint.KeyPurpose keyPurpose; + android.hardware.security.keymint.HardwareAuthenticatorType hardwareAuthenticatorType; + android.hardware.security.keymint.SecurityLevel securityLevel; + boolean boolValue; + int integer; + long longInteger; + long dateTime; + byte[] blob; } diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyDerivationFunction.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyDerivationFunction.aidl deleted file mode 100644 index e166ab6ad9..0000000000 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyDerivationFunction.aidl +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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. - */ - -package android.hardware.security.keymint; - -/** - * Key derivation functions, mostly used in ECIES. - */ -@VintfStability -@Backing(type="int") -enum KeyDerivationFunction { - /** Do not apply a key derivation function; use the raw agreed key */ - NONE = 0, - /** HKDF defined in RFC 5869 with SHA256 */ - RFC5869_SHA256 = 1, - /** KDF1 defined in ISO 18033-2 with SHA1 */ - ISO18033_2_KDF1_SHA1 = 2, - /** KDF1 defined in ISO 18033-2 with SHA256 */ - ISO18033_2_KDF1_SHA256 = 3, - /** KDF2 defined in ISO 18033-2 with SHA1 */ - ISO18033_2_KDF2_SHA1 = 4, - /** KDF2 defined in ISO 18033-2 with SHA256 */ - ISO18033_2_KDF2_SHA256 = 5, -} diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl index 938064ca53..f3ed96b83f 100644 --- a/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameter.aidl @@ -16,40 +16,16 @@ package android.hardware.security.keymint; -import android.hardware.security.keymint.Algorithm; -import android.hardware.security.keymint.BlockMode; -import android.hardware.security.keymint.Digest; -import android.hardware.security.keymint.EcCurve; -import android.hardware.security.keymint.HardwareAuthenticatorType; -import android.hardware.security.keymint.KeyDerivationFunction; -import android.hardware.security.keymint.KeyOrigin; -import android.hardware.security.keymint.KeyPurpose; -import android.hardware.security.keymint.PaddingMode; -import android.hardware.security.keymint.SecurityLevel; import android.hardware.security.keymint.Tag; - +import android.hardware.security.keymint.KeyParameterValue; /** * Identifies the key authorization parameters to be used with keyMint. This is usually * provided as an array of KeyParameters to IKeyMintDevice or Operation. - * - * TODO(seleneh): Union was not supported in aidl when this cl is first drafted. So we just had - * the Tags, and bool, int, long, int[], and we will cast to the appropate types base on the - * Tag value. We need to update this defination to distingish Algorithm, BlockMode, - * PaddingMode, KeyOrigin...etc later, as union support is recently added to aidl. - * b/173253030 */ @VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) parcelable KeyParameter { - /** - * Identify what type of key parameter this parcelable actually holds, and based on the type - * of tag is int, long, bool, or byte[], one of the fields below will be referenced. - */ Tag tag; - - boolean boolValue; - int integer; - long longInteger; - // TODO: change this to nullable. - byte[] blob; + KeyParameterValue value; } diff --git a/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl new file mode 100644 index 0000000000..a4f5154e62 --- /dev/null +++ b/security/keymint/aidl/android/hardware/security/keymint/KeyParameterValue.aidl @@ -0,0 +1,54 @@ +/* + * 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. + */ + +package android.hardware.security.keymint; + +import android.hardware.security.keymint.Algorithm; +import android.hardware.security.keymint.BlockMode; +import android.hardware.security.keymint.Digest; +import android.hardware.security.keymint.EcCurve; +import android.hardware.security.keymint.HardwareAuthenticatorType; +import android.hardware.security.keymint.KeyOrigin; +import android.hardware.security.keymint.KeyPurpose; +import android.hardware.security.keymint.PaddingMode; +import android.hardware.security.keymint.SecurityLevel; + +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true, Ord=true, PartialOrd=true, Hash=true) +union KeyParameterValue { + + /* Represents an invalid value type. */ + int invalid; + + /* Enum types */ + Algorithm algorithm; + BlockMode blockMode; + PaddingMode paddingMode; + Digest digest; + EcCurve ecCurve; + KeyOrigin origin; + KeyPurpose keyPurpose; + HardwareAuthenticatorType hardwareAuthenticatorType; + SecurityLevel securityLevel; + + /* Other types */ + boolean boolValue; // Always true, if present. + int integer; + long longInteger; + long dateTime; + + byte[] blob; +} diff --git a/security/keymint/support/include/keymint_support/keymint_tags.h b/security/keymint/support/include/keymint_support/keymint_tags.h index 4e3d7ff3a0..c443c535ff 100644 --- a/security/keymint/support/include/keymint_support/keymint_tags.h +++ b/security/keymint/support/include/keymint_support/keymint_tags.h @@ -141,72 +141,73 @@ using all_tags_t = MetaList< template struct TypedTag2ValueType; -#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name) \ - template \ - struct TypedTag2ValueType> { \ - typedef decltype(static_cast(nullptr)->field_name) type; \ - }; \ - template \ - inline auto accessTagValue(TypedTag, const KeyParameter& param) \ - ->const decltype(param.field_name)& { \ - return param.field_name; \ - } \ - template \ - inline auto accessTagValue(TypedTag, KeyParameter& param) \ - ->decltype(param.field_name)& { \ - return param.field_name; \ +#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name) \ + template \ + struct TypedTag2ValueType> { \ + using type = std::remove_reference(nullptr) \ + ->get())>::type; \ + static constexpr KeyParameterValue::Tag unionTag = KeyParameterValue::field_name; \ + }; \ + template \ + inline auto& accessTagValue(TypedTag, const KeyParameter& param) { \ + return param.value.get(); \ + } \ + template \ + inline auto& accessTagValue(TypedTag, KeyParameter& param) { \ + return param.value.get(); \ } MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, longInteger) MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, longInteger) -MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, longInteger) +MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, dateTime) MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, integer) MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, integer) MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, boolValue) MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob) MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob) -// TODO(seleneh) change these MAKE_TAG_ENUM_VALUE_ACCESSOR back to the 2 parameter -// version when aidl supports union -#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name, field_type) \ - template <> \ - struct TypedTag2ValueType { \ - typedef field_type type; \ - }; \ - inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param) \ - ->const field_type& { \ - return *reinterpret_cast(¶m.field_name); \ - } \ - inline auto accessTagValue(decltype(typed_tag), KeyParameter& param)->field_type& { \ - return *reinterpret_cast(¶m.field_name); \ +#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name) \ + template <> \ + struct TypedTag2ValueType { \ + using type = std::remove_reference(nullptr) \ + ->get())>::type; \ + static constexpr KeyParameterValue::Tag unionTag = KeyParameterValue::field_name; \ + }; \ + inline auto& accessTagValue(decltype(typed_tag), const KeyParameter& param) { \ + return param.value.get(); \ + } \ + inline auto& accessTagValue(decltype(typed_tag), KeyParameter& param) { \ + return param.value.get(); \ } -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, integer, Algorithm) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, integer, BlockMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, integer, Digest) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, integer, EcCurve) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, integer, KeyOrigin) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, integer, PaddingMode) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, integer, KeyPurpose) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, integer, HardwareAuthenticatorType) -MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_HARDWARE_TYPE, integer, SecurityLevel) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, algorithm) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, blockMode) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, digest) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, ecCurve) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, origin) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, paddingMode) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, keyPurpose) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, hardwareAuthenticatorType) +MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_HARDWARE_TYPE, securityLevel) template inline KeyParameter makeKeyParameter(TypedTag ttag, ValueT&& value) { - KeyParameter param; - param.tag = tag; - param.longInteger = 0; - accessTagValue(ttag, param) = std::forward(value); - return param; + KeyParameter retval; + retval.tag = tag; + retval.value = KeyParameterValue::make::unionTag>( + std::forward(value)); + return retval; } // the boolean case template inline KeyParameter makeKeyParameter(TypedTag) { - KeyParameter param; - param.tag = tag; - param.boolValue = true; - return param; + KeyParameter retval; + retval.tag = tag; + retval.value = KeyParameterValue::make(true); + return retval; } template @@ -321,7 +322,7 @@ std::remove_reference_t defaultOr(NullOr&& optional, Default&& template inline NullOr>::type&> authorizationValue( TypedTag ttag, const KeyParameter& param) { - if (tag != param.tag) return {}; + if (TypedTag2ValueType>::unionTag != param.value.getTag()) return {}; return accessTagValue(ttag, param); } diff --git a/security/keymint/support/key_param_output.cpp b/security/keymint/support/key_param_output.cpp index c56e0354e6..0950eb69f8 100644 --- a/security/keymint/support/key_param_output.cpp +++ b/security/keymint/support/key_param_output.cpp @@ -35,38 +35,8 @@ ostream& operator<<(ostream& os, const ::std::vector& set) { return os; } -// TODO(seleneh) update this to a parsing that looks at each tags individually -// such as ALGORITHM BLOCK_MODE when aidl union support is added. ostream& operator<<(ostream& os, const KeyParameter& param) { - os << param.tag << ": "; - switch (typeFromTag(param.tag)) { - case TagType::INVALID: - return os << " Invalid"; - case TagType::ENUM_REP: - case TagType::ENUM: - case TagType::UINT_REP: - case TagType::UINT: - return os << param.integer; - case TagType::ULONG_REP: - case TagType::ULONG: - case TagType::DATE: - return os << param.longInteger; - case TagType::BOOL: - return os << "true"; - case TagType::BIGNUM: - os << " Bignum: "; - for (size_t i = 0; i < param.blob.size(); ++i) { - os << std::hex << ::std::setw(2) << static_cast(param.blob[i]) << ::std::dec; - } - return os; - case TagType::BYTES: - os << " Bytes: "; - for (size_t i = 0; i < param.blob.size(); ++i) { - os << ::std::hex << ::std::setw(2) << static_cast(param.blob[i]) << ::std::dec; - } - return os; - } - return os << "UNKNOWN TAG TYPE!"; + return os << param.toString(); } } // namespace aidl::android::hardware::security::keymint