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 <keystore/keymaster_tags.h> 24 #include <ostream> 25 #include <sstream> 26 #include <string> 27 28 namespace keystore { 29 30 inline static std::ostream& formatArgs(std::ostream& out) { 31 return out; 32 } 33 34 template <typename First, typename... Args> 35 inline static std::ostream& formatArgs(std::ostream& out, First&& first, Args&&... args) { 36 out << first; 37 return formatArgs(out, args...); 38 } 39 40 template <typename... Args> inline static std::string argsToString(Args&&... args) { 41 std::stringstream s; 42 formatArgs(s, args...); 43 return s.str(); 44 } 45 46 template <typename... Msgs> 47 inline static ErrorCode ksHandleHidlError(const Return<ErrorCode>& error, Msgs&&... msgs) { 48 if (!error.isOk()) { 49 ALOGE("HIDL call failed with %s @ %s", error.description().c_str(), 50 argsToString(msgs...).c_str()); 51 return ErrorCode::UNKNOWN_ERROR; 52 } 53 return ErrorCode(error); 54 } 55 template <typename... Msgs> 56 inline static ErrorCode ksHandleHidlError(const Return<void>& error, Msgs&&... msgs) { 57 if (!error.isOk()) { 58 ALOGE("HIDL call failed with %s @ %s", error.description().c_str(), 59 argsToString(msgs...).c_str()); 60 return ErrorCode::UNKNOWN_ERROR; 61 } 62 return ErrorCode::OK; 63 } 64 65 #define KS_HANDLE_HIDL_ERROR(rc) \ 66 ::keystore::ksHandleHidlError(rc, __FILE__, ":", __LINE__, ":", __PRETTY_FUNCTION__) 67 68 inline static hidl_vec<uint8_t> blob2hidlVec(const uint8_t* data, const size_t length, 69 bool inPlace = true) { 70 hidl_vec<uint8_t> result; 71 if (inPlace) 72 result.setToExternal(const_cast<unsigned char*>(data), length); 73 else { 74 result.resize(length); 75 memcpy(&result[0], data, length); 76 } 77 return result; 78 } 79 80 inline static hidl_vec<uint8_t> blob2hidlVec(const std::string& value) { 81 hidl_vec<uint8_t> result; 82 result.setToExternal( 83 reinterpret_cast<uint8_t*>(const_cast<std::string::value_type*>(value.data())), 84 static_cast<size_t>(value.size())); 85 return result; 86 } 87 88 inline static hidl_vec<uint8_t> blob2hidlVec(const std::vector<uint8_t>& blob) { 89 hidl_vec<uint8_t> result; 90 result.setToExternal(const_cast<uint8_t*>(blob.data()), static_cast<size_t>(blob.size())); 91 return result; 92 } 93 94 template <typename T, typename OutIter> 95 inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) { 96 const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value); 97 return std::copy(value_ptr, value_ptr + sizeof(value), dest); 98 } 99 100 inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) { 101 static_assert( 102 std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value, 103 "This function assumes token HMAC is 32 bytes, but it might not be."); 104 static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) + 105 sizeof(token.authenticatorId) + sizeof(token.authenticatorType) + 106 sizeof(token.timestamp) + 32 /* HMAC size */ 107 == sizeof(hw_auth_token_t), 108 "HardwareAuthToken content size does not match hw_auth_token_t size"); 109 110 hidl_vec<uint8_t> result; 111 result.resize(sizeof(hw_auth_token_t)); 112 auto pos = result.begin(); 113 *pos++ = 0; // Version byte 114 pos = copy_bytes_to_iterator(token.challenge, pos); 115 pos = copy_bytes_to_iterator(token.userId, pos); 116 pos = copy_bytes_to_iterator(token.authenticatorId, pos); 117 pos = copy_bytes_to_iterator(token.authenticatorType, pos); 118 pos = copy_bytes_to_iterator(token.timestamp, pos); 119 pos = std::copy(token.hmac.data(), token.hmac.data() + token.hmac.size(), pos); 120 121 return result; 122 } 123 124 inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) { 125 return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size()); 126 } 127 128 } // namespace keystore 129 130 #endif // KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_ 131