1 /* 2 * Copyright 2014 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 17 #ifndef SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_ 18 #define SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_ 19 20 /** 21 * This header contains various definitions that make working with keymaster tags safer and easier. 22 * It makes use of a fair amount of template metaprogramming, which is genarally a bad idea for 23 * maintainability, but in this case all of the metaprogramming serves the purpose of making it 24 * impossible to make certain classes of mistakes when operating on keymaster authorizations. For 25 * example, it's an error to create a keymaster_param_t with tag == KM_TAG_PURPOSE and then to 26 * assign KM_ALGORITHM_RSA to the enumerated element of its union, but because "enumerated" is a 27 * uint32_t, there's no way for the compiler, ordinarily, to diagnose it. Also, generic functions 28 * to manipulate authorizations of multiple types can't be written, because they need to know which 29 * union parameter to modify. 30 * 31 * The machinery in this header solves these problems. The core elements are two templated classes, 32 * TypedTag and TypedEnumTag. These classes are templated on a tag type and a tag value, and in the 33 * case of TypedEnumTag, an enumeration type as well. Specializations are created for each 34 * keymaster tag, associating the tag type with the tag, and an instance of each specialization is 35 * created, and named the same as the keymaster tag, but with the KM_ prefix omitted. Because the 36 * classes include a conversion operator to keymaster_tag_t, they can be used anywhere a 37 * keymaster_tag_t is expected. 38 * 39 * They also define a "value_type" typedef, which specifies the type of values associated with that 40 * particular tag. This enables template functions to be written that check that the correct 41 * parameter type is used for a given tag, and that use the correct union entry for the tag type. A 42 * very useful example is the overloaded "Authorization" function defined below, which takes tag and 43 * value arguments and correctly constructs a keyamster_param_t struct. 44 * 45 * Because the classes have no data members and all of their methods are inline, they have ZERO 46 * run-time cost in and of themselves. The one way in which they can create code bloat is when 47 * template functions using them are expanded multiple times. The standard method of creating 48 * trivial, inlined template functions which call non-templated functions which are compact but not 49 * type-safe, allows the program to have both the type-safety of the templates and the compactness 50 * of the non-templated functions, at the same time. 51 */ 52 53 #include <hardware/hw_auth_token.h> 54 #include <hardware/keymaster_defs.h> 55 56 namespace keymaster { 57 58 // The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have. We 59 // need these old values to be able to support old keys that use them. 60 static const keymaster_tag_t KM_TAG_DIGEST_OLD = static_cast<keymaster_tag_t>(KM_ENUM | 5); 61 static const keymaster_tag_t KM_TAG_PADDING_OLD = static_cast<keymaster_tag_t>(KM_ENUM | 7); 62 63 // Until we have C++11, fake std::static_assert. 64 template <bool b> struct StaticAssert {}; 65 template <> struct StaticAssert<true> { 66 static void check() {} 67 }; 68 69 // An unusable type that we can associate with tag types that don't have a simple value type. 70 // That will prevent the associated type from being used inadvertently. 71 class Void { 72 Void(); 73 ~Void(); 74 }; 75 76 /** 77 * A template that defines the association between non-enumerated tag types and their value 78 * types. For each tag type we define a specialized struct that contains a typedef "value_type". 79 */ 80 template <keymaster_tag_type_t tag_type> struct TagValueType {}; 81 template <> struct TagValueType<KM_ULONG> { typedef uint64_t value_type; }; 82 template <> struct TagValueType<KM_ULONG_REP> { typedef uint64_t value_type; }; 83 template <> struct TagValueType<KM_DATE> { typedef uint64_t value_type; }; 84 template <> struct TagValueType<KM_UINT> { typedef uint32_t value_type; }; 85 template <> struct TagValueType<KM_UINT_REP> { typedef uint32_t value_type; }; 86 template <> struct TagValueType<KM_INVALID> { typedef Void value_type; }; 87 template <> struct TagValueType<KM_BOOL> { typedef bool value_type; }; 88 template <> struct TagValueType<KM_BYTES> { typedef keymaster_blob_t value_type; }; 89 template <> struct TagValueType<KM_BIGNUM> { typedef keymaster_blob_t value_type; }; 90 91 /** 92 * TypedTag is a templatized version of keymaster_tag_t, which provides compile-time checking of 93 * keymaster tag types. Instances are convertible to keymaster_tag_t, so they can be used wherever 94 * keymaster_tag_t is expected, and because they encode the tag type it's possible to create 95 * function overloadings that only operate on tags with a particular type. 96 */ 97 template <keymaster_tag_type_t tag_type, keymaster_tag_t tag> class TypedTag { 98 public: 99 typedef typename TagValueType<tag_type>::value_type value_type; 100 101 inline TypedTag() { 102 // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type 103 // 'tag_type'. Attempting to instantiate a tag with the wrong type will result in a compile 104 // error (no match for template specialization StaticAssert<false>), with no run-time cost. 105 StaticAssert<(tag & tag_type) == tag_type>::check(); 106 StaticAssert<(tag_type != KM_ENUM) && (tag_type != KM_ENUM_REP)>::check(); 107 } 108 // NOLINTNEXTLINE(google-explicit-constructor) 109 inline operator keymaster_tag_t() { return tag; } 110 // NOLINTNEXTLINE(google-runtime-int) 111 inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); } 112 }; 113 114 template <keymaster_tag_type_t tag_type, keymaster_tag_t tag, typename KeymasterEnum> 115 class TypedEnumTag { 116 public: 117 typedef KeymasterEnum value_type; 118 119 inline TypedEnumTag() { 120 // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type 121 // 'tag_type'. Attempting to instantiate a tag with the wrong type will result in a compile 122 // error (no match for template specialization StaticAssert<false>), with no run-time cost. 123 StaticAssert<(tag & tag_type) == tag_type>::check(); 124 StaticAssert<(tag_type == KM_ENUM) || (tag_type == KM_ENUM_REP)>::check(); 125 } 126 // NOLINTNEXTLINE(google-explicit-constructor) 127 inline operator keymaster_tag_t() { return tag; } 128 // NOLINTNEXTLINE(google-runtime-int) 129 inline long masked_tag() { return static_cast<long>(keymaster_tag_mask_type(tag)); } 130 }; 131 132 #ifdef KEYMASTER_NAME_TAGS 133 const char* StringifyTag(keymaster_tag_t tag); 134 #endif 135 136 // DECLARE_KEYMASTER_TAG is used to declare TypedTag instances for each non-enum keymaster tag. 137 #define DECLARE_KEYMASTER_TAG(type, name) extern TypedTag<type, KM_##name> name 138 139 DECLARE_KEYMASTER_TAG(KM_INVALID, TAG_INVALID); 140 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_KEY_SIZE); 141 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MAC_LENGTH); 142 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_CALLER_NONCE); 143 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MIN_MAC_LENGTH); 144 DECLARE_KEYMASTER_TAG(KM_ULONG, TAG_RSA_PUBLIC_EXPONENT); 145 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ECIES_SINGLE_HASH_MODE); 146 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_INCLUDE_UNIQUE_ID); 147 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_ACTIVE_DATETIME); 148 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_ORIGINATION_EXPIRE_DATETIME); 149 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_USAGE_EXPIRE_DATETIME); 150 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MIN_SECONDS_BETWEEN_OPS); 151 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_MAX_USES_PER_BOOT); 152 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_USAGE_COUNT_LIMIT); 153 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_USERS); 154 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_USER_ID); 155 DECLARE_KEYMASTER_TAG(KM_ULONG_REP, TAG_USER_SECURE_ID); 156 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_NO_AUTH_REQUIRED); 157 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_AUTH_TIMEOUT); 158 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALLOW_WHILE_ON_BODY); 159 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_UNLOCKED_DEVICE_REQUIRED); 160 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_TRUSTED_CONFIRMATION_REQUIRED); 161 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ALL_APPLICATIONS); 162 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_ID); 163 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_APPLICATION_DATA); 164 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_CREATION_DATETIME); 165 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANCE); 166 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_ROLLBACK_RESISTANT); 167 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ROOT_OF_TRUST); 168 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ASSOCIATED_DATA); 169 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_NONCE); 170 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_AUTH_TOKEN); 171 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_BOOTLOADER_ONLY); 172 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_OS_VERSION); 173 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_OS_PATCHLEVEL); 174 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_UNIQUE_ID); 175 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_CHALLENGE); 176 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_APPLICATION_ID); 177 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_RESET_SINCE_ID_ROTATION); 178 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_BRAND); 179 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_DEVICE); 180 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_PRODUCT); 181 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_SERIAL); 182 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_IMEI); 183 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MEID); 184 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MANUFACTURER); 185 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_ATTESTATION_ID_MODEL); 186 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_EARLY_BOOT_ONLY); 187 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_DEVICE_UNIQUE_ATTESTATION); 188 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_IDENTITY_CREDENTIAL_KEY); 189 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_STORAGE_KEY); 190 DECLARE_KEYMASTER_TAG(KM_BOOL, TAG_TRUSTED_USER_PRESENCE_REQUIRED); 191 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_BOOT_PATCHLEVEL); 192 DECLARE_KEYMASTER_TAG(KM_UINT, TAG_VENDOR_PATCHLEVEL); 193 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_CONFIRMATION_TOKEN); 194 DECLARE_KEYMASTER_TAG(KM_BIGNUM, TAG_CERTIFICATE_SERIAL); 195 DECLARE_KEYMASTER_TAG(KM_BYTES, TAG_CERTIFICATE_SUBJECT); 196 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_CERTIFICATE_NOT_BEFORE); 197 DECLARE_KEYMASTER_TAG(KM_DATE, TAG_CERTIFICATE_NOT_AFTER); 198 // DECLARE_KEYMASTER_ENUM_TAG is used to declare TypedEnumTag instances for each enum keymaster tag. 199 #define DECLARE_KEYMASTER_ENUM_TAG(type, name, enumtype) \ 200 extern TypedEnumTag<type, KM_##name, enumtype> name 201 202 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PURPOSE, keymaster_purpose_t); 203 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ALGORITHM, keymaster_algorithm_t); 204 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_BLOCK_MODE, keymaster_block_mode_t); 205 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_DIGEST, keymaster_digest_t); 206 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_DIGEST_OLD, keymaster_digest_t); 207 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_PADDING, keymaster_padding_t); 208 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_PADDING_OLD, keymaster_padding_t); 209 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_BLOB_USAGE_REQUIREMENTS, 210 keymaster_key_blob_usage_requirements_t); 211 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_ORIGIN, keymaster_key_origin_t); 212 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_USER_AUTH_TYPE, hw_authenticator_type_t); 213 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_KDF, keymaster_kdf_t); 214 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM, TAG_EC_CURVE, keymaster_ec_curve_t); 215 DECLARE_KEYMASTER_ENUM_TAG(KM_ENUM_REP, TAG_RSA_OAEP_MGF_DIGEST, keymaster_digest_t); 216 217 // 218 // Overloaded function "Authorization" to create keymaster_key_param_t objects for all of tags. 219 // 220 221 template <keymaster_tag_t Tag> 222 inline keymaster_key_param_t Authorization(TypedTag<KM_BOOL, Tag> tag) { 223 return keymaster_param_bool(tag); 224 } 225 226 template <keymaster_tag_t Tag> 227 inline keymaster_key_param_t Authorization(TypedTag<KM_UINT, Tag> tag, uint32_t value) { 228 return keymaster_param_int(tag, value); 229 } 230 231 template <keymaster_tag_t Tag> 232 inline keymaster_key_param_t Authorization(TypedTag<KM_UINT_REP, Tag> tag, uint32_t value) { 233 return keymaster_param_int(tag, value); 234 } 235 236 template <keymaster_tag_t Tag> 237 inline keymaster_key_param_t Authorization(TypedTag<KM_ULONG, Tag> tag, uint64_t value) { 238 return keymaster_param_long(tag, value); 239 } 240 241 template <keymaster_tag_t Tag> 242 inline keymaster_key_param_t Authorization(TypedTag<KM_ULONG_REP, Tag> tag, uint64_t value) { 243 return keymaster_param_long(tag, value); 244 } 245 246 template <keymaster_tag_t Tag> 247 inline keymaster_key_param_t Authorization(TypedTag<KM_DATE, Tag> tag, uint64_t value) { 248 return keymaster_param_date(tag, value); 249 } 250 251 template <keymaster_tag_t Tag> 252 inline keymaster_key_param_t Authorization(TypedTag<KM_BYTES, Tag> tag, const void* bytes, 253 size_t bytes_len) { 254 return keymaster_param_blob(tag, reinterpret_cast<const uint8_t*>(bytes), bytes_len); 255 } 256 257 template <keymaster_tag_t Tag> 258 inline keymaster_key_param_t Authorization(TypedTag<KM_BYTES, Tag> tag, 259 const keymaster_blob_t& blob) { 260 return keymaster_param_blob(tag, blob.data, blob.data_length); 261 } 262 263 template <keymaster_tag_t Tag> 264 inline keymaster_key_param_t Authorization(TypedTag<KM_BIGNUM, Tag> tag, const void* bytes, 265 size_t bytes_len) { 266 return keymaster_param_blob(tag, reinterpret_cast<const uint8_t*>(bytes), bytes_len); 267 } 268 269 template <keymaster_tag_t Tag> 270 inline keymaster_key_param_t Authorization(TypedTag<KM_BIGNUM, Tag> tag, 271 const keymaster_blob_t& blob) { 272 return keymaster_param_blob(tag, blob.data, blob.data_length); 273 } 274 275 template <keymaster_tag_t Tag, typename KeymasterEnum> 276 inline keymaster_key_param_t Authorization(TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag, 277 KeymasterEnum value) { 278 return keymaster_param_enum(tag, value); 279 } 280 281 template <keymaster_tag_t Tag, typename KeymasterEnum> 282 inline keymaster_key_param_t Authorization(TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag, 283 KeymasterEnum value) { 284 return keymaster_param_enum(tag, value); 285 } 286 287 } // namespace keymaster 288 289 #endif // SYSTEM_KEYMASTER_KEYMASTER_TAGS_H_ 290