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