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
17#ifndef GATEKEEPER_H_
18#define GATEKEEPER_H_
19
20#include <stdint.h>
21#include <UniquePtr.h>
22#include <hardware/hw_auth_token.h>
23
24#include "gatekeeper_messages.h"
25#include "password_handle.h"
26
27namespace gatekeeper {
28
29struct __attribute__((packed)) failure_record_t {
30    uint64_t secure_user_id;
31    uint64_t last_checked_timestamp;
32    uint32_t failure_counter;
33};
34
35/**
36 * Base class for gatekeeper implementations. Provides all functionality except
37 * the ability to create/access keys and compute signatures. These are left up
38 * to the platform-specific implementation.
39 */
40class GateKeeper {
41public:
42    GateKeeper() {}
43    virtual ~GateKeeper() {}
44
45    void Enroll(const EnrollRequest &request, EnrollResponse *response);
46    void Verify(const VerifyRequest &request, VerifyResponse *response);
47
48protected:
49
50    // The following methods are intended to be implemented by concrete subclasses
51
52    /**
53     * Retrieves the key used by GateKeeper::MintAuthToken to sign the payload
54     * of the AuthToken. This is not cached as is may have changed due to an event such
55     * as a password change.
56     *
57     * Writes the length in bytes of the returned key to length if it is not null.
58     *
59     * Ownership of the auth_token_key pointer is maintained by the implementor.
60     *
61     * Returns true if the key was successfully fetched.
62     *
63     */
64    virtual bool GetAuthTokenKey(const uint8_t **auth_token_key, uint32_t *length)
65            const = 0;
66
67    /**
68     * The key used to sign and verify password data.
69     *
70     * MUST be different from the AuthTokenKey.
71     *
72     * GetPasswordKey is not const because unlike AuthTokenKey,
73     * this value can be cached.
74     *
75     * Ownership of the password_key pointer is maintained by the implementor.
76     *
77     */
78    virtual void GetPasswordKey(const uint8_t **password_key, uint32_t *length) = 0;
79
80    /**
81     * Uses platform-specific routines to compute a signature on the provided password.
82     *
83     * This can be implemented as a simple pass-through to ComputeSignature, but is
84     * available in case handling for password signatures is different from general
85     * purpose signatures.
86     *
87     * Writes the signature_length size signature to the 'signature' pointer.
88     */
89    virtual void ComputePasswordSignature(uint8_t *signature, uint32_t signature_length,
90            const uint8_t *key, uint32_t key_length, const uint8_t *password,
91            uint32_t password_length, salt_t salt) const = 0;
92
93    /**
94     * Retrieves a unique, cryptographically randomly generated buffer for use in password
95     * hashing, etc.
96     *
97     * Assings the random to the random UniquePtr, relinquishing ownership to the caller
98     */
99    virtual void GetRandom(void *random, uint32_t requested_size) const = 0;
100
101    /**
102     * Uses platform-specific routines to compute a signature on the provided message.
103     *
104     * Writes the signature_length size signature to the 'signature' pointer.
105     */
106    virtual void ComputeSignature(uint8_t *signature, uint32_t signature_length,
107            const uint8_t *key, uint32_t key_length, const uint8_t *message,
108            const uint32_t length) const = 0;
109
110    /**
111     * Get the time since boot in milliseconds.
112     *
113     * Should return 0 on error.
114     */
115    virtual uint64_t GetMillisecondsSinceBoot() const = 0;
116
117    /**
118     * Returns the value of the current failure record for the user.
119     *
120     * The failure record should be written to hardware-backed secure storage, such as
121     * RPMB, if the target device supports it.
122     *
123     * If 'secure' is false, password is operating in a fallback mode. Implementations
124     * may store the failure record in memory or in non-secure storage if this value is false.
125     *
126     * Returns true on success, false if failure record cannot be retrieved.
127     */
128    virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t *record,
129            bool secure) = 0;
130
131    /**
132     * Initializes or reinitializes the failure record for the current user.
133     *
134     * Must be persisted in secure storage if the target device supports it.
135     *
136     * If 'secure' is false, password is operating in a fallback mode. Implementations
137     * may store the failure record in memory or in non-secure storage if this value is false.
138     *
139     * Returns true if the failure record was successfully persisted.
140     */
141    virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool secure) = 0;
142
143    /*
144     * Writes the provided failure record to persistent storage.
145     *
146     * Must be persisted in secure storage if the target device supports it.
147     *
148     * If 'secure' is false, password is operating in a fallback mode. Implementations
149     * may store the failure record in memory or in non-secure storage if this value is false.
150     *
151     * Returns true if record was successfully written.
152     */
153    virtual bool WriteFailureRecord(uint32_t uid, failure_record_t *record, bool secure) = 0;
154
155    /**
156     * Computes the amount of time to throttle the user due to the current failure_record
157     * counter. An implementation is provided by the generic GateKeeper, but may be
158     * overriden.
159     */
160    virtual uint32_t ComputeRetryTimeout(const failure_record_t *record);
161
162    /**
163     * Returns whether the GateKeeper implementation is backed by hardware.
164     */
165    virtual bool IsHardwareBacked() const = 0;
166
167    /**
168     * Verifies that handle matches password HMAC'ed with the password_key
169     */
170    virtual bool DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password);
171
172private:
173    /**
174     * Generates a signed attestation of an authentication event and assings
175     * to auth_token UniquePtr.
176     * The format is consistent with that of hw_auth_token_t.
177     * Also returns the length in length if it is not null.
178     */
179    void MintAuthToken(UniquePtr<uint8_t> *auth_token, uint32_t *length, uint64_t timestamp,
180            secure_id_t user_id, secure_id_t authenticator_id, uint64_t challenge);
181
182    /**
183     * Populates password_handle with the data provided and computes HMAC.
184     */
185    bool CreatePasswordHandle(SizedBuffer *password_handle, salt_t salt,
186            secure_id_t secure_id, secure_id_t authenticator_id, uint8_t handle_version,
187            const uint8_t *password, uint32_t password_length);
188
189    /**
190     * Increments the counter on the current failure record for the provided user id.
191     * Sets the last_checked_timestamp to timestamp. Writes the updated record
192     * to *record if not null.
193     *
194     * Returns true if failure record was successfully incremented.
195     */
196    bool IncrementFailureRecord(uint32_t uid, secure_id_t user_id, uint64_t timestamp,
197            failure_record_t *record, bool secure);
198
199    /**
200     * Determines whether the request is within the current throttle window.
201     *
202     * If the system timer has been reset due to a reboot or otherwise, resets
203     * the throttle window with a base at the current time.
204     *
205     * Returns true if the request is in the throttle window.
206     */
207    bool ThrottleRequest(uint32_t uid, uint64_t timestamp,
208            failure_record_t *record, bool secure, GateKeeperMessage *response);
209};
210
211}
212
213#endif // GATEKEEPER_H_
214