blob: e4ba30d1863048e1f8dbdf7f43417d1454bc4b59 [file] [log] [blame]
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +02001// Copyright 2017 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef U2FD_U2FHID_H_
6#define U2FD_U2FHID_H_
7
Louis Collardca8d2712019-08-26 17:57:58 +08008#include <functional>
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +02009#include <memory>
10#include <string>
11#include <vector>
12
13#include <base/timer/timer.h>
14#include <brillo/errors/error.h>
Louis Collard255ca582019-05-24 12:54:33 +080015#include <metrics/metrics_library.h>
Louis Collard10ac9e92019-02-23 18:34:45 +080016#include <trunks/cr50_headers/u2f.h>
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020017
18#include "u2fd/hid_interface.h"
Louis Collard10ac9e92019-02-23 18:34:45 +080019#include "u2fd/u2f_adpu.h"
Louis Collardca8d2712019-08-26 17:57:58 +080020#include "u2fd/u2f_msg_handler.h"
Louis Collardf59aa942019-02-25 17:50:14 +080021#include "u2fd/user_state.h"
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020022
23namespace u2f {
24
Andrey Pronin34c6faf2018-08-14 14:37:26 -070025constexpr uint32_t kDefaultVendorId = 0x18d1;
26constexpr uint32_t kDefaultProductId = 0x502c;
27
28// Mandatory length of the U2F HID report.
29constexpr size_t kU2fReportSize = 64;
30
31// HID frame CMD/SEQ byte definitions.
32constexpr uint8_t kFrameTypeMask = 0x80;
33constexpr uint8_t kFrameTypeInit = 0x80;
34// when bit 7 is not set, the frame type is CONTinuation.
35
36// INIT command parameters
37constexpr uint32_t kCidBroadcast = -1U;
38constexpr size_t kInitNonceSize = 8;
39
40constexpr uint8_t kCapFlagWink = 0x01;
41constexpr uint8_t kCapFlagLock = 0x02;
42
43constexpr size_t kMaxPayloadSize = (64 - 7 + 128 * (64 - 5)); // 7609 bytes
44
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020045// U2fHid emulates U2FHID protocol on top of the TPM U2F implementation.
46// The object reads the HID report sent by the HIDInterface passed to the
47// constructor, parses it and extracts the U2FHID command. If this is a U2F
48// message, finally sends the raw U2F APDU to the |transmit_func| callback
49// passed to the constructor. It returns the final result (response APDU or
50// error code) inside an HID report through the HIDInterface.
51class U2fHid {
52 public:
Andrey Pronin34c6faf2018-08-14 14:37:26 -070053 // U2FHID Command codes
54 enum class U2fHidCommand : uint8_t {
55 kPing = 1,
56 kMsg = 3,
57 kLock = 4,
58 kVendorSysInfo = 5,
59 kInit = 6,
60 kWink = 8,
61 kError = 0x3f,
62 };
63
64 // U2FHID error codes
65 enum class U2fHidError : uint8_t {
66 kNone = 0,
67 kInvalidCmd = 1,
68 kInvalidPar = 2,
69 kInvalidLen = 3,
70 kInvalidSeq = 4,
71 kMsgTimeout = 5,
72 kChannelBusy = 6,
73 kLockRequired = 10,
74 kInvalidCid = 11,
75 kOther = 127,
76 };
77
Louis Collardca8d2712019-08-26 17:57:58 +080078 // Create a new virtual U2F HID Device. Does not take ownership of
79 // msg_handler, which must outlive this instance.
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020080 U2fHid(std::unique_ptr<HidInterface> hid,
Louis Collardca8d2712019-08-26 17:57:58 +080081 std::function<void()> wink_fn,
82 U2fMessageHandler* msg_handler);
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020083 ~U2fHid();
84 bool Init();
85
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020086 private:
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020087 // U2FHID protocol commands implementation.
88 void CmdInit(uint32_t cid, const std::string& payload);
89 int CmdLock(std::string* resp);
90 int CmdMsg(std::string* resp);
91 int CmdPing(std::string* resp);
Vincent Palatin828bfe92018-04-05 15:14:44 +020092 int CmdSysInfo(std::string* resp);
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020093 int CmdWink(std::string* resp);
94
95 // Fully resets the state of the possibly on-going U2FHID transaction.
96 void ClearTransaction();
97
98 // Sends back a U2FHID report with just the |errcode| error code inside
99 // on channel |cid|.
100 // If |clear| is set, clear the transaction state at the same time.
101 void ReturnError(U2fHidError errcode, uint32_t cid, bool clear);
102
103 // Called when we reach the deadline for the on-going transaction.
104 void TransactionTimeout();
105
106 // Called when we reach the deadline for an unreleased channel lock.
107 void LockTimeout();
108
109 // Sends back a U2FHID report indicating success and carrying the response
110 // payload |resp|.
111 void ReturnResponse(const std::string& resp);
112
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200113 // Executes the action requested by the command contained in the current
114 // transaction.
115 void ExecuteCmd();
116
117 // Parses the HID report contained in |report| and append the content to the
118 // current U2FHID transaction or create a new one.
119 void ProcessReport(const std::string& report);
120
Louis Collard10ac9e92019-02-23 18:34:45 +0800121
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200122 std::unique_ptr<HidInterface> hid_;
Louis Collardca8d2712019-08-26 17:57:58 +0800123 std::function<void()> wink_fn_;
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200124 uint32_t free_cid_;
125 uint32_t locked_cid_;
126 base::OneShotTimer lock_timeout_;
Louis Collardca8d2712019-08-26 17:57:58 +0800127 U2fMessageHandler* msg_handler_;
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200128
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200129 class HidPacket;
130 class HidMessage;
131 struct Transaction;
132
133 std::unique_ptr<Transaction> transaction_;
134
135 DISALLOW_COPY_AND_ASSIGN(U2fHid);
136};
137
138} // namespace u2f
139
140#endif // U2FD_U2FHID_H_