-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcros_fp_device.h
163 lines (134 loc) · 5.73 KB
/
cros_fp_device.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
// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BIOD_CROS_FP_DEVICE_H_
#define BIOD_CROS_FP_DEVICE_H_
#include <bitset>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/files/file_util.h>
#include <libec/fingerprint/cros_fp_device_interface.h>
#include <libec/ec_command_factory.h>
#include <libec/fingerprint/fp_info_command.h>
#include <libec/fingerprint/fp_mode.h>
#include "biod/biod_metrics.h"
#include "biod/uinput_device.h"
namespace biod {
class CrosFpDevice : public ec::CrosFpDeviceInterface {
public:
static std::unique_ptr<CrosFpDevice> Create(
BiodMetricsInterface* biod_metrics,
std::unique_ptr<ec::EcCommandFactoryInterface> ec_command_factory) {
// Using new to access non-public constructor.
// See https://abseil.io/tips/134.
auto dev = base::WrapUnique(
new CrosFpDevice(biod_metrics, std::move(ec_command_factory)));
if (!dev->Init()) {
return nullptr;
}
return dev;
}
void SetMkbpEventCallback(MkbpCallback callback) override;
// Run a simple command to get the version information from FP MCU and check
// whether the image type returned is the same as |expected_image|.
static bool WaitOnEcBoot(const base::ScopedFD& cros_fp_fd,
ec_image expected_image);
// Run a simple command to get the version information from FP MCU.
static std::optional<EcVersion> GetVersion(const base::ScopedFD& cros_fp_fd);
// ec::CrosFpDeviceInterface overrides:
~CrosFpDevice() override;
bool SetFpMode(const ec::FpMode& mode) override;
ec::FpMode GetFpMode() override;
std::optional<FpStats> GetFpStats() override;
std::optional<std::bitset<32>> GetDirtyMap() override;
bool SupportsPositiveMatchSecret() override;
std::optional<brillo::SecureVector> GetPositiveMatchSecret(
int index) override;
std::optional<GetSecretReply> GetPositiveMatchSecretWithPubkey(
int index,
const brillo::Blob& pk_in_x,
const brillo::Blob& pk_in_y) override;
std::unique_ptr<VendorTemplate> GetTemplate(int index) override;
bool UploadTemplate(const VendorTemplate& tmpl) override;
bool PreloadTemplate(size_t idx, const VendorTemplate& tmpl) override;
bool ReloadTemplates(size_t num) override;
bool SetContext(std::string user_id) override;
bool SetNonceContext(const brillo::Blob& nonce,
const brillo::Blob& encrypted_user_id,
const brillo::Blob& iv) override;
std::optional<brillo::Blob> GetNonce() override;
bool ResetContext() override;
// Initialise the entropy in the SBP. If |reset| is true, the old entropy
// will be deleted. If |reset| is false, we will only add entropy, and only
// if no entropy had been added before.
bool InitEntropy(bool reset) override;
bool UpdateFpInfo() override;
std::optional<PairingKeyKeygenReply> PairingKeyKeygen() override;
std::optional<brillo::Blob> PairingKeyWrap(
const brillo::Blob& pub_x,
const brillo::Blob& pub_y,
const brillo::Blob& encrypted_priv) override;
bool LoadPairingKey(const brillo::Blob& encrypted_pairing_key) override;
int MaxTemplateCount() override;
int TemplateVersion() override;
int DeadPixelCount() override;
ec::FpSensorErrors GetHwErrors() override;
ec::EcCmdVersionSupportStatus EcCmdVersionSupported(uint16_t cmd,
uint32_t ver) override;
// Kernel device exposing the MCU command interface.
static constexpr char kCrosFpPath[] = "/dev/cros_fp";
// Although very rare, we have seen device commands fail due
// to ETIMEDOUT. For this reason, we attempt certain critical
// device IO operation twice.
static constexpr int kMaxIoAttempts = 2;
static constexpr int kLastTemplate = -1;
protected:
CrosFpDevice(
BiodMetricsInterface* biod_metrics,
std::unique_ptr<ec::EcCommandFactoryInterface> ec_command_factory)
: ec_command_factory_(std::move(ec_command_factory)),
biod_metrics_(biod_metrics) {}
bool Init();
virtual int read(int fd, void* buf, size_t count) {
return ::read(fd, buf, count);
}
std::optional<std::string> ReadVersion();
private:
struct EcProtocolInfo {
uint16_t max_read = 0;
uint16_t max_write = 0;
};
bool EcDevInit();
std::optional<EcProtocolInfo> EcProtoInfo();
bool EcReboot(ec_image to_image);
// Run the EC command to generate new entropy in the underlying MCU.
// |reset| specifies whether we want to merely add entropy (false), or
// perform a reset, which erases old entropy(true).
bool AddEntropy(bool reset);
// Get block id from rollback info.
std::optional<int32_t> GetRollBackInfoId();
std::optional<brillo::SecureVector> FpReadMatchSecret(uint16_t index);
std::optional<GetSecretReply> FpReadMatchSecretWithPubkey(
int index, const brillo::Blob& pk_in_x, const brillo::Blob& pk_in_y);
std::optional<int> GetIndexOfLastTemplate();
// Run a sequence of EC commands to update the entropy in the
// MCU. If |reset| is set to true, it will additionally erase the existing
// entropy too.
bool UpdateEntropy(bool reset);
std::unique_ptr<ec::FlashProtectCommand> GetFlashProtect();
void OnEventReadable();
base::ScopedFD cros_fd_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> watcher_;
EcProtocolInfo ec_protocol_info_;
std::unique_ptr<ec::FpInfoCommand> info_;
std::unique_ptr<ec::EcCommandFactoryInterface> ec_command_factory_;
MkbpCallback mkbp_event_;
UinputDevice input_device_;
BiodMetricsInterface* biod_metrics_ = nullptr; // Not owned.
};
} // namespace biod
#endif // BIOD_CROS_FP_DEVICE_H_