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