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 33 typedef enum { 34 ERROR_NONE = 0, 35 ERROR_INVALID = 1, 36 ERROR_RETRY = 2, 37 ERROR_UNKNOWN = 3, 38 ERROR_MEMORY_ALLOCATION_FAILED = 4, 39 ERROR_NOT_IMPLEMENTED = 5, 40 } gatekeeper_error_t; 41 42 struct SizedBuffer { SizedBufferSizedBuffer43 SizedBuffer() { 44 length = 0; 45 } ~SizedBufferSizedBuffer46 ~SizedBuffer() { 47 if (buffer && length > 0) { 48 memset_s(buffer.get(), 0, length); 49 } 50 } 51 /* 52 * Constructs a SizedBuffer out of a pointer and a length 53 * Takes ownership of the buf pointer, and deallocates it 54 * when destructed. 55 */ SizedBufferSizedBuffer56 SizedBuffer(uint8_t buf[], uint32_t len) { 57 if (buf == nullptr) { 58 length = 0; 59 } else { 60 buffer.reset(buf); 61 length = len; 62 } 63 } 64 SizedBufferSizedBuffer65 SizedBuffer(SizedBuffer && rhs) : buffer(move(rhs.buffer)), length(rhs.length) { 66 rhs.length = 0; 67 } 68 69 SizedBuffer & operator=(SizedBuffer && rhs) { 70 if (&rhs != this) { 71 buffer = move(rhs.buffer); 72 length = rhs.length; 73 rhs.length = 0; 74 } 75 return *this; 76 } 77 78 operator bool() const { 79 return buffer; 80 } 81 sizeSizedBuffer82 uint32_t size() const { return buffer ? length : 0; } 83 84 /** 85 * Returns an pointer to the const buffer IFF the buffer is initialized and the length 86 * field holds a values greater or equal to the size of the requested template argument type. 87 */ 88 template <typename T> DataSizedBuffer89 const T* Data() const { 90 if (buffer.get() != nullptr && sizeof(T) <= length) { 91 return reinterpret_cast<const T*>(buffer.get()); 92 } 93 return nullptr; 94 } 95 96 private: 97 UniquePtr<uint8_t[]> buffer; 98 uint32_t length; 99 }; 100 101 /* 102 * Abstract base class of all message objects. Handles serialization of common 103 * elements like the error and user ID. Delegates specialized serialization 104 * to protected pure virtual functions implemented by subclasses. 105 */ 106 struct GateKeeperMessage { GateKeeperMessageGateKeeperMessage107 GateKeeperMessage() : error(ERROR_NONE) {} GateKeeperMessageGateKeeperMessage108 explicit GateKeeperMessage(gatekeeper_error_t error) : error(error) {} ~GateKeeperMessageGateKeeperMessage109 virtual ~GateKeeperMessage() {} 110 111 /** 112 * Returns serialized size in bytes of the current state of the 113 * object. 114 */ 115 uint32_t GetSerializedSize() const; 116 /** 117 * Converts the object into its serialized representation. 118 * 119 * Expects payload to be allocated with GetSerializedSize bytes. 120 * 121 * Returns the number of bytes written or 0 on error. 122 */ 123 uint32_t Serialize(uint8_t *payload, const uint8_t *end) const; 124 125 /** 126 * Inflates the object from its serial representation. 127 */ 128 gatekeeper_error_t Deserialize(const uint8_t *payload, const uint8_t *end); 129 130 /** 131 * Calls may fail due to throttling. If so, this sets a timeout in milliseconds 132 * for when the caller should attempt the call again. Additionally, sets the 133 * error to ERROR_RETRY. 134 */ 135 void SetRetryTimeout(uint32_t retry_timeout); 136 137 /** 138 * The following methods are intended to be implemented by subclasses. 139 * They are hooks to serialize the elements specific to each particular 140 * specialization. 141 */ 142 143 /** 144 * Returns the size of serializing only the elements specific to the 145 * current sublclass. 146 */ nonErrorSerializedSizeGateKeeperMessage147 virtual uint32_t nonErrorSerializedSize() const { return 0; } ; 148 /** 149 * Takes a pointer to a buffer prepared by Serialize and writes 150 * the subclass specific data into it. The size of the buffer must be exactly 151 * that returned by nonErrorSerializedSize() in bytes. 152 */ nonErrorSerializeGateKeeperMessage153 virtual void nonErrorSerialize(uint8_t *) const { } 154 155 /** 156 * Deserializes subclass specific data from payload without reading past end. 157 */ nonErrorDeserializeGateKeeperMessage158 virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *, const uint8_t *) { 159 return ERROR_NONE; 160 } 161 162 gatekeeper_error_t error; 163 uint32_t user_id; 164 uint32_t retry_timeout; 165 }; 166 167 struct VerifyRequest : public GateKeeperMessage { 168 VerifyRequest( 169 uint32_t user_id, 170 uint64_t challenge, 171 SizedBuffer enrolled_password_handle, 172 SizedBuffer provided_password_payload); VerifyRequestVerifyRequest173 VerifyRequest() : challenge(0) {} 174 175 uint32_t nonErrorSerializedSize() const override; 176 void nonErrorSerialize(uint8_t *buffer) const override; 177 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 178 179 uint64_t challenge; 180 SizedBuffer password_handle; 181 SizedBuffer provided_password; 182 }; 183 184 struct VerifyResponse : public GateKeeperMessage { 185 VerifyResponse(uint32_t user_id, SizedBuffer auth_token); 186 VerifyResponse(); 187 188 void SetVerificationToken(SizedBuffer auth_token); 189 190 uint32_t nonErrorSerializedSize() const override; 191 void nonErrorSerialize(uint8_t *buffer) const override; 192 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 193 194 SizedBuffer auth_token; 195 bool request_reenroll; 196 }; 197 198 struct EnrollRequest : public GateKeeperMessage { 199 EnrollRequest(uint32_t user_id, SizedBuffer password_handle, 200 SizedBuffer provided_password, SizedBuffer enrolled_password); 201 EnrollRequest() = default; 202 203 uint32_t nonErrorSerializedSize() const override; 204 void nonErrorSerialize(uint8_t *buffer) const override; 205 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 206 207 /** 208 * The password handle returned from the previous call to enroll or NULL 209 * if none 210 */ 211 SizedBuffer password_handle; 212 /** 213 * The currently enrolled password as entered by the user 214 */ 215 SizedBuffer enrolled_password; 216 /** 217 * The password desired by the user 218 */ 219 SizedBuffer provided_password; 220 }; 221 222 struct EnrollResponse : public GateKeeperMessage { 223 public: 224 EnrollResponse(uint32_t user_id, SizedBuffer enrolled_password_handle); 225 EnrollResponse() = default; 226 227 void SetEnrolledPasswordHandle(SizedBuffer enrolled_password_handle); 228 229 uint32_t nonErrorSerializedSize() const override; 230 void nonErrorSerialize(uint8_t *buffer) const override; 231 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 232 233 SizedBuffer enrolled_password_handle; 234 }; 235 236 struct DeleteUserRequest : public GateKeeperMessage { 237 DeleteUserRequest(uint32_t user_id); 238 DeleteUserRequest() = default; 239 nonErrorSerializedSizeDeleteUserRequest240 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteUserRequest241 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteUserRequest242 gatekeeper_error_t nonErrorDeserialize( 243 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 244 }; 245 246 struct DeleteUserResponse : public GateKeeperMessage { DeleteUserResponseDeleteUserResponse247 DeleteUserResponse() {} 248 nonErrorSerializedSizeDeleteUserResponse249 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteUserResponse250 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteUserResponse251 gatekeeper_error_t nonErrorDeserialize( 252 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 253 }; 254 255 256 struct DeleteAllUsersRequest : public GateKeeperMessage { DeleteAllUsersRequestDeleteAllUsersRequest257 DeleteAllUsersRequest() {}; 258 nonErrorSerializedSizeDeleteAllUsersRequest259 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteAllUsersRequest260 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteAllUsersRequest261 gatekeeper_error_t nonErrorDeserialize( 262 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 263 }; 264 265 struct DeleteAllUsersResponse : public GateKeeperMessage { DeleteAllUsersResponseDeleteAllUsersResponse266 DeleteAllUsersResponse() {} 267 nonErrorSerializedSizeDeleteAllUsersResponse268 uint32_t nonErrorSerializedSize() const override { return 0; } nonErrorSerializeDeleteAllUsersResponse269 void nonErrorSerialize(uint8_t * /*buffer*/) const override {} nonErrorDeserializeDeleteAllUsersResponse270 gatekeeper_error_t nonErrorDeserialize( 271 const uint8_t * /*payload*/, const uint8_t * /*end*/) override { return ERROR_NONE; } 272 }; 273 274 } 275 276 #endif // GATEKEEPER_MESSAGES_H_ 277