summaryrefslogtreecommitdiff
path: root/include/gatekeeper/gatekeeper.h
blob: 62f0b342df33d22d32927bfce570e0578b2edab2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
/*
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef GATEKEEPER_H_
#define GATEKEEPER_H_

#include <stdint.h>
#include <gatekeeper/UniquePtr.h>
#include <hardware/hw_auth_token.h>

#include "gatekeeper_messages.h"
#include "password_handle.h"

namespace gatekeeper {

struct __attribute__((packed)) failure_record_t {
    uint64_t secure_user_id;
    uint64_t last_checked_timestamp;
    uint32_t failure_counter;
};

/**
 * Base class for gatekeeper implementations. Provides all functionality except
 * the ability to create/access keys and compute signatures. These are left up
 * to the platform-specific implementation.
 */
class GateKeeper {
public:
    GateKeeper() {}
    virtual ~GateKeeper() {}

    void Enroll(const EnrollRequest &request, EnrollResponse *response);
    void Verify(const VerifyRequest &request, VerifyResponse *response);
    void DeleteUser(const DeleteUserRequest &request, DeleteUserResponse *response);
    void DeleteAllUsers(const DeleteAllUsersRequest &request, DeleteAllUsersResponse *response);

protected:

    // The following methods are intended to be implemented by concrete subclasses

    /**
     * Retrieves the key used by GateKeeper::MintAuthToken to sign the payload
     * of the AuthToken. This is not cached as is may have changed due to an event such
     * as a password change.
     *
     * Writes the length in bytes of the returned key to length if it is not null.
     *
     * Ownership of the auth_token_key pointer is maintained by the implementor.
     *
     * Returns true if the key was successfully fetched.
     *
     */
    virtual bool GetAuthTokenKey(const uint8_t **auth_token_key, uint32_t *length)
            const = 0;

    /**
     * The key used to sign and verify password data.
     *
     * MUST be different from the AuthTokenKey.
     *
     * GetPasswordKey is not const because unlike AuthTokenKey,
     * this value can be cached.
     *
     * Ownership of the password_key pointer is maintained by the implementor.
     *
     */
    virtual void GetPasswordKey(const uint8_t **password_key, uint32_t *length) = 0;

    /**
     * Uses platform-specific routines to compute a signature on the provided password.
     *
     * This can be implemented as a simple pass-through to ComputeSignature, but is
     * available in case handling for password signatures is different from general
     * purpose signatures.
     *
     * Writes the signature_length size signature to the 'signature' pointer.
     */
    virtual void ComputePasswordSignature(uint8_t *signature, uint32_t signature_length,
            const uint8_t *key, uint32_t key_length, const uint8_t *password,
            uint32_t password_length, salt_t salt) const = 0;

    /**
     * Retrieves a unique, cryptographically randomly generated buffer for use in password
     * hashing, etc.
     *
     * Assings the random to the random UniquePtr, relinquishing ownership to the caller
     */
    virtual void GetRandom(void *random, uint32_t requested_size) const = 0;

    /**
     * Uses platform-specific routines to compute a signature on the provided message.
     *
     * Writes the signature_length size signature to the 'signature' pointer.
     */
    virtual void ComputeSignature(uint8_t *signature, uint32_t signature_length,
            const uint8_t *key, uint32_t key_length, const uint8_t *message,
            const uint32_t length) const = 0;

    /**
     * Get the time since boot in milliseconds.
     *
     * Should return 0 on error.
     */
    virtual uint64_t GetMillisecondsSinceBoot() const = 0;

    /**
     * Removes all records for the given user.
     *
     * Returns true if the user's records were successfully deleted.
     */
    virtual gatekeeper_error_t RemoveUser(uint32_t /* uid */) { return ERROR_NOT_IMPLEMENTED; }

    /**
     * Removes all records.
     *
     * Returns true if the records were successfully deleted.
     */
    virtual gatekeeper_error_t RemoveAllUsers() { return ERROR_NOT_IMPLEMENTED; }

    /**
     * Returns the value of the current failure record for the user.
     *
     * The failure record should be written to hardware-backed secure storage, such as
     * RPMB, if the target device supports it.
     *
     * If 'secure' is false, password is operating in a fallback mode. Implementations
     * may store the failure record in memory or in non-secure storage if this value is false.
     *
     * Returns true on success, false if failure record cannot be retrieved.
     */
    virtual bool GetFailureRecord(uint32_t uid, secure_id_t user_id, failure_record_t *record,
            bool secure) = 0;

    /**
     * Initializes or reinitializes the failure record for the current user.
     *
     * Must be persisted in secure storage if the target device supports it.
     *
     * If 'secure' is false, password is operating in a fallback mode. Implementations
     * may store the failure record in memory or in non-secure storage if this value is false.
     *
     * Returns true if the failure record was successfully persisted.
     */
    virtual bool ClearFailureRecord(uint32_t uid, secure_id_t user_id, bool secure) = 0;

    /*
     * Writes the provided failure record to persistent storage.
     *
     * Must be persisted in secure storage if the target device supports it.
     *
     * If 'secure' is false, password is operating in a fallback mode. Implementations
     * may store the failure record in memory or in non-secure storage if this value is false.
     *
     * Returns true if record was successfully written.
     */
    virtual bool WriteFailureRecord(uint32_t uid, failure_record_t *record, bool secure) = 0;

    /**
     * Computes the amount of time to throttle the user due to the current failure_record
     * counter. An implementation is provided by the generic GateKeeper, but may be
     * overriden.
     */
    virtual uint32_t ComputeRetryTimeout(const failure_record_t *record);

    /**
     * Returns whether the GateKeeper implementation is backed by hardware.
     */
    virtual bool IsHardwareBacked() const = 0;

    /**
     * Verifies that handle matches password HMAC'ed with the password_key
     */
    virtual bool DoVerify(const password_handle_t *expected_handle, const SizedBuffer &password);

private:
    /**
     * Generates a signed attestation of an authentication event and assings
     * to auth_token UniquePtr.
     * The format is consistent with that of hw_auth_token_t.
     * Also returns the length in length if it is not null.
     */
    gatekeeper_error_t MintAuthToken(SizedBuffer *auth_token, uint64_t timestamp,
            secure_id_t user_id, secure_id_t authenticator_id, uint64_t challenge);

    /**
     * Populates password_handle with the data provided and computes HMAC.
     */
    bool CreatePasswordHandle(SizedBuffer *password_handle, salt_t salt,
            secure_id_t secure_id, secure_id_t authenticator_id, uint8_t handle_version,
            const SizedBuffer & password);

    /**
     * Increments the counter on the current failure record for the provided user id.
     * Sets the last_checked_timestamp to timestamp. Writes the updated record
     * to *record if not null.
     *
     * Returns true if failure record was successfully incremented.
     */
    bool IncrementFailureRecord(uint32_t uid, secure_id_t user_id, uint64_t timestamp,
            failure_record_t *record, bool secure);

    /**
     * Determines whether the request is within the current throttle window.
     *
     * If the system timer has been reset due to a reboot or otherwise, resets
     * the throttle window with a base at the current time.
     *
     * Returns true if the request is in the throttle window.
     */
    bool ThrottleRequest(uint32_t uid, uint64_t timestamp,
            failure_record_t *record, bool secure, GateKeeperMessage *response);
};

}

#endif // GATEKEEPER_H_