Home | History | Annotate | Download | only in include
      1 /*
      2  **
      3  ** Copyright 2016, The Android Open Source Project
      4  **
      5  ** Licensed under the Apache License, Version 2.0 (the "License");
      6  ** you may not use this file except in compliance with the License.
      7  ** You may obtain a copy of the License at
      8  **
      9  **     http://www.apache.org/licenses/LICENSE-2.0
     10  **
     11  ** Unless required by applicable law or agreed to in writing, software
     12  ** distributed under the License is distributed on an "AS IS" BASIS,
     13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  ** See the License for the specific language governing permissions and
     15  ** limitations under the License.
     16  */
     17 
     18 #ifndef KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
     19 #define KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
     20 
     21 #include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
     22 #include <hidl/Status.h>
     23 #include "keymaster_tags.h"
     24 #include <ostream>
     25 #include <sstream>
     26 #include <string>
     27 
     28 #include <android-base/logging.h>
     29 
     30 namespace keymaster {
     31 namespace ng {
     32 
     33 inline static std::ostream& formatArgs(std::ostream& out) {
     34     return out;
     35 }
     36 
     37 template <typename First, typename... Args>
     38 inline static std::ostream& formatArgs(std::ostream& out, First&& first, Args&&... args) {
     39     out << first;
     40     return formatArgs(out, args...);
     41 }
     42 
     43 template <typename... Args> inline static std::string argsToString(Args&&... args) {
     44     std::stringstream s;
     45     formatArgs(s, args...);
     46     return s.str();
     47 }
     48 
     49 template <typename... Msgs>
     50 inline static ErrorCode ksHandleHidlError(const Return<ErrorCode>& error, Msgs&&... msgs) {
     51     if (!error.isOk()) {
     52         LOG(ERROR) << "HIDL call failed with " << error.description() << " @ "
     53               << argsToString(msgs...);
     54         return ErrorCode::UNKNOWN_ERROR;
     55     }
     56     return ErrorCode(error);
     57 }
     58 template <typename... Msgs>
     59 inline static ErrorCode ksHandleHidlError(const Return<void>& error, Msgs&&... msgs) {
     60     if (!error.isOk()) {
     61         LOG(ERROR) << "HIDL call failed with " << error.description() << " @ "
     62               << argsToString(msgs...);
     63         return ErrorCode::UNKNOWN_ERROR;
     64     }
     65     return ErrorCode::OK;
     66 }
     67 
     68 #define KS_HANDLE_HIDL_ERROR(rc)                                                                   \
     69     ::keystore::ksHandleHidlError(rc, __FILE__, ":", __LINE__, ":", __PRETTY_FUNCTION__)
     70 
     71 inline static hidl_vec<uint8_t> blob2hidlVec(const uint8_t* data, const size_t length,
     72                                              bool inPlace = true) {
     73     hidl_vec<uint8_t> result;
     74     if (inPlace)
     75         result.setToExternal(const_cast<unsigned char*>(data), length);
     76     else {
     77         result.resize(length);
     78         memcpy(&result[0], data, length);
     79     }
     80     return result;
     81 }
     82 
     83 inline static hidl_vec<uint8_t> blob2hidlVec(const std::string& value) {
     84     hidl_vec<uint8_t> result;
     85     result.setToExternal(
     86         reinterpret_cast<uint8_t*>(const_cast<std::string::value_type*>(value.data())),
     87         static_cast<size_t>(value.size()));
     88     return result;
     89 }
     90 
     91 inline static hidl_vec<uint8_t> blob2hidlVec(const std::vector<uint8_t>& blob) {
     92     hidl_vec<uint8_t> result;
     93     result.setToExternal(const_cast<uint8_t*>(blob.data()), static_cast<size_t>(blob.size()));
     94     return result;
     95 }
     96 
     97 template <typename T, typename OutIter>
     98 inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
     99     const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
    100     return std::copy(value_ptr, value_ptr + sizeof(value), dest);
    101 }
    102 
    103 inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
    104     static_assert(
    105         std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value,
    106         "This function assumes token HMAC is 32 bytes, but it might not be.");
    107     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
    108                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
    109                           sizeof(token.timestamp) + 32 /* HMAC size */
    110                       == sizeof(hw_auth_token_t),
    111                   "HardwareAuthToken content size does not match hw_auth_token_t size");
    112 
    113     hidl_vec<uint8_t> result;
    114     result.resize(sizeof(hw_auth_token_t));
    115     auto pos = result.begin();
    116     *pos++ = 0;  // Version byte
    117     pos = copy_bytes_to_iterator(token.challenge, pos);
    118     pos = copy_bytes_to_iterator(token.userId, pos);
    119     pos = copy_bytes_to_iterator(token.authenticatorId, pos);
    120     pos = copy_bytes_to_iterator(token.authenticatorType, pos);
    121     pos = copy_bytes_to_iterator(token.timestamp, pos);
    122     pos = std::copy(token.hmac.data(), token.hmac.data() + token.hmac.size(), pos);
    123 
    124     return result;
    125 }
    126 
    127 inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) {
    128     return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
    129 }
    130 
    131 }
    132 }  // namespace keystore
    133 
    134 #endif  // KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
    135