-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathle_credential_backend.h
249 lines (227 loc) · 10.6 KB
/
le_credential_backend.h
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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRYPTOHOME_LE_CREDENTIAL_BACKEND_H_
#define CRYPTOHOME_LE_CREDENTIAL_BACKEND_H_
#include <map>
#include <string>
#include <vector>
#include <brillo/secure_blob.h>
namespace cryptohome {
// Constants used to define the hash tree. Currently we place them here,
// since they are used between LECredentialManager and LECredentialBackend.
const uint32_t kLengthLabels = 14;
const uint32_t kNumChildren = 4;
const uint32_t kBitsPerLevel = 2;
// List of error values returned from TPM for the Low Entropy Credential
// check routine.
enum LECredBackendError {
// Credential check was successful.
LE_TPM_SUCCESS = 0,
// Check failed due to incorrect Low Entropy credential provided.
LE_TPM_ERROR_INVALID_LE_SECRET,
// Reset failed due to incorrect Reset credential provided.
LE_TPM_ERROR_INVALID_RESET_SECRET,
// Check failed since the credential has been locked out due to too many
// attempts per the delay schedule.
LE_TPM_ERROR_TOO_MANY_ATTEMPTS,
// Check failed due to the hash tree being out of sync. This should
// prompt a hash tree resynchronization and retry.
LE_TPM_ERROR_HASH_TREE_SYNC,
// Check failed due to an operation failing on the TPM side. This should
// prompt a hash tree resynchronization and retry.
LE_TPM_ERROR_TPM_OP_FAILED,
// The PCR is in unexpected state. The basic way to proceed from here is to
// reboot the device.
LE_TPM_ERROR_PCR_NOT_MATCH,
};
// Enum used to denote the LE log entry type.
enum LELogEntryType {
LE_LOG_INSERT = 0,
LE_LOG_CHECK,
LE_LOG_REMOVE,
LE_LOG_RESET,
// Sentinel value.
LE_LOG_INVALID,
};
// Container for LE credential log replay data obtained from the LE Backend.
// This struct is used during sychronization operations which occur when the
// on-disk hash tree state and LE Backend hash tree state are out-of-sync.
struct LELogEntry {
LELogEntryType type;
// Label on which the log operation is performed.
uint64_t label;
// Value of root hash after the log operation is performed.
std::vector<uint8_t> root;
// For insert operations, this signifies the MAC of the inserted leaf.
std::vector<uint8_t> mac;
};
// Defines a set of PCR indexes (in bitmask) and the digest that is valid
// after computation of sha256 of concatenation of PCR values included in
// bitmask.
struct ValidPcrValue {
/* The set of PCR indexes that have to pass the validation. */
uint8_t bitmask[2];
/* The hash digest of the PCR values contained in the bitmask */
std::string digest;
};
typedef std::vector<ValidPcrValue> ValidPcrCriteria;
// LECredentialBackend - class for performing Low Entropy (LE) Credential
// related operations in the TPM. The Tpm class implementations which support LE
// Credential handling will contain an object of a class which implements
// this interface. The base Tpm Class will have a functnon which can be
// used to retrieve a reference to this object. For Tpm implementations which
// don't support LE Credentials, the aforementioned function will return a
// nullptr.
class LECredentialBackend {
public:
// Resets the TPM Low Entropy (LE) Credential Hash Tree root hash
// with its initial known value, which assumes all MACs are all-zero.
//
// This function should be executed only when we are setting up a hash tree
// on a new / wiped device, or resetting the hash tree due to an
// unrecoverable error.
//
// Returns true on success, false otherwise.
//
// In all cases, the resulting root hash is returned in |new_root|.
virtual bool Reset(std::vector<uint8_t>* new_root) = 0;
// Returns whether LE credential protection is supported in this specific
// backend. Not all TPM2-based h/w will support this feature (only Cr50
// and later), so this function will only return true for h/w which does.
virtual bool IsSupported() = 0;
// Tries to insert a credential into the TPM.
//
// The label of the leaf node is in |label|, the list of auxiliary hashes is
// in |h_aux|, the LE credential to be added is in |le_secret|. Along with
// it, its associated reset_secret |reset_secret| and the high entropy
// credential it protects |he_secret| are also provided. The delay schedule
// which determines the delay enforced between authentication attempts is
// provided by |delay_schedule|. The list of valid PCR values that would be
// accepted by authentication is provided by |valid_pcr_criteria|.
//
// If successful, the new credential metadata will be placed in the blob
// pointed by |cred_metadata|. The MAC of the credential will be returned
// in |mac|.
//
// Returns true on success, false on failure.
//
// |h_aux| requires a particular order: starting from left child to right
// child, from leaf upwards till the children of the root label.
//
// In all cases, the resulting root hash is returned in |new_root|.
virtual bool InsertCredential(
const uint64_t label,
const std::vector<std::vector<uint8_t>>& h_aux,
const brillo::SecureBlob& le_secret,
const brillo::SecureBlob& he_secret,
const brillo::SecureBlob& reset_secret,
const std::map<uint32_t, uint32_t>& delay_schedule,
const ValidPcrCriteria& valid_pcr_criteria,
std::vector<uint8_t>* cred_metadata,
std::vector<uint8_t>* mac,
std::vector<uint8_t>* new_root) = 0;
// Checks the metadata leaf version and returns if the leaf needs to be bound
// to PCR.
virtual bool NeedsPCRBinding(const std::vector<uint8_t>& cred_metadata) = 0;
// Looks into the metadata and retrieves the number of wrong authentication
// attempts. Returns -1 on error.
virtual int GetWrongAuthAttempts(
const std::vector<uint8_t>& cred_metadata) = 0;
// Tries to verify/authenticate a credential.
//
// The obfuscated LE Credential is |le_secret| and the credential metadata is
// in |orig_cred_metadata|.
//
// Returns true on success, false on failure.
// On success, |err| is set to LE_TPM_SUCCESS.
// On failure, |err| is set with the appropriate error code:
// - LE_TPM_ERROR_INVALID_LE_SECRET for incorrect authentication attempt.
// - LE_TPM_ERROR_TOO_MANY_ATTEMPTS for locked out credential.
// - LE_TPM_ERROR_HASH_TREE for error in hash tree sync.
// - LE_TPM_ERROR_TPM_OP_FAILED for Tpm operation error.
//
// On success, or failure due to an invalid |le_secret|, the updated
// credential metadata and corresponding new MAC will be returned in
// |new_cred_metadata| and |new_mac|.
//
// On success, the released high entropy credential will be returned in
// |he_secret| and the reset secret in |reset_secret|.
//
// In all cases, the resulting root hash is returned in |new_root|.
virtual bool CheckCredential(const uint64_t label,
const std::vector<std::vector<uint8_t>>& h_aux,
const std::vector<uint8_t>& orig_cred_metadata,
const brillo::SecureBlob& le_secret,
std::vector<uint8_t>* new_cred_metadata,
std::vector<uint8_t>* new_mac,
brillo::SecureBlob* he_secret,
brillo::SecureBlob* reset_secret,
LECredBackendError* err,
std::vector<uint8_t>* new_root) = 0;
// Tries to reset a (potentially locked out) credential.
//
// The reset credential is |reset_secret| and the credential metadata is
// in |orig_cred_metadata|.
//
// Returns true on success, false on failure.
// On success, |err| is set to LE_TPM_SUCCESS.
// On failure, |err| is set with the appropriate error code:
// - LE_TPM_ERROR_INVALID_RESET_SECRET for incorrect authentication attempt.
// - LE_TPM_ERROR_HASH_TREE for error in hash tree sync.
// - LE_TPM_ERROR_TPM_OP_FAILED for Tpm operation error.
//
// On success, the updated credential metadata and corresponding new MAC will
// be returned in |new_cred_metadata| and |new_mac|.
//
// In all cases, the resulting root hash is returned in |new_root|.
virtual bool ResetCredential(const uint64_t label,
const std::vector<std::vector<uint8_t>>& h_aux,
const std::vector<uint8_t>& orig_cred_metadata,
const brillo::SecureBlob& reset_secret,
std::vector<uint8_t>* new_cred_metadata,
std::vector<uint8_t>* new_mac,
LECredBackendError* err,
std::vector<uint8_t>* new_root) = 0;
// Removes the credential which has label |label|.
//
// The corresponding list of auxiliary hashes is in |h_aux|, and the MAC of
// the label that needs to be removed is |mac|.
//
// Returns true on success, false on failure.
//
// In all cases, the resulting root hash is returned in |new_root|.
virtual bool RemoveCredential(const uint64_t label,
const std::vector<std::vector<uint8_t>>& h_aux,
const std::vector<uint8_t>& mac,
std::vector<uint8_t>* new_root) = 0;
// Retrieves the replay log.
//
// The current on-disk root hash is supplied via |cur_disk_root_hash|.
// The LE backend's current root hash is returned in |root_hash|
//
// Returns true on success (was able to communicate with the backend), and
// false otherwise.
// TODO(crbug.com/809710): Add a |log_data| vector which should return log
// entries in already-parsed form.
virtual bool GetLog(const std::vector<uint8_t>& cur_disk_root_hash,
std::vector<uint8_t>* root_hash,
std::vector<LELogEntry>* log) = 0;
// Replays the log operation referenced by |log_entry_root|, where
// |log_entry_root| is the resulting root hash after the operation, and is
// retrieved from the log entry.
// |h_aux| and |orig_cred_metadata| refer to, respectively, the list of
// auxiliary hashes and the original credential metadata associated with the
// label concerned (available in the log entry). The resulting metadata and
// MAC are stored in |new_cred_metadata| and |new_mac|.
//
// Returns true on success, false on failure.
virtual bool ReplayLogOperation(
const std::vector<uint8_t>& log_entry_root,
const std::vector<std::vector<uint8_t>>& h_aux,
const std::vector<uint8_t>& orig_cred_metadata,
std::vector<uint8_t>* new_cred_metadata,
std::vector<uint8_t>* new_mac) = 0;
};
} // namespace cryptohome
#endif // CRYPTOHOME_LE_CREDENTIAL_BACKEND_H_