1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #ifndef GATEKEEPER_MESSAGES_H_ 17 #define GATEKEEPER_MESSAGES_H_ 18 19 #include <stdint.h> 20 #include <gatekeeper/UniquePtr.h> 21 22 #include <new> 23 24 #include "gatekeeper_utils.h" 25 /** 26 * Message serialization objects for communicating with the hardware gatekeeper. 27 */ 28 namespace gatekeeper { 29 30 const uint32_t ENROLL = 0; 31 const uint32_t VERIFY = 1; 32 const uint32_t DELETE_USER = 2; 33 const uint32_t DELETE_ALL_USERS = 3; 34 35 typedef enum { 36 ERROR_NONE = 0, 37 ERROR_INVALID = 1, 38 ERROR_RETRY = 2, 39 ERROR_UNKNOWN = 3, 40 ERROR_MEMORY_ALLOCATION_FAILED = 4, 41 ERROR_NOT_IMPLEMENTED = 5, 42 } gatekeeper_error_t; 43 44 struct SizedBuffer { SizedBufferSizedBuffer45 SizedBuffer() { 46 length = 0; 47 } ~SizedBufferSizedBuffer48 ~SizedBuffer() { 49 if (buffer && length > 0) { 50 memset_s(buffer.get(), 0, length); 51 } 52 } 53 /* 54 * Constructs a SizedBuffer out of a pointer and a length 55 * Takes ownership of the buf pointer, and deallocates it 56 * when destructed. 57 */ SizedBufferSizedBuffer58 SizedBuffer(uint8_t buf[], uint32_t len) { 59 if (buf == nullptr) { 60 length = 0; 61 } else { 62 buffer.reset(buf); 63 length = len; 64 } 65 } 66 SizedBufferSizedBuffer67 SizedBuffer(SizedBuffer && rhs) : buffer(move(rhs.buffer)), length(rhs.length) { 68 rhs.length = 0; 69 } 70 71 SizedBuffer & operator=(SizedBuffer && rhs) { 72 if (&rhs != this) { 73 buffer = move(rhs.buffer); 74 length = rhs.length; 75 rhs.length = 0; 76 } 77 return *this; 78 } 79 80 operator bool() const { 81 return buffer; 82 } 83 sizeSizedBuffer84 uint32_t size() const { return buffer ? length : 0; } 85 86 /** 87 * Returns an pointer to the const buffer IFF the buffer is initialized and the length 88 * field holds a values greater or equal to the size of the requested template argument type. 89 */ 90 template <typename T> DataSizedBuffer91 const T* Data() const { 92 if (buffer.get() != nullptr && sizeof(T) <= length) { 93 return reinterpret_cast<const T*>(buffer.get()); 94 } 95 return nullptr; 96 } 97 98 private: 99 UniquePtr<uint8_t[]> buffer; 100 uint32_t length; 101 }; 102 103 /* 104 * Abstract base class of all message objects. Handles serialization of common 105 * elements like the error and user ID. Delegates specialized serialization 106 * to protected pure virtual functions implemented by subclasses. 107 */ 108 struct GateKeeperMessage { GateKeeperMessageGateKeeperMessage109 GateKeeperMessage() : error(ERROR_NONE) {} GateKeeperMessageGateKeeperMessage110 explicit GateKeeperMessage(gatekeeper_error_t error) : error(error) {} ~GateKeeperMessageGateKeeperMessage111 virtual ~GateKeeperMessage() {} 112 113 /** 114 * Returns serialized size in bytes of the current state of the 115 * object. 116 */ 117 uint32_t GetSerializedSize() const; 118 /** 119 * Converts the object into its serialized representation. 120 * 121 * Expects payload to be allocated with GetSerializedSize bytes. 122 * 123 * Returns the number of bytes written or 0 on error. 124 */ 125 uint32_t Serialize(uint8_t *payload, const uint8_t *end) const; 126 127 /** 128 * Inflates the object from its serial representation. 129 */ 130 gatekeeper_error_t Deserialize(const uint8_t *payload, const uint8_t *end); 131 132 /** 133 * Calls may fail due to throttling. If so, this sets a timeout in milliseconds 134 * for when the caller should attempt the call again. Additionally, sets the 135 * error to ERROR_RETRY. 136 */ 137 void SetRetryTimeout(uint32_t retry_timeout); 138 139 /** 140 * The following methods are intended to be implemented by subclasses. 141 * They are hooks to serialize the elements specific to each particular 142 * specialization. 143 */ 144 145 /** 146 * Returns the size of serializing only the elements specific to the 147 * current sublclass. 148 */ nonErrorSerializedSizeGateKeeperMessage149 virtual uint32_t nonErrorSerializedSize() const { return 0; } ; 150 /** 151 * Takes a pointer to a buffer prepared by Serialize and writes 152 * the subclass specific data into it. The size of the buffer must be exactly 153 * that returned by nonErrorSerializedSize() in bytes. 154 */ nonErrorSerializeGateKeeperMessage155 virtual void nonErrorSerialize(uint8_t *) const { } 156 157 /** 158 * Deserializes subclass specific data from payload without reading past end. 159 */ nonErrorDeserializeGateKeeperMessage160 virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *, const uint8_t *) { 161 return ERROR_NONE; 162 } 163 164 gatekeeper_error_t error; 165 uint32_t user_id; 166 uint32_t retry_timeout; 167 }; 168 169 struct VerifyRequest : public GateKeeperMessage { 170 VerifyRequest( 171 uint32_t user_id, 172 uint64_t challenge, 173 SizedBuffer enrolled_password_handle, 174 SizedBuffer provided_password_payload); VerifyRequestVerifyRequest175 VerifyRequest() : challenge(0) {} 176 177 uint32_t nonErrorSerializedSize() const override; 178 void nonErrorSerialize(uint8_t *buffer) const override; 179 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 180 181 uint64_t challenge; 182 SizedBuffer password_handle; 183 SizedBuffer provided_password; 184 }; 185 186 struct VerifyResponse : public GateKeeperMessage { 187 VerifyResponse(uint32_t user_id, SizedBuffer auth_token); 188 VerifyResponse(); 189 190 void SetVerificationToken(SizedBuffer auth_token); 191 192 uint32_t nonErrorSerializedSize() const override; 193 void nonErrorSerialize(uint8_t *buffer) const override; 194 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 195 196 SizedBuffer auth_token; 197 bool request_reenroll; 198 }; 199 200 struct EnrollRequest : public GateKeeperMessage { 201 EnrollRequest(uint32_t user_id, SizedBuffer password_handle, 202 SizedBuffer provided_password, SizedBuffer enrolled_password); 203 EnrollRequest() = default; 204 205 uint32_t nonErrorSerializedSize() const override; 206 void nonErrorSerialize(uint8_t *buffer) const override; 207 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 208 209 /** 210 * The password handle returned from the previous call to enroll or NULL 211 * if none 212 */ 213 SizedBuffer password_handle; 214 /** 215 * The currently enrolled password as entered by the user 216 */ 217 SizedBuffer enrolled_password; 218 /** 219 * The password desired by the user 220 */ 221 SizedBuffer provided_password; 222 }; 223 224 struct EnrollResponse : public GateKeeperMessage { 225 public: 226 EnrollResponse(uint32_t user_id, SizedBuffer enrolled_password_handle); 227 EnrollResponse() = default; 228 229 void SetEnrolledPasswordHandle(SizedBuffer enrolled_password_handle); 230 231 uint32_t nonErrorSerializedSize() const override; 232 void nonErrorSerialize(uint8_t *buffer) const override; 233 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 234 235 SizedBuffer enrolled_password_handle; 236 }; 237 238 struct DeleteUserRequest : public GateKeeperMessage { 239 DeleteUserRequest(uint32_t user_id); 240 DeleteUserRequest() = default; 241 nonErrorSerializedSizeDeleteUserRequest242 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteUserRequest243 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteUserRequest244 gatekeeper_error_t nonErrorDeserialize( 245 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 246 }; 247 248 struct DeleteUserResponse : public GateKeeperMessage { DeleteUserResponseDeleteUserResponse249 DeleteUserResponse() {} 250 nonErrorSerializedSizeDeleteUserResponse251 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteUserResponse252 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteUserResponse253 gatekeeper_error_t nonErrorDeserialize( 254 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 255 }; 256 257 258 struct DeleteAllUsersRequest : public GateKeeperMessage { DeleteAllUsersRequestDeleteAllUsersRequest259 DeleteAllUsersRequest() {}; 260 nonErrorSerializedSizeDeleteAllUsersRequest261 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteAllUsersRequest262 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteAllUsersRequest263 gatekeeper_error_t nonErrorDeserialize( 264 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 265 }; 266 267 struct DeleteAllUsersResponse : public GateKeeperMessage { DeleteAllUsersResponseDeleteAllUsersResponse268 DeleteAllUsersResponse() {} 269 nonErrorSerializedSizeDeleteAllUsersResponse270 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteAllUsersResponse271 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteAllUsersResponse272 gatekeeper_error_t nonErrorDeserialize( 273 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 274 }; 275 276 } 277 278 #endif // GATEKEEPER_MESSAGES_H_ 279