1e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis/*
2e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * Copyright (C) 2018 The Android Open Source Project
3e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis *
4e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * Licensed under the Apache License, Version 2.0 (the "License");
5e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * you may not use this file except in compliance with the License.
6e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * You may obtain a copy of the License at
7e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis *
8e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis *      http://www.apache.org/licenses/LICENSE-2.0
9e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis *
10e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * Unless required by applicable law or agreed to in writing, software
11e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * distributed under the License is distributed on an "AS IS" BASIS,
12e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * See the License for the specific language governing permissions and
14e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis * limitations under the License.
15e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis */
16e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
17e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#define LOG_TAG "ConfirmationIOHidlHalTest"
18e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <cutils/log.h>
19e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
20e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <algorithm>
21e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <iostream>
22e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <memory>
23e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
24e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <android/hardware/confirmationui/1.0/IConfirmationResultCallback.h>
25e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <android/hardware/confirmationui/1.0/IConfirmationUI.h>
26e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <android/hardware/confirmationui/1.0/types.h>
27e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <android/hardware/confirmationui/support/confirmationui_utils.h>
28e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
29e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <VtsHalHidlTargetCallbackBase.h>
30e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <VtsHalHidlTargetTestBase.h>
31e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
32e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <openssl/hmac.h>
33e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <openssl/sha.h>
34e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
35e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#include <cn-cbor/cn-cbor.h>
36e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
37e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisusing ::android::sp;
38e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
39e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisusing ::std::string;
40e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
41e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace android {
42e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace hardware {
43e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
44e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace confirmationui {
45e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace V1_0 {
46e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
47e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace test {
48e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisnamespace {
49fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskisconst support::auth_token_key_t testKey(static_cast<uint8_t>(TestKeyBits::BYTE));
50fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis
51e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisclass HMacImplementation {
52e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   public:
53fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis    static support::NullOr<support::hmac_t> hmac256(
54fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis        const support::auth_token_key_t& key,
55fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis        std::initializer_list<support::ByteBufferProxy> buffers) {
56e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        HMAC_CTX hmacCtx;
57e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        HMAC_CTX_init(&hmacCtx);
58fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis        if (!HMAC_Init_ex(&hmacCtx, key.data(), key.size(), EVP_sha256(), nullptr)) {
59e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            return {};
60e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        }
61e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        for (auto& buffer : buffers) {
62e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            if (!HMAC_Update(&hmacCtx, buffer.data(), buffer.size())) {
63e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                return {};
64e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            }
65e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        }
66fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis        support::hmac_t result;
67e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        if (!HMAC_Final(&hmacCtx, result.data(), nullptr)) {
68e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            return {};
69e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        }
70e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        return result;
71e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
72e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
73e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
74e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisusing HMacer = support::HMac<HMacImplementation>;
75e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
76e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskistemplate <typename... Data>
77e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskishidl_vec<uint8_t> testHMAC(const Data&... data) {
78e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto hmac = HMacer::hmac256(testKey, data...);
79e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    if (!hmac.isOk()) {
80e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        EXPECT_TRUE(false) << "Failed to compute test hmac.  This is a self-test error.";
81e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        return {};
82e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
83fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis    hidl_vec<uint8_t> result(hmac.value().size());
84fe584fb317bc7e22d88c97629679a875ee5d9433Janis Danisevskis    copy(hmac.value().data(), hmac.value().data() + hmac.value().size(), result.data());
85e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return result;
86e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
87e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
88e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisusing ::android::hardware::keymaster::V4_0::HardwareAuthToken;
89e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisusing ::android::hardware::keymaster::V4_0::HardwareAuthenticatorType;
90e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
91e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskistemplate <typename T>
92e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisauto toBytes(const T& v) -> const uint8_t (&)[sizeof(T)] {
93e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return *reinterpret_cast<const uint8_t(*)[sizeof(T)]>(&v);
94e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
95e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
96e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisHardwareAuthToken makeTestToken(const TestModeCommands command, uint64_t timestamp = 0) {
97e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    HardwareAuthToken auth_token;
98e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.challenge = static_cast<uint64_t>(command);
99e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.userId = 0;
100e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.authenticatorId = 0;
101e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.authenticatorType = HardwareAuthenticatorType::NONE;
102e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.timestamp = timestamp;
103e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
104e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // Canonical form  of auth-token v0
105e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // version (1 byte)
106e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // challenge (8 bytes)
107e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // user_id (8 bytes)
108e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // authenticator_id (8 bytes)
109e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // authenticator_type (4 bytes)
110e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // timestamp (8 bytes)
111e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // total 37 bytes
112e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auth_token.mac = testHMAC("\0",
113e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                              toBytes(auth_token.challenge),                         //
114e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                              toBytes(auth_token.userId),                            //
115e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                              toBytes(auth_token.authenticatorId),                   //
116e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                              toBytes(support::hton(auth_token.authenticatorType)),  //
117e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                              toBytes(support::hton(auth_token.timestamp)));         //
118e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
119e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return auth_token;
120e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
121e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
122e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#define DEBUG_CONFRIMATIONUI_UTILS_TEST
123e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
124e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
125e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisstd::ostream& hexdump(std::ostream& out, const uint8_t* data, size_t size) {
126e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    for (size_t i = 0; i < size; ++i) {
127e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        uint8_t byte = data[i];
128e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        out << std::hex << std::setw(2) << std::setfill('0') << (unsigned)byte;
129e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        switch (i & 0xf) {
130e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            case 0xf:
131e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                out << "\n";
132e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                break;
133e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            case 7:
134e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                out << "  ";
135e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                break;
136e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            default:
137e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                out << " ";
138e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                break;
139e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        }
140e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
141e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return out;
142e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
143e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#endif
144e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
145e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisconstexpr char hex_value[256] = {0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
146e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
147e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
148e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 1,  2,  3,  4,  5,  6,  7, 8, 9, 0, 0, 0, 0, 0, 0,  // '0'..'9'
149e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 'A'..'F'
150e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
151e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 'a'..'f'
152e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
153e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
154e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
155e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
156e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
157e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
158e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
159e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0,  //
160e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0};
161e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
162e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisstd::string hex2str(std::string a) {
163e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    std::string b;
164e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    size_t num = a.size() / 2;
165e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    b.resize(num);
166e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    for (size_t i = 0; i < num; i++) {
167e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
168e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
169e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return b;
170e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
171e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
172e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace
173e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
174e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisclass ConfirmationArgs {
175e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   public:
176e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ResponseCode error_;
177e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> formattedMessage_;
178e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> confirmationToken_;
179e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    bool verifyConfirmationToken() {
180e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        static constexpr char confirmationPrefix[] = "confirmation token";
181e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        EXPECT_EQ(32U, confirmationToken_.size());
182e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        return 32U == confirmationToken_.size() &&
183e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis               !memcmp(confirmationToken_.data(),
184e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                       testHMAC(confirmationPrefix, formattedMessage_).data(), 32);
185e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
186e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
187e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
188e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisclass ConfirmationTestCallback : public ::testing::VtsHalHidlTargetCallbackBase<ConfirmationArgs>,
189e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 public IConfirmationResultCallback {
190e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   public:
191e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    Return<void> result(ResponseCode error, const hidl_vec<uint8_t>& formattedMessage,
192e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                        const hidl_vec<uint8_t>& confirmationToken) override {
193e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        ConfirmationArgs args;
194e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        args.error_ = error;
195e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        args.formattedMessage_ = formattedMessage;
196e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        args.confirmationToken_ = confirmationToken;
197e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        NotifyFromCallback(args);
198e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        return Void();
199e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
200e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
201e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
202e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisclass ConfirmationUIHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
203e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   public:
204e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // get the test environment singleton
205e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static ConfirmationUIHidlEnvironment* Instance() {
206e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        static ConfirmationUIHidlEnvironment* instance = new ConfirmationUIHidlEnvironment;
207e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        return instance;
208e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
209e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
210e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    void registerTestServices() override { registerTestService<IConfirmationUI>(); }
211e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
212e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   private:
213e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ConfirmationUIHidlEnvironment(){};
214e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
215e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    GTEST_DISALLOW_COPY_AND_ASSIGN_(ConfirmationUIHidlEnvironment);
216e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
217e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
218e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisclass ConfirmationUIHidlTest : public ::testing::VtsHalHidlTargetTestBase {
219e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   public:
220e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    void TearDown() override { confirmator().abort(); }
221e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
222e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static void SetUpTestCase() {
223e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        string service_name =
224e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis            ConfirmationUIHidlEnvironment::Instance()->getServiceName<IConfirmationUI>();
225e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        confirmator_ = IConfirmationUI::getService(service_name);
226e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        ASSERT_NE(nullptr, confirmator_.get());
227e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
228e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
229e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static void TearDownTestCase() { confirmator_.clear(); }
230e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
231e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static IConfirmationUI& confirmator() { return *confirmator_; }
232e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
233e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis   private:
234e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static sp<IConfirmationUI> confirmator_;
235e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
236e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
237e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskissp<IConfirmationUI> ConfirmationUIHidlTest::confirmator_;
238e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
239e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#define ASSERT_HAL_CALL(expected, call)                               \
240e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    {                                                                 \
241e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        auto result = call;                                           \
242e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        ASSERT_TRUE(result.isOk());                                   \
243e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        ASSERT_EQ(expected, static_cast<decltype(expected)>(result)); \
244e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    }
245e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
246e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisstruct CnCborDeleter {
247e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    void operator()(cn_cbor* ptr) { cn_cbor_free(ptr); }
248e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis};
249e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
250e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskistypedef std::unique_ptr<cn_cbor, CnCborDeleter> CnCborPtr;
251e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
252e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Simulates the User taping Ok
253e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, UserOkTest) {
254e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = "Me first, gimme gimme!";
255e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
256e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
257e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
258e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
259e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::OK,
260e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
261e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
262e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::OK, confirmator().deliverSecureInputEvent(
263e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                          makeTestToken(TestModeCommands::OK_EVENT)));
264e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
265e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto result = conf_cb->WaitForCallback();
266e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(ResponseCode::OK, result.args->error_);
267e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
268e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_TRUE(result.args->verifyConfirmationToken());
269e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
270e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    cn_cbor_errback cn_cbor_error;
271e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto parsed_message =
272e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis        CnCborPtr(cn_cbor_decode(result.args->formattedMessage_.data(),
273e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                 result.args->formattedMessage_.size(), &cn_cbor_error));
274e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // is parsable CBOR
275e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_TRUE(parsed_message.get());
276e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // is a map
277e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(CN_CBOR_MAP, parsed_message->type);
278e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
279e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // the message must have exactly 2 key value pairs.
280e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // cn_cbor holds 2*<no_of_pairs> in the length field
281e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(4, parsed_message->length);
282e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // map has key "prompt"
283e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto prompt = cn_cbor_mapget_string(parsed_message.get(), "prompt");
284e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_TRUE(prompt);
285e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(CN_CBOR_TEXT, prompt->type);
286e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(22, prompt->length);
287e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0, memcmp(test_prompt, prompt->v.str, 22));
288e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    // map has key "extra"
289e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto extra_out = cn_cbor_mapget_string(parsed_message.get(), "extra");
290e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_TRUE(extra_out);
291e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(CN_CBOR_BYTES, extra_out->type);
292e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(3, extra_out->length);
293e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0, memcmp(test_extra, extra_out->v.bytes, 3));
294e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
295e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
296e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Initiates a confirmation prompt with a message that is too long
297e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, MessageTooLongTest) {
298e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[static_cast<uint32_t>(MessageSize::MAX)] = {};
299e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = "D\'oh!";
300e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
301e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
302e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
303e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::UIErrorMessageTooLong,
304e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
305e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
306e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
307e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// If the message gets very long some HAL implementations might fail even before the message
308e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// reaches the trusted app implementation. But the HAL must still diagnose the correct error.
309e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, MessageWayTooLongTest) {
310e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[static_cast<uint32_t>(MessageSize::MAX) * 10] = {};
311e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = "D\'oh!";
312e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
313e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
314e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + sizeof(test_extra));
315e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::UIErrorMessageTooLong,
316e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
317e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
318e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
319e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Simulates the User tapping the Cancel
320e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, UserCancelTest) {
321e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = "Me first, gimme gimme!";
322e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
323e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
324e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
325e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
326e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::OK,
327e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
328e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
329e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::OK, confirmator().deliverSecureInputEvent(
330e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                          makeTestToken(TestModeCommands::CANCEL_EVENT)));
331e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
332e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto result = conf_cb->WaitForCallback();
333e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(ResponseCode::Canceled, result.args->error_);
334e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
335e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0U, result.args->confirmationToken_.size());
336e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0U, result.args->formattedMessage_.size());
337e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
338e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
339e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Simulates the framework candelling an ongoing prompt
340e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, AbortTest) {
341e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = "Me first, gimme gimme!";
342e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
343e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
344e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
345e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
346e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::OK,
347e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
348e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
349e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    confirmator().abort();
350e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
351e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto result = conf_cb->WaitForCallback();
352e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(ResponseCode::Aborted, result.args->error_);
353e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0U, result.args->confirmationToken_.size());
354e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(0U, result.args->formattedMessage_.size());
355e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
356e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
357e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Passing malformed UTF-8 to the confirmation UI
358e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// This test passes a string that ends in the middle of a multibyte character
359e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, MalformedUTF8Test1) {
360e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = {char(0xc0), 0};
361e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
362e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
363e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
364e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
365e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
366e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
367e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
368e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
369e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Passing malformed UTF-8 to the confirmation UI
370e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// This test passes a string with a 5-byte character.
371e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, MalformedUTF8Test2) {
372e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = {char(0xf8), char(0x82), char(0x82),
373e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                                           char(0x82), char(0x82), 0};
374e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
375e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
376e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
377e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
378e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
379e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
380e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
381e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
382e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Passing malformed UTF-8 to the confirmation UI
383e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// This test passes a string with a 2-byte character followed by a stray non UTF-8 character.
384e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST_F(ConfirmationUIHidlTest, MalformedUTF8Test3) {
385e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr char test_prompt[] = {char(0xc0), char(0x82), char(0x83), 0};
386e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    static constexpr uint8_t test_extra[] = {0x1, 0x2, 0x3};
387e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    sp<ConfirmationTestCallback> conf_cb = new ConfirmationTestCallback;
388e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_string prompt_text(test_prompt);
389e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hidl_vec<uint8_t> extra(test_extra, test_extra + 3);
390e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_HAL_CALL(ResponseCode::UIErrorMalformedUTF8Encoding,
391e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis                    confirmator().promptUserConfirmation(conf_cb, prompt_text, extra, "en", {}));
392e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
393e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
394e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis// Test the implementation of HMAC SHA 256 against a golden blob.
395e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis DanisevskisTEST(ConfirmationUITestSelfTest, HMAC256SelfTest) {
396e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    const char key_str[32] = "keykeykeykeykeykeykeykeykeykeyk";
397e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    const uint8_t(&key)[32] = *reinterpret_cast<const uint8_t(*)[32]>(key_str);
398e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto expected = hex2str("2377fbcaa7fb3f6c20cfa1d9ebc60e9922cf58c909e25e300f3cb57f7805c886");
399e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    auto result = HMacer::hmac256(key, "value1", "value2", "value3");
400e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
401e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#ifdef DEBUG_CONFRIMATIONUI_UTILS_TEST
402e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hexdump(std::cout, reinterpret_cast<const uint8_t*>(expected.data()), 32) << std::endl;
403e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    hexdump(std::cout, result.value().data(), 32) << std::endl;
404e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis#endif
405e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
406e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    support::ByteBufferProxy expected_bytes(expected);
407e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_TRUE(result.isOk());
408e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ASSERT_EQ(expected, result.value());
409e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
410e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
411e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace test
412e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace V1_0
413e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace confirmationui
414e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace hardware
415e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}  // namespace android
416e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis
417e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskisint main(int argc, char** argv) {
418e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ::testing::InitGoogleTest(&argc, argv);
419e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    std::vector<std::string> positional_args;
420e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    int status = RUN_ALL_TESTS();
421e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    ALOGI("Test result = %d", status);
422e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis    return status;
423e0b1903d80ba92e0438e34111a55ec6bdb61fdfeJanis Danisevskis}
424