1 /*
2 * Copyright (C) 2017 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
18 #include <vector>
19 #include <gtest/gtest.h>
20
21 #include <ese/ese.h>
22 #include <ese/app/boot.h>
23 #include "../boot_private.h"
24
25 #include "ese_operations_interface.h"
26 #include "ese_operations_wrapper.h"
27
28 using ::testing::Test;
29
30 class FakeTransceive : public EseOperationsInterface {
31 public:
FakeTransceive()32 FakeTransceive() { }
~FakeTransceive()33 virtual ~FakeTransceive() { }
34
EseOpen(struct EseInterface * ese,void * data)35 virtual int EseOpen(struct EseInterface *ese, void *data) {
36 return 0;
37 }
EseHwReceive(struct EseInterface * ese,uint8_t * data,uint32_t len,int complete)38 virtual uint32_t EseHwReceive(struct EseInterface *ese, uint8_t *data,
39 uint32_t len, int complete) { return -1; }
EseHwTransmit(struct EseInterface * ese,const uint8_t * data,uint32_t len,int complete)40 virtual uint32_t EseHwTransmit(struct EseInterface *ese, const uint8_t *data,
41 uint32_t len, int complete) { return -1; }
EseReset(struct EseInterface * ese)42 virtual int EseReset(struct EseInterface *ese) { return -1; }
EsePoll(struct EseInterface * ese,uint8_t poll_for,float timeout,int complete)43 virtual int EsePoll(struct EseInterface *ese, uint8_t poll_for, float timeout, int complete) {
44 return -1;
45 }
EseClose(struct EseInterface * ese)46 virtual void EseClose(struct EseInterface *ese) { }
47
EseTransceive(struct EseInterface * ese,const struct EseSgBuffer * tx_sg,uint32_t tx_nsg,struct EseSgBuffer * rx_sg,uint32_t rx_nsg)48 virtual uint32_t EseTransceive(struct EseInterface *ese, const struct EseSgBuffer *tx_sg, uint32_t tx_nsg,
49 struct EseSgBuffer *rx_sg, uint32_t rx_nsg) {
50 // Get this calls expected data.
51 EXPECT_NE(0UL, invocations.size());
52 if (!invocations.size())
53 return 0;
54 const struct Invocation &invocation = invocations.at(0);
55
56 uint32_t tx_total = ese_sg_length(tx_sg, tx_nsg);
57 EXPECT_EQ(invocation.expected_tx.size(), tx_total);
58 std::vector<uint8_t> incoming(tx_total);
59 ese_sg_to_buf(tx_sg, tx_nsg, 0, tx_total, incoming.data());
60 EXPECT_EQ(0, memcmp(incoming.data(), invocation.expected_tx.data(), tx_total));
61
62 // Supply the golden return data and pop off the invocation.
63 ese_sg_from_buf(rx_sg, rx_nsg, 0, invocation.rx.size(), invocation.rx.data());
64 uint32_t rx_total = invocation.rx.size();
65 invocations.erase(invocations.begin());
66 return rx_total;
67 }
68
69 struct Invocation {
70 std::vector<uint8_t> rx;
71 std::vector<uint8_t> expected_tx;
72 };
73
74 std::vector<Invocation> invocations;
75 };
76
77 class BootAppTest : public virtual Test {
78 public:
BootAppTest()79 BootAppTest() { }
~BootAppTest()80 virtual ~BootAppTest() { }
81
SetUp()82 void SetUp() {
83 // Configure ese with our internal ops.
84 EseOperationsWrapper::InitializeEse(&ese_, &trans_);
85 }
86
TearDown()87 void TearDown() {
88 trans_.invocations.resize(0);
89 }
90
91 protected:
92 FakeTransceive trans_;
93 EseInterface ese_;
94 };
95
TEST_F(BootAppTest,EseBootSessionOpenSuccess)96 TEST_F(BootAppTest, EseBootSessionOpenSuccess) {
97 EXPECT_EQ(0, ese_open(&ese_, NULL));
98 struct EseBootSession session;
99 ese_boot_session_init(&session);
100
101 trans_.invocations.resize(2);
102
103 trans_.invocations[0].expected_tx.resize(kManageChannelOpenLength);
104 memcpy(trans_.invocations[0].expected_tx.data(), kManageChannelOpen,
105 kManageChannelOpenLength);
106 trans_.invocations[0].rx.resize(3);
107 trans_.invocations[0].rx[0] = 0x01; // Channel
108 trans_.invocations[0].rx[1] = 0x90; // Return code
109 trans_.invocations[0].rx[2] = 0x00;
110
111 trans_.invocations[1].expected_tx.resize(kSelectAppletLength);
112 memcpy(trans_.invocations[1].expected_tx.data(), kSelectApplet,
113 kSelectAppletLength);
114 trans_.invocations[1].expected_tx[0] |= 0x01; // Channel
115 trans_.invocations[1].rx.resize(2);
116 trans_.invocations[1].rx[0] = 0x90;
117 trans_.invocations[1].rx[1] = 0x00;
118 EXPECT_EQ(ESE_APP_RESULT_OK, ese_boot_session_open(&ese_, &session));
119 };
120
TEST_F(BootAppTest,EseBootSessionOpenCooldown)121 TEST_F(BootAppTest, EseBootSessionOpenCooldown) {
122 EXPECT_EQ(0, ese_open(&ese_, NULL));
123 struct EseBootSession session;
124 ese_boot_session_init(&session);
125
126 trans_.invocations.resize(1);
127
128 trans_.invocations[0].expected_tx.resize(kManageChannelOpenLength);
129 memcpy(trans_.invocations[0].expected_tx.data(), kManageChannelOpen,
130 kManageChannelOpenLength);
131 trans_.invocations[0].rx.resize(2);
132 trans_.invocations[0].rx[0] = 0x66; // Return code
133 trans_.invocations[0].rx[1] = 0xA5;
134 // This return code should allow a subsequent call of
135 // ese_boot_cooldown_values();
136 EXPECT_EQ(ESE_APP_RESULT_ERROR_COOLDOWN, ese_boot_session_open(&ese_, &session));
137 };
138
TEST_F(BootAppTest,EseBootSessionOpenSelectFailure)139 TEST_F(BootAppTest, EseBootSessionOpenSelectFailure) {
140 EXPECT_EQ(0, ese_open(&ese_, NULL));
141 struct EseBootSession session;
142 ese_boot_session_init(&session);
143
144 trans_.invocations.resize(2);
145
146 trans_.invocations[0].expected_tx.resize(kManageChannelOpenLength);
147 memcpy(trans_.invocations[0].expected_tx.data(), kManageChannelOpen,
148 kManageChannelOpenLength);
149 trans_.invocations[0].rx.resize(3);
150 trans_.invocations[0].rx[0] = 0x01; // Channel
151 trans_.invocations[0].rx[1] = 0x90; // Return code
152 trans_.invocations[0].rx[2] = 0x00;
153
154 trans_.invocations[1].expected_tx.resize(kSelectAppletLength);
155 memcpy(trans_.invocations[1].expected_tx.data(), kSelectApplet,
156 kSelectAppletLength);
157 trans_.invocations[1].expected_tx[0] |= 0x01; // Channel
158 trans_.invocations[1].rx.resize(2);
159 trans_.invocations[1].rx[0] = 0x90;
160 trans_.invocations[1].rx[1] = 0x01;
161 EXPECT_EQ(ESE_APP_RESULT_ERROR_OS, ese_boot_session_open(&ese_, &session));
162 };
163