1  /*
2   * Copyright 2019, The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *     http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #pragma once
18  
19  #include <stdint.h>
20  #include <teeui/utils.h>
21  
22  #include <memory>
23  #include <tuple>
24  
25  #include <teeui/common_message_types.h>
26  #include <teeui/generic_messages.h>
27  
28  namespace secure_input {
29  
30  enum class DTupKeyEvent : uint32_t { RESERVED = 0, VOL_DOWN = 114, VOL_UP = 115, PWR = 116 };
31  
32  enum class InputResponse : uint32_t {
33      OK,
34      PENDING_MORE,
35      TIMED_OUT,
36  };
37  
38  enum class SecureInputCommand : uint32_t {
39      Invalid,
40      InputHandshake,
41      FinalizeInputSession,
42      DeliverInputEvent,
43  };
44  
45  static constexpr const ::teeui::Protocol kSecureInputProto = 1;
46  
47  #define DECLARE_SECURE_INPUT_COMMAND(cmd)                                                          \
48      using Cmd##cmd = ::teeui::Cmd<kSecureInputProto, SecureInputCommand, SecureInputCommand::cmd>
49  
50  DECLARE_SECURE_INPUT_COMMAND(InputHandshake);
51  DECLARE_SECURE_INPUT_COMMAND(FinalizeInputSession);
52  DECLARE_SECURE_INPUT_COMMAND(DeliverInputEvent);
53  
54  constexpr size_t kNonceBytes = 32;
55  constexpr size_t kSignatureBytes = 32;
56  constexpr char kConfirmationUIHandshakeLabel[] = "DTup input handshake";
57  constexpr char kConfirmationUIEventLabel[] = "DTup input event";
58  using Nonce = teeui::Array<uint8_t, kNonceBytes>;
59  using Signature = teeui::Array<uint8_t, kSignatureBytes>;
60  
61  constexpr const uint64_t kUserPreInputGracePeriodMillis = 750;
62  constexpr const uint64_t kUserDoupleClickTimeoutMillis = 350;
63  
64  using InputHandshake = teeui::Message<CmdInputHandshake>;
65  using InputHandshakeResponse = teeui::Message<teeui::ResponseCode, Nonce>;
66  
67  /*
68   * This command delivers the nonce Nci and the HMAC signature over
69   * kConfirmationUIHandshakeLabel||Nco||Nci to the TA.
70   * Note the terminating 0 of the label does NOT go into the signature.
71   * Command::Vendor, TrustyCommand::FinalizeInputSession, Nci, <signature>.
72   */
73  using FinalizeInputSessionHandshake = teeui::Message<CmdFinalizeInputSession, Nonce, Signature>;
74  using FinalizeInputSessionHandshakeResponse = teeui::Message<teeui::ResponseCode>;
75  
76  /*
77   * This command delivers an input event to the TA.
78   * Command::Vendor, TrustyCommand::DeliverInputEvent, <key event>,
79   * signature over kConfirmationUIEventLabel||<key event>||Nci.
80   * Note the terminating 0 of the label does NOT go into the signature.
81   */
82  using DeliverInputEvent = teeui::Message<CmdDeliverInputEvent, DTupKeyEvent, Nonce>;
83  using DeliverInputEventResponse = teeui::Message<teeui::ResponseCode, InputResponse>;
84  
85  // Input Event
read(teeui::Message<DTupKeyEvent>,teeui::ReadStream in)86  inline std::tuple<teeui::ReadStream, DTupKeyEvent> read(teeui::Message<DTupKeyEvent>,
87                                                          teeui::ReadStream in) {
88      return teeui::readSimpleType<DTupKeyEvent>(in);
89  }
write(teeui::WriteStream out,const DTupKeyEvent & v)90  inline teeui::WriteStream write(teeui::WriteStream out, const DTupKeyEvent& v) {
91      return write(out, teeui::bytesCast(v));
92  }
93  
94  // InputResponse
read(teeui::Message<InputResponse>,teeui::ReadStream in)95  inline std::tuple<teeui::ReadStream, InputResponse> read(teeui::Message<InputResponse>,
96                                                           teeui::ReadStream in) {
97      return teeui::readSimpleType<InputResponse>(in);
98  }
write(teeui::WriteStream out,const InputResponse & v)99  inline teeui::WriteStream write(teeui::WriteStream out, const InputResponse& v) {
100      return write(out, teeui::bytesCast(v));
101  }
102  
103  }  // namespace secure_input
104