blob: a7d24729460d804680e56b5656394b892e50feb8 [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 -070025// Mandatory length of the U2F HID report.
26constexpr size_t kU2fReportSize = 64;
27
28// HID frame CMD/SEQ byte definitions.
29constexpr uint8_t kFrameTypeMask = 0x80;
30constexpr uint8_t kFrameTypeInit = 0x80;
31// when bit 7 is not set, the frame type is CONTinuation.
32
33// INIT command parameters
34constexpr uint32_t kCidBroadcast = -1U;
35constexpr size_t kInitNonceSize = 8;
36
Andrey Pronin34c6faf2018-08-14 14:37:26 -070037constexpr uint8_t kCapFlagLock = 0x02;
38
39constexpr size_t kMaxPayloadSize = (64 - 7 + 128 * (64 - 5)); // 7609 bytes
40
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020041// U2fHid emulates U2FHID protocol on top of the TPM U2F implementation.
42// The object reads the HID report sent by the HIDInterface passed to the
43// constructor, parses it and extracts the U2FHID command. If this is a U2F
44// message, finally sends the raw U2F APDU to the |transmit_func| callback
45// passed to the constructor. It returns the final result (response APDU or
46// error code) inside an HID report through the HIDInterface.
47class U2fHid {
48 public:
Andrey Pronin34c6faf2018-08-14 14:37:26 -070049 // U2FHID Command codes
50 enum class U2fHidCommand : uint8_t {
51 kPing = 1,
52 kMsg = 3,
53 kLock = 4,
54 kVendorSysInfo = 5,
55 kInit = 6,
56 kWink = 8,
57 kError = 0x3f,
58 };
59
60 // U2FHID error codes
61 enum class U2fHidError : uint8_t {
62 kNone = 0,
63 kInvalidCmd = 1,
64 kInvalidPar = 2,
65 kInvalidLen = 3,
66 kInvalidSeq = 4,
67 kMsgTimeout = 5,
68 kChannelBusy = 6,
69 kLockRequired = 10,
70 kInvalidCid = 11,
71 kOther = 127,
72 };
73
Louis Collardca8d2712019-08-26 17:57:58 +080074 // Create a new virtual U2F HID Device. Does not take ownership of
75 // msg_handler, which must outlive this instance.
Tom Hughes0f7203b2020-08-24 18:29:15 -070076 U2fHid(std::unique_ptr<HidInterface> hid, U2fMessageHandler* msg_handler);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090077 U2fHid(const U2fHid&) = delete;
78 U2fHid& operator=(const U2fHid&) = delete;
79
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020080 ~U2fHid();
81 bool Init();
82
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020083 private:
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020084 // U2FHID protocol commands implementation.
85 void CmdInit(uint32_t cid, const std::string& payload);
86 int CmdLock(std::string* resp);
87 int CmdMsg(std::string* resp);
88 int CmdPing(std::string* resp);
Vincent Palatin828bfe92018-04-05 15:14:44 +020089 int CmdSysInfo(std::string* resp);
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +020090
91 // Fully resets the state of the possibly on-going U2FHID transaction.
92 void ClearTransaction();
93
94 // Sends back a U2FHID report with just the |errcode| error code inside
95 // on channel |cid|.
96 // If |clear| is set, clear the transaction state at the same time.
97 void ReturnError(U2fHidError errcode, uint32_t cid, bool clear);
98
99 // Called when we reach the deadline for the on-going transaction.
100 void TransactionTimeout();
101
102 // Called when we reach the deadline for an unreleased channel lock.
103 void LockTimeout();
104
105 // Sends back a U2FHID report indicating success and carrying the response
106 // payload |resp|.
107 void ReturnResponse(const std::string& resp);
108
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200109 // Executes the action requested by the command contained in the current
110 // transaction.
111 void ExecuteCmd();
112
113 // Parses the HID report contained in |report| and append the content to the
114 // current U2FHID transaction or create a new one.
115 void ProcessReport(const std::string& report);
116
117 std::unique_ptr<HidInterface> hid_;
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200118 uint32_t free_cid_;
119 uint32_t locked_cid_;
120 base::OneShotTimer lock_timeout_;
Louis Collardca8d2712019-08-26 17:57:58 +0800121 U2fMessageHandler* msg_handler_;
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200122
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200123 class HidPacket;
124 class HidMessage;
125 struct Transaction;
126
127 std::unique_ptr<Transaction> transaction_;
Vincent Palatinc6c7e4e2017-06-15 15:45:05 +0200128};
129
130} // namespace u2f
131
132#endif // U2FD_U2FHID_H_