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 <UniquePtr.h>
21
22
23#include "gatekeeper_utils.h"
24/**
25 * Message serialization objects for communicating with the hardware gatekeeper.
26 */
27namespace gatekeeper {
28
29const uint32_t ENROLL = 0;
30const uint32_t VERIFY = 1;
31
32typedef enum {
33    ERROR_NONE = 0,
34    ERROR_INVALID = 1,
35    ERROR_RETRY = 2,
36    ERROR_UNKNOWN = 3,
37} gatekeeper_error_t;
38
39struct SizedBuffer {
40    SizedBuffer() {
41        length = 0;
42    }
43
44    /*
45     * Constructs a SizedBuffer of a provided
46     * length.
47     */
48    SizedBuffer(uint32_t length) {
49        if (length != 0) {
50            buffer.reset(new uint8_t[length]);
51        } else {
52            buffer.reset();
53        }
54        this->length = length;
55    }
56
57    /*
58     * Constructs a SizedBuffer out of a pointer and a length
59     * Takes ownership of the buf pointer, and deallocates it
60     * when destructed.
61     */
62    SizedBuffer(uint8_t buf[], uint32_t len) {
63        buffer.reset(buf);
64        length = len;
65    }
66
67    UniquePtr<uint8_t[]> buffer;
68    uint32_t length;
69};
70
71/*
72 * Abstract base class of all message objects. Handles serialization of common
73 * elements like the error and user ID. Delegates specialized serialization
74 * to protected pure virtual functions implemented by subclasses.
75 */
76struct GateKeeperMessage {
77    GateKeeperMessage() : error(ERROR_NONE) {}
78    GateKeeperMessage(gatekeeper_error_t error) : error(error) {}
79    virtual ~GateKeeperMessage() {}
80
81    /**
82     * Returns serialized size in bytes of the current state of the
83     * object.
84     */
85    uint32_t GetSerializedSize() const;
86    /**
87     * Converts the object into its serialized representation.
88     *
89     * Expects payload to be allocated with GetSerializedSize bytes.
90     *
91     * Returns the number of bytes written or 0 on error.
92     */
93    uint32_t Serialize(uint8_t *payload, const uint8_t *end) const;
94
95    /**
96     * Inflates the object from its serial representation.
97     */
98    gatekeeper_error_t Deserialize(const uint8_t *payload, const uint8_t *end);
99
100    /**
101     * Calls may fail due to throttling. If so, this sets a timeout in milliseconds
102     * for when the caller should attempt the call again. Additionally, sets the
103     * error to ERROR_RETRY.
104     */
105    void SetRetryTimeout(uint32_t retry_timeout);
106
107    /**
108     * The following methods are intended to be implemented by subclasses.
109     * They are hooks to serialize the elements specific to each particular
110     * specialization.
111     */
112
113    /**
114     * Returns the size of serializing only the elements specific to the
115     * current sublclass.
116     */
117    virtual uint32_t nonErrorSerializedSize() const { return 0; } ;
118    /**
119     * Takes a pointer to a buffer prepared by Serialize and writes
120     * the subclass specific data into it. The size of the buffer must be exactly
121     * that returned by nonErrorSerializedSize() in bytes.
122     */
123    virtual void nonErrorSerialize(uint8_t *) const { }
124
125    /**
126     * Deserializes subclass specific data from payload without reading past end.
127     */
128    virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *, const uint8_t *) {
129        return ERROR_NONE;
130    }
131
132    gatekeeper_error_t error;
133    uint32_t user_id;
134    uint32_t retry_timeout;
135};
136
137struct VerifyRequest : public GateKeeperMessage {
138    VerifyRequest(
139            uint32_t user_id,
140            uint64_t challenge,
141            SizedBuffer *enrolled_password_handle,
142            SizedBuffer *provided_password_payload);
143    VerifyRequest();
144    ~VerifyRequest();
145
146    virtual uint32_t nonErrorSerializedSize() const;
147    virtual void nonErrorSerialize(uint8_t *buffer) const;
148    virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end);
149
150    uint64_t challenge;
151    SizedBuffer password_handle;
152    SizedBuffer provided_password;
153};
154
155struct VerifyResponse : public GateKeeperMessage {
156    VerifyResponse(uint32_t user_id, SizedBuffer *auth_token);
157    VerifyResponse();
158    ~VerifyResponse();
159
160    void SetVerificationToken(SizedBuffer *auth_token);
161
162    virtual uint32_t nonErrorSerializedSize() const;
163    virtual void nonErrorSerialize(uint8_t *buffer) const;
164    virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end);
165
166    SizedBuffer auth_token;
167    bool request_reenroll;
168};
169
170struct EnrollRequest : public GateKeeperMessage {
171    EnrollRequest(uint32_t user_id, SizedBuffer *password_handle,
172            SizedBuffer *provided_password, SizedBuffer *enrolled_password);
173    EnrollRequest();
174    ~EnrollRequest();
175
176    virtual uint32_t nonErrorSerializedSize() const;
177    virtual void nonErrorSerialize(uint8_t *buffer) const;
178    virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end);
179
180    /**
181     * The password handle returned from the previous call to enroll or NULL
182     * if none
183     */
184    SizedBuffer password_handle;
185    /**
186     * The currently enrolled password as entered by the user
187     */
188    SizedBuffer enrolled_password;
189    /**
190     * The password desired by the user
191     */
192    SizedBuffer provided_password;
193};
194
195struct EnrollResponse : public GateKeeperMessage {
196public:
197    EnrollResponse(uint32_t user_id, SizedBuffer *enrolled_password_handle);
198    EnrollResponse();
199    ~EnrollResponse();
200
201    void SetEnrolledPasswordHandle(SizedBuffer *enrolled_password_handle);
202
203    virtual uint32_t nonErrorSerializedSize() const;
204    virtual void nonErrorSerialize(uint8_t *buffer) const;
205    virtual gatekeeper_error_t nonErrorDeserialize(const uint8_t *payload, const uint8_t *end);
206
207   SizedBuffer enrolled_password_handle;
208};
209}
210
211#endif // GATEKEEPER_MESSAGES_H_
212