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