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