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
formatArgs(std::ostream & out)30 inline static std::ostream& formatArgs(std::ostream& out) {
31 return out;
32 }
33
34 template <typename First, typename... Args>
formatArgs(std::ostream & out,First && first,Args &&...args)35 inline static std::ostream& formatArgs(std::ostream& out, First&& first, Args&&... args) {
36 out << first;
37 return formatArgs(out, args...);
38 }
39
argsToString(Args &&...args)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>
ksHandleHidlError(const Return<ErrorCode> & error,Msgs &&...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>
ksHandleHidlError(const Return<void> & error,Msgs &&...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
blob2hidlVec(const std::string & value)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
blob2hidlVec(const std::vector<uint8_t> & blob)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>
copy_bytes_to_iterator(const T & value,OutIter dest)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
authToken2HidlVec(const HardwareAuthToken & token)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
hidlVec2String(const hidl_vec<uint8_t> & value)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