Home | History | Annotate | Download | only in support
      1 /*
      2  * Copyright (C) 2018 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 #include <hardware/hw_auth_token.h>
     18 #include <keymasterV4_0/keymaster_utils.h>
     19 
     20 namespace android {
     21 namespace hardware {
     22 
     23 inline static bool operator<(const hidl_vec<uint8_t>& a, const hidl_vec<uint8_t>& b) {
     24     auto result = memcmp(a.data(), b.data(), std::min(a.size(), b.size()));
     25     if (!result) return a.size() < b.size();
     26     return result < 0;
     27 }
     28 
     29 template <size_t SIZE>
     30 inline static bool operator<(const hidl_array<uint8_t, SIZE>& a,
     31                              const hidl_array<uint8_t, SIZE>& b) {
     32     return memcmp(a.data(), b.data(), SIZE) == -1;
     33 }
     34 
     35 namespace keymaster {
     36 namespace V4_0 {
     37 
     38 bool operator<(const HmacSharingParameters& a, const HmacSharingParameters& b) {
     39     return std::tie(a.seed, a.nonce) < std::tie(b.seed, b.nonce);
     40 }
     41 
     42 namespace support {
     43 
     44 template <typename T, typename InIter>
     45 inline static InIter copy_bytes_from_iterator(T* value, InIter src) {
     46     uint8_t* value_ptr = reinterpret_cast<uint8_t*>(value);
     47     std::copy(src, src + sizeof(T), value_ptr);
     48     return src + sizeof(T);
     49 }
     50 
     51 template <typename T, typename OutIter>
     52 inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
     53     const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
     54     return std::copy(value_ptr, value_ptr + sizeof(value), dest);
     55 }
     56 
     57 constexpr size_t kHmacSize = 32;
     58 
     59 hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
     60     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
     61                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
     62                           sizeof(token.timestamp) + kHmacSize ==
     63                       sizeof(hw_auth_token_t),
     64                   "HardwareAuthToken content size does not match hw_auth_token_t size");
     65 
     66     hidl_vec<uint8_t> result;
     67     result.resize(sizeof(hw_auth_token_t));
     68     auto pos = result.begin();
     69     *pos++ = 0;  // Version byte
     70     pos = copy_bytes_to_iterator(token.challenge, pos);
     71     pos = copy_bytes_to_iterator(token.userId, pos);
     72     pos = copy_bytes_to_iterator(token.authenticatorId, pos);
     73     auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
     74     pos = copy_bytes_to_iterator(auth_type, pos);
     75     auto timestamp = htonq(token.timestamp);
     76     pos = copy_bytes_to_iterator(timestamp, pos);
     77     if (token.mac.size() != kHmacSize) {
     78         std::fill(pos, pos + kHmacSize, 0);
     79     } else {
     80         std::copy(token.mac.begin(), token.mac.end(), pos);
     81     }
     82 
     83     return result;
     84 }
     85 
     86 HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) {
     87     HardwareAuthToken token;
     88     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
     89                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
     90                           sizeof(token.timestamp) + kHmacSize ==
     91                       sizeof(hw_auth_token_t),
     92                   "HardwareAuthToken content size does not match hw_auth_token_t size");
     93 
     94     if (buffer.size() != sizeof(hw_auth_token_t)) return {};
     95 
     96     auto pos = buffer.begin();
     97     ++pos;  // skip first byte
     98     pos = copy_bytes_from_iterator(&token.challenge, pos);
     99     pos = copy_bytes_from_iterator(&token.userId, pos);
    100     pos = copy_bytes_from_iterator(&token.authenticatorId, pos);
    101     pos = copy_bytes_from_iterator(&token.authenticatorType, pos);
    102     token.authenticatorType = static_cast<HardwareAuthenticatorType>(
    103         ntohl(static_cast<uint32_t>(token.authenticatorType)));
    104     pos = copy_bytes_from_iterator(&token.timestamp, pos);
    105     token.timestamp = ntohq(token.timestamp);
    106     token.mac.resize(kHmacSize);
    107     std::copy(pos, pos + kHmacSize, token.mac.data());
    108 
    109     return token;
    110 }
    111 
    112 }  // namespace support
    113 }  // namespace V4_0
    114 }  // namespace keymaster
    115 }  // namespace hardware
    116 }  // namespace android
    117