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