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