Home | History | Annotate | Download | only in keymasterV4_0
      1 /*
      2  * Copyright 2017 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_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
     18 #define SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
     19 
     20 /**
     21  * This header contains various definitions that make working with keymaster tags safer and easier.
     22  *
     23  * It makes use of a fair amount of template metaprogramming. The metaprogramming serves the purpose
     24  * of making it impossible to make certain classes of mistakes when operating on keymaster
     25  * authorizations.  For example, it's an error to create a KeyParameter with tag == Tag::PURPOSE
     26  * and then to assign Algorithm::RSA to algorithm element of its union. But because the user
     27  * must choose the union field, there could be a mismatch which the compiler has now way to
     28  * diagnose.
     29  *
     30  * The machinery in this header solves these problems by describing which union field corresponds
     31  * to which Tag. Central to this mechanism is the template TypedTag. It has zero size and binds a
     32  * numeric Tag to a type that the compiler understands. By means of the macro DECLARE_TYPED_TAG,
     33  * we declare types for each of the tags defined in hardware/interfaces/keymaster/4.0/types.hal.
     34  *
     35  * The macro DECLARE_TYPED_TAG(name) generates a typename TAG_name_t and a zero sized instance
     36  * TAG_name. Once these typed tags have been declared we define metafunctions mapping the each tag
     37  * to its value c++ type and the correct union element of KeyParameter. This is done by means of
     38  * the macros MAKE_TAG_*VALUE_ACCESSOR, which generates TypedTag2ValueType, a metafunction mapping
     39  * a typed tag to the corresponding c++ type, and access function, accessTagValue returning a
     40  * reference to the correct element of KeyParameter.
     41  * E.g.:
     42  *      given "KeyParameter param;" then "accessTagValue(TAG_PURPOSE, param)"
     43  *      yields a reference to param.f.purpose
     44  * If used in an assignment the compiler can now check the compatibility of the assigned value.
     45  *
     46  * For convenience we also provide the constructor like function Authorization().
     47  * Authorization takes a typed tag and a value and checks at compile time whether the value given
     48  * is suitable for the given tag. At runtime it creates a new KeyParameter initialized with the
     49  * given tag and value and returns it by value.
     50  *
     51  * The second convenience function, authorizationValue, allows access to the KeyParameter value in
     52  * a safe way. It takes a typed tag and a KeyParameter and returns a reference to the value wrapped
     53  * by NullOr. NullOr has out-of-band information about whether it is save to access the wrapped
     54  * reference.
     55  * E.g.:
     56  *      auto param = Authorization(TAG_ALGORITM, Algorithm::RSA);
     57  *      auto value1 = authorizationValue(TAG_PURPOSE, param);
     58  *      auto value2 = authorizationValue(TAG_ALGORITM, param);
     59  * value1.isOk() yields false, but value2.isOk() yields true, thus value2.value() is save to access.
     60  */
     61 
     62 #include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
     63 
     64 #include <type_traits>
     65 
     66 namespace android {
     67 namespace hardware {
     68 namespace keymaster {
     69 namespace V4_0 {
     70 
     71 // The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have.  We
     72 // need these old values to be able to support old keys that use them.
     73 static const int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5;
     74 static const int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7;
     75 
     76 constexpr TagType typeFromTag(Tag tag) {
     77     return static_cast<TagType>(static_cast<uint32_t>(tag) & static_cast<uint32_t>(0xf0000000));
     78 }
     79 
     80 /**
     81  * TypedTag is a templatized version of Tag, which provides compile-time checking of
     82  * keymaster tag types. Instances are convertible to Tag, so they can be used wherever
     83  * Tag is expected, and because they encode the tag type it's possible to create
     84  * function overloads that only operate on tags with a particular type.
     85  */
     86 template <TagType tag_type, Tag tag>
     87 struct TypedTag {
     88     inline TypedTag() {
     89         // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type
     90         // 'tag_type'.  Attempting to instantiate a tag with the wrong type will result in a compile
     91         // error (no match for template specialization StaticAssert<false>), with no run-time cost.
     92         static_assert(typeFromTag(tag) == tag_type, "mismatch between tag and tag_type");
     93     }
     94     operator Tag() const { return tag; }
     95     int32_t maskedTag() { return tag & 0x0FFFFFFF; }
     96 };
     97 
     98 template <Tag tag>
     99 struct Tag2TypedTag {
    100     typedef TypedTag<typeFromTag(tag), tag> type;
    101 };
    102 
    103 #define DECLARE_TYPED_TAG(name)                                    \
    104     typedef typename Tag2TypedTag<Tag::name>::type TAG_##name##_t; \
    105     static TAG_##name##_t TAG_##name;
    106 
    107 DECLARE_TYPED_TAG(ACTIVE_DATETIME);
    108 DECLARE_TYPED_TAG(ALGORITHM);
    109 DECLARE_TYPED_TAG(ALLOW_WHILE_ON_BODY);
    110 DECLARE_TYPED_TAG(APPLICATION_DATA);
    111 DECLARE_TYPED_TAG(APPLICATION_ID);
    112 DECLARE_TYPED_TAG(ASSOCIATED_DATA);
    113 DECLARE_TYPED_TAG(ATTESTATION_APPLICATION_ID);
    114 DECLARE_TYPED_TAG(ATTESTATION_CHALLENGE);
    115 DECLARE_TYPED_TAG(AUTH_TIMEOUT);
    116 DECLARE_TYPED_TAG(BLOB_USAGE_REQUIREMENTS);
    117 DECLARE_TYPED_TAG(BLOCK_MODE);
    118 DECLARE_TYPED_TAG(BOOTLOADER_ONLY);
    119 DECLARE_TYPED_TAG(CALLER_NONCE);
    120 DECLARE_TYPED_TAG(CONFIRMATION_TOKEN);
    121 DECLARE_TYPED_TAG(CREATION_DATETIME);
    122 DECLARE_TYPED_TAG(DIGEST);
    123 DECLARE_TYPED_TAG(EC_CURVE);
    124 DECLARE_TYPED_TAG(INCLUDE_UNIQUE_ID);
    125 DECLARE_TYPED_TAG(INVALID);
    126 DECLARE_TYPED_TAG(KEY_SIZE);
    127 DECLARE_TYPED_TAG(MAC_LENGTH);
    128 DECLARE_TYPED_TAG(MAX_USES_PER_BOOT);
    129 DECLARE_TYPED_TAG(MIN_MAC_LENGTH);
    130 DECLARE_TYPED_TAG(MIN_SECONDS_BETWEEN_OPS);
    131 DECLARE_TYPED_TAG(NONCE);
    132 DECLARE_TYPED_TAG(NO_AUTH_REQUIRED);
    133 DECLARE_TYPED_TAG(ORIGIN);
    134 DECLARE_TYPED_TAG(ORIGINATION_EXPIRE_DATETIME);
    135 DECLARE_TYPED_TAG(OS_PATCHLEVEL);
    136 DECLARE_TYPED_TAG(OS_VERSION);
    137 DECLARE_TYPED_TAG(PADDING);
    138 DECLARE_TYPED_TAG(PURPOSE);
    139 DECLARE_TYPED_TAG(RESET_SINCE_ID_ROTATION);
    140 DECLARE_TYPED_TAG(ROLLBACK_RESISTANCE);
    141 DECLARE_TYPED_TAG(ROOT_OF_TRUST);
    142 DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT);
    143 DECLARE_TYPED_TAG(TRUSTED_CONFIRMATION_REQUIRED);
    144 DECLARE_TYPED_TAG(UNIQUE_ID);
    145 DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED);
    146 DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
    147 DECLARE_TYPED_TAG(USER_AUTH_TYPE);
    148 DECLARE_TYPED_TAG(USER_ID);
    149 DECLARE_TYPED_TAG(USER_SECURE_ID);
    150 
    151 template <typename... Elems>
    152 struct MetaList {};
    153 
    154 using all_tags_t =
    155     MetaList<TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t,
    156              TAG_MIN_MAC_LENGTH_t, TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t,
    157              TAG_ACTIVE_DATETIME_t, TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
    158              TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t,
    159              TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
    160              TAG_ALLOW_WHILE_ON_BODY_t, TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t,
    161              TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t,
    162              TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t,
    163              TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t,
    164              TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t,
    165              TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t,
    166              TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t>;
    167 
    168 template <typename TypedTagType>
    169 struct TypedTag2ValueType;
    170 
    171 #define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name)                              \
    172     template <Tag tag>                                                             \
    173     struct TypedTag2ValueType<TypedTag<tag_type, tag>> {                           \
    174         typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type;    \
    175     };                                                                             \
    176     template <Tag tag>                                                             \
    177     inline auto accessTagValue(TypedTag<tag_type, tag>, const KeyParameter& param) \
    178         ->const decltype(param.field_name)& {                                      \
    179         return param.field_name;                                                   \
    180     }                                                                              \
    181     template <Tag tag>                                                             \
    182     inline auto accessTagValue(TypedTag<tag_type, tag>, KeyParameter& param)       \
    183         ->decltype(param.field_name)& {                                            \
    184         return param.field_name;                                                   \
    185     }
    186 
    187 MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, f.longInteger)
    188 MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, f.longInteger)
    189 MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, f.dateTime)
    190 MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, f.integer)
    191 MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, f.integer)
    192 MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, f.boolValue)
    193 MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob)
    194 MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob)
    195 
    196 #define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name)                     \
    197     template <>                                                                 \
    198     struct TypedTag2ValueType<decltype(typed_tag)> {                            \
    199         typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type; \
    200     };                                                                          \
    201     inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param)  \
    202         ->const decltype(param.field_name)& {                                   \
    203         return param.field_name;                                                \
    204     }                                                                           \
    205     inline auto accessTagValue(decltype(typed_tag), KeyParameter& param)        \
    206         ->decltype(param.field_name)& {                                         \
    207         return param.field_name;                                                \
    208     }
    209 
    210 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, f.algorithm)
    211 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOB_USAGE_REQUIREMENTS, f.keyBlobUsageRequirements)
    212 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, f.blockMode)
    213 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, f.digest)
    214 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, f.ecCurve)
    215 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, f.origin)
    216 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, f.paddingMode)
    217 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, f.purpose)
    218 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, f.hardwareAuthenticatorType)
    219 
    220 template <TagType tag_type, Tag tag, typename ValueT>
    221 inline KeyParameter makeKeyParameter(TypedTag<tag_type, tag> ttag, ValueT&& value) {
    222     KeyParameter param;
    223     param.tag = tag;
    224     param.f.longInteger = 0;
    225     accessTagValue(ttag, param) = std::forward<ValueT>(value);
    226     return param;
    227 }
    228 
    229 // the boolean case
    230 template <Tag tag>
    231 inline KeyParameter makeKeyParameter(TypedTag<TagType::BOOL, tag>) {
    232     KeyParameter param;
    233     param.tag = tag;
    234     param.f.boolValue = true;
    235     return param;
    236 }
    237 
    238 template <typename... Pack>
    239 struct FirstOrNoneHelper;
    240 template <typename First>
    241 struct FirstOrNoneHelper<First> {
    242     typedef First type;
    243 };
    244 template <>
    245 struct FirstOrNoneHelper<> {
    246     struct type {};
    247 };
    248 
    249 template <typename... Pack>
    250 using FirstOrNone = typename FirstOrNoneHelper<Pack...>::type;
    251 
    252 template <TagType tag_type, Tag tag, typename... Args>
    253 inline KeyParameter Authorization(TypedTag<tag_type, tag> ttag, Args&&... args) {
    254     static_assert(tag_type != TagType::BOOL || (sizeof...(args) == 0),
    255                   "TagType::BOOL Authorizations do not take parameters. Presence is truth.");
    256     static_assert(tag_type == TagType::BOOL || (sizeof...(args) == 1),
    257                   "Authorization other then TagType::BOOL take exactly one parameter.");
    258     static_assert(
    259         tag_type == TagType::BOOL ||
    260             std::is_convertible<std::remove_cv_t<std::remove_reference_t<FirstOrNone<Args...>>>,
    261                                 typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>::value,
    262         "Invalid argument type for given tag.");
    263 
    264     return makeKeyParameter(ttag, std::forward<Args>(args)...);
    265 }
    266 
    267 /**
    268  * This class wraps a (mostly return) value and stores whether or not the wrapped value is valid out
    269  * of band. Note that if the wrapped value is a reference it is unsafe to access the value if
    270  * !isOk(). If the wrapped type is a pointer or value and !isOk(), it is still safe to access the
    271  * wrapped value. In this case the pointer will be NULL though, and the value will be default
    272  * constructed.
    273  */
    274 template <typename ValueT>
    275 class NullOr {
    276     template <typename T>
    277     struct reference_initializer {
    278         static T&& init() { return *static_cast<std::remove_reference_t<T>*>(nullptr); }
    279     };
    280     template <typename T>
    281     struct pointer_initializer {
    282         static T init() { return nullptr; }
    283     };
    284     template <typename T>
    285     struct value_initializer {
    286         static T init() { return T(); }
    287     };
    288     template <typename T>
    289     using initializer_t =
    290         std::conditional_t<std::is_lvalue_reference<T>::value, reference_initializer<T>,
    291                            std::conditional_t<std::is_pointer<T>::value, pointer_initializer<T>,
    292                                               value_initializer<T>>>;
    293 
    294    public:
    295     NullOr() : value_(initializer_t<ValueT>::init()), null_(true) {}
    296     NullOr(ValueT&& value) : value_(std::forward<ValueT>(value)), null_(false) {}
    297 
    298     bool isOk() const { return !null_; }
    299 
    300     const ValueT& value() const & { return value_; }
    301     ValueT& value() & { return value_; }
    302     ValueT&& value() && { return std::move(value_); }
    303 
    304    private:
    305     ValueT value_;
    306     bool null_;
    307 };
    308 
    309 template <typename T>
    310 std::remove_reference_t<T> NullOrOr(T&& v) {
    311     if (v.isOk()) return v;
    312     return {};
    313 }
    314 
    315 template <typename Head, typename... Tail>
    316 std::remove_reference_t<Head> NullOrOr(Head&& head, Tail&&... tail) {
    317     if (head.isOk()) return head;
    318     return NullOrOr(std::forward<Tail>(tail)...);
    319 }
    320 
    321 template <typename Default, typename Wrapped>
    322 std::remove_reference_t<Wrapped> defaultOr(NullOr<Wrapped>&& optional, Default&& def) {
    323     static_assert(std::is_convertible<std::remove_reference_t<Default>,
    324                                       std::remove_reference_t<Wrapped>>::value,
    325                   "Type of default value must match the type wrapped by NullOr");
    326     if (optional.isOk()) return optional.value();
    327     return def;
    328 }
    329 
    330 template <TagType tag_type, Tag tag>
    331 inline NullOr<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type&> authorizationValue(
    332     TypedTag<tag_type, tag> ttag, const KeyParameter& param) {
    333     if (tag != param.tag) return {};
    334     return accessTagValue(ttag, param);
    335 }
    336 
    337 inline bool operator==(const KeyParameter& a, const KeyParameter& b) {
    338     if (a.tag != b.tag) {
    339         return false;
    340     }
    341 
    342     switch (a.tag) {
    343         /* Boolean tags */
    344         case Tag::INVALID:
    345         case Tag::CALLER_NONCE:
    346         case Tag::INCLUDE_UNIQUE_ID:
    347         case Tag::BOOTLOADER_ONLY:
    348         case Tag::NO_AUTH_REQUIRED:
    349         case Tag::ALLOW_WHILE_ON_BODY:
    350         case Tag::UNLOCKED_DEVICE_REQUIRED:
    351         case Tag::ROLLBACK_RESISTANCE:
    352         case Tag::RESET_SINCE_ID_ROTATION:
    353         case Tag::TRUSTED_CONFIRMATION_REQUIRED:
    354         case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
    355             return true;
    356 
    357         /* Integer tags */
    358         case Tag::KEY_SIZE:
    359         case Tag::MIN_MAC_LENGTH:
    360         case Tag::MIN_SECONDS_BETWEEN_OPS:
    361         case Tag::MAX_USES_PER_BOOT:
    362         case Tag::OS_VERSION:
    363         case Tag::OS_PATCHLEVEL:
    364         case Tag::MAC_LENGTH:
    365         case Tag::USER_ID:
    366         case Tag::AUTH_TIMEOUT:
    367         case Tag::VENDOR_PATCHLEVEL:
    368         case Tag::BOOT_PATCHLEVEL:
    369             return a.f.integer == b.f.integer;
    370 
    371         /* Long integer tags */
    372         case Tag::RSA_PUBLIC_EXPONENT:
    373         case Tag::USER_SECURE_ID:
    374             return a.f.longInteger == b.f.longInteger;
    375 
    376         /* Date-time tags */
    377         case Tag::ACTIVE_DATETIME:
    378         case Tag::ORIGINATION_EXPIRE_DATETIME:
    379         case Tag::USAGE_EXPIRE_DATETIME:
    380         case Tag::CREATION_DATETIME:
    381             return a.f.dateTime == b.f.dateTime;
    382 
    383         /* Bytes tags */
    384         case Tag::APPLICATION_ID:
    385         case Tag::APPLICATION_DATA:
    386         case Tag::ROOT_OF_TRUST:
    387         case Tag::UNIQUE_ID:
    388         case Tag::ATTESTATION_CHALLENGE:
    389         case Tag::ATTESTATION_APPLICATION_ID:
    390         case Tag::ATTESTATION_ID_BRAND:
    391         case Tag::ATTESTATION_ID_DEVICE:
    392         case Tag::ATTESTATION_ID_PRODUCT:
    393         case Tag::ATTESTATION_ID_SERIAL:
    394         case Tag::ATTESTATION_ID_IMEI:
    395         case Tag::ATTESTATION_ID_MEID:
    396         case Tag::ATTESTATION_ID_MANUFACTURER:
    397         case Tag::ATTESTATION_ID_MODEL:
    398         case Tag::ASSOCIATED_DATA:
    399         case Tag::CONFIRMATION_TOKEN:
    400         case Tag::NONCE:
    401             return a.blob == b.blob;
    402 
    403         /* Enum tags */
    404         case Tag::PURPOSE:
    405             return a.f.purpose == b.f.purpose;
    406         case Tag::ALGORITHM:
    407             return a.f.algorithm == b.f.algorithm;
    408         case Tag::BLOCK_MODE:
    409             return a.f.blockMode == b.f.blockMode;
    410         case Tag::DIGEST:
    411             return a.f.digest == b.f.digest;
    412         case Tag::PADDING:
    413             return a.f.paddingMode == b.f.paddingMode;
    414         case Tag::EC_CURVE:
    415             return a.f.ecCurve == b.f.ecCurve;
    416         case Tag::BLOB_USAGE_REQUIREMENTS:
    417             return a.f.keyBlobUsageRequirements == b.f.keyBlobUsageRequirements;
    418         case Tag::USER_AUTH_TYPE:
    419             return a.f.integer == b.f.integer;
    420         case Tag::ORIGIN:
    421             return a.f.origin == b.f.origin;
    422         case Tag::HARDWARE_TYPE:
    423             return a.f.hardwareType == b.f.hardwareType;
    424     }
    425 
    426     return false;
    427 }
    428 
    429 }  // namespace V4_0
    430 }  // namespace keymaster
    431 }  // namespace hardware
    432 }  // namespace android
    433 
    434 #endif  // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
    435