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 } gatekeeper_error_t; 40 41 struct SizedBuffer { SizedBufferSizedBuffer42 SizedBuffer() { 43 length = 0; 44 } ~SizedBufferSizedBuffer45 ~SizedBuffer() { 46 if (buffer && length > 0) { 47 memset_s(buffer.get(), 0, length); 48 } 49 } 50 /* 51 * Constructs a SizedBuffer out of a pointer and a length 52 * Takes ownership of the buf pointer, and deallocates it 53 * when destructed. 54 */ SizedBufferSizedBuffer55 SizedBuffer(uint8_t buf[], uint32_t len) { 56 if (buf == nullptr) { 57 length = 0; 58 } else { 59 buffer.reset(buf); 60 length = len; 61 } 62 } 63 SizedBufferSizedBuffer64 SizedBuffer(SizedBuffer && rhs) : buffer(move(rhs.buffer)), length(rhs.length) { 65 rhs.length = 0; 66 } 67 68 SizedBuffer & operator=(SizedBuffer && rhs) { 69 if (&rhs != this) { 70 buffer = move(rhs.buffer); 71 length = rhs.length; 72 rhs.length = 0; 73 } 74 return *this; 75 } 76 77 operator bool() const { 78 return buffer; 79 } 80 sizeSizedBuffer81 uint32_t size() const { return buffer ? length : 0; } 82 83 /** 84 * Returns an pointer to the const buffer IFF the buffer is initialized and the length 85 * field holds a values greater or equal to the size of the requested template argument type. 86 */ 87 template <typename T> DataSizedBuffer88 const T* Data() const { 89 if (buffer.get() != nullptr && sizeof(T) <= length) { 90 return reinterpret_cast<const T*>(buffer.get()); 91 } 92 return nullptr; 93 } 94 95 private: 96 UniquePtr<uint8_t[]> buffer; 97 uint32_t length; 98 }; 99 100 /* 101 * Abstract base class of all message objects. Handles serialization of common 102 * elements like the error and user ID. Delegates specialized serialization 103 * to protected pure virtual functions implemented by subclasses. 104 */ 105 struct GateKeeperMessage { GateKeeperMessageGateKeeperMessage106 GateKeeperMessage() : error(ERROR_NONE) {} GateKeeperMessageGateKeeperMessage107 explicit GateKeeperMessage(gatekeeper_error_t error) : error(error) {} ~GateKeeperMessageGateKeeperMessage108 virtual ~GateKeeperMessage() {} 109 110 /** 111 * Returns serialized size in bytes of the current state of the 112 * object. 113 */ 114 uint32_t GetSerializedSize() const; 115 /** 116 * Converts the object into its serialized representation. 117 * 118 * Expects payload to be allocated with GetSerializedSize bytes. 119 * 120 * Returns the number of bytes written or 0 on error. 121 */ 122 uint32_t Serialize(uint8_t *payload, const uint8_t *end) const; 123 124 /** 125 * Inflates the object from its serial representation. 126 */ 127 gatekeeper_error_t Deserialize(const uint8_t *payload, const uint8_t *end); 128 129 /** 130 * Calls may fail due to throttling. If so, this sets a timeout in milliseconds 131 * for when the caller should attempt the call again. Additionally, sets the 132 * error to ERROR_RETRY. 133 */ 134 void SetRetryTimeout(uint32_t retry_timeout); 135 136 /** 137 * The following methods are intended to be implemented by subclasses. 138 * They are hooks to serialize the elements specific to each particular 139 * specialization. 140 */ 141 142 /** 143 * Returns the size of serializing only the elements specific to the 144 * current sublclass. 145 */ nonErrorSerializedSizeGateKeeperMessage146 virtual uint32_t nonErrorSerializedSize() const { return 0; } ; 147 /** 148 * Takes a pointer to a buffer prepared by Serialize and writes 149 * the subclass specific data into it. The size of the buffer must be exactly 150 * that returned by nonErrorSerializedSize() in bytes. 151 */ nonErrorSerializeGateKeeperMessage152 virtual void nonErrorSerialize(uint8_t *) const { } 153 154 /** 155 * Deserializes subclass specific data from payload without reading past end. 156 */ nonErrorDeserializeGateKeeperMessage157 virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *, const uint8_t *) { 158 return ERROR_NONE; 159 } 160 161 gatekeeper_error_t error; 162 uint32_t user_id; 163 uint32_t retry_timeout; 164 }; 165 166 struct VerifyRequest : public GateKeeperMessage { 167 VerifyRequest( 168 uint32_t user_id, 169 uint64_t challenge, 170 SizedBuffer enrolled_password_handle, 171 SizedBuffer provided_password_payload); VerifyRequestVerifyRequest172 VerifyRequest() : challenge(0) {} 173 174 uint32_t nonErrorSerializedSize() const override; 175 void nonErrorSerialize(uint8_t *buffer) const override; 176 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 177 178 uint64_t challenge; 179 SizedBuffer password_handle; 180 SizedBuffer provided_password; 181 }; 182 183 struct VerifyResponse : public GateKeeperMessage { 184 VerifyResponse(uint32_t user_id, SizedBuffer auth_token); 185 VerifyResponse(); 186 187 void SetVerificationToken(SizedBuffer auth_token); 188 189 uint32_t nonErrorSerializedSize() const override; 190 void nonErrorSerialize(uint8_t *buffer) const override; 191 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 192 193 SizedBuffer auth_token; 194 bool request_reenroll; 195 }; 196 197 struct EnrollRequest : public GateKeeperMessage { 198 EnrollRequest(uint32_t user_id, SizedBuffer password_handle, 199 SizedBuffer provided_password, SizedBuffer enrolled_password); 200 EnrollRequest() = default; 201 202 uint32_t nonErrorSerializedSize() const override; 203 void nonErrorSerialize(uint8_t *buffer) const override; 204 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 205 206 /** 207 * The password handle returned from the previous call to enroll or NULL 208 * if none 209 */ 210 SizedBuffer password_handle; 211 /** 212 * The currently enrolled password as entered by the user 213 */ 214 SizedBuffer enrolled_password; 215 /** 216 * The password desired by the user 217 */ 218 SizedBuffer provided_password; 219 }; 220 221 struct EnrollResponse : public GateKeeperMessage { 222 public: 223 EnrollResponse(uint32_t user_id, SizedBuffer enrolled_password_handle); 224 EnrollResponse() = default; 225 226 void SetEnrolledPasswordHandle(SizedBuffer enrolled_password_handle); 227 228 uint32_t nonErrorSerializedSize() const override; 229 void nonErrorSerialize(uint8_t *buffer) const override; 230 gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end) override; 231 232 SizedBuffer enrolled_password_handle; 233 }; 234 } 235 236 #endif // GATEKEEPER_MESSAGES_H_ 237