1 /*
2 **
3 ** Copyright 2020, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 #include "SocketTransport.h"
18
19 #include <arpa/inet.h>
20 #include <errno.h>
21
22 #include <memory>
23 #include <vector>
24
25 #include <aidl/android/hardware/security/keymint/ErrorCode.h>
26 #include <android-base/logging.h>
27 #include <sys/socket.h>
28
29 #include "ITransport.h"
30
31 #define PORT 8080
32 #define IPADDR "192.168.9.112"
33 #define MAX_RECV_BUFFER_SIZE 2500
34
35 namespace keymint::javacard {
36 using ::aidl::android::hardware::security::keymint::ErrorCode;
37 using std::shared_ptr;
38 using std::vector;
39
openConnection()40 keymaster_error_t SocketTransport::openConnection() {
41 struct sockaddr_in serv_addr;
42 if ((mSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
43 LOG(ERROR) << "Socket creation failed"
44 << " Error: " << strerror(errno);
45 return static_cast<keymaster_error_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
46 }
47
48 serv_addr.sin_family = AF_INET;
49 serv_addr.sin_port = htons(PORT);
50
51 // Convert IPv4 and IPv6 addresses from text to binary form
52 if (inet_pton(AF_INET, IPADDR, &serv_addr.sin_addr) <= 0) {
53 LOG(ERROR) << "Invalid address/ Address not supported.";
54 return static_cast<keymaster_error_t>(ErrorCode::HARDWARE_TYPE_UNAVAILABLE);
55 }
56
57 if (connect(mSocket, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
58 close(mSocket);
59 LOG(ERROR) << "Connection failed. Error: " << strerror(errno);
60 return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
61 }
62 socketStatus = true;
63 return KM_ERROR_OK;
64 }
65
sendData(const vector<uint8_t> & inData,vector<uint8_t> & output)66 keymaster_error_t SocketTransport::sendData(const vector<uint8_t>& inData,
67 vector<uint8_t>& output) {
68 int count = 1;
69 while (!socketStatus && count++ < 5) {
70 sleep(1);
71 LOG(ERROR) << "Trying to open socket connection... count: " << count;
72 openConnection();
73 }
74
75 if (count >= 5) {
76 LOG(ERROR) << "Failed to open socket connection";
77 return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
78 }
79 // Prepend the input length to the inputData before sending.
80 vector<uint8_t> inDataPrependedLength;
81 inDataPrependedLength.push_back(static_cast<uint8_t>(inData.size() >> 8));
82 inDataPrependedLength.push_back(static_cast<uint8_t>(inData.size() & 0xFF));
83 inDataPrependedLength.insert(inDataPrependedLength.end(), inData.begin(), inData.end());
84
85 if (0 >
86 send(mSocket, inDataPrependedLength.data(), inDataPrependedLength.size(), MSG_NOSIGNAL)) {
87 static int connectionResetCnt = 0; /* To avoid loop */
88 if ((ECONNRESET == errno || EPIPE == errno) && connectionResetCnt == 0) {
89 // Connection reset. Try open socket and then sendData.
90 socketStatus = false;
91 connectionResetCnt++;
92 return sendData(inData, output);
93 }
94 LOG(ERROR) << "Failed to send data over socket err: " << errno;
95 connectionResetCnt = 0;
96 return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
97 }
98
99 if (!readData(output)) {
100 return KM_ERROR_SECURE_HW_COMMUNICATION_FAILED;
101 }
102 return KM_ERROR_OK;
103 }
104
closeConnection()105 keymaster_error_t SocketTransport::closeConnection() {
106 close(mSocket);
107 socketStatus = false;
108 return KM_ERROR_OK;
109 }
110
isConnected()111 bool SocketTransport::isConnected() {
112 return socketStatus;
113 }
114
readData(vector<uint8_t> & output)115 bool SocketTransport::readData(vector<uint8_t>& output) {
116 uint8_t buffer[MAX_RECV_BUFFER_SIZE];
117 ssize_t expectedResponseLen = 0;
118 ssize_t totalBytesRead = 0;
119 // The first 2 bytes in the response contains the expected response length.
120 do {
121 size_t i = 0;
122 ssize_t numBytes = read(mSocket, buffer, MAX_RECV_BUFFER_SIZE);
123 if (0 > numBytes) {
124 LOG(ERROR) << "Failed to read data from socket.";
125 return false;
126 }
127 totalBytesRead += numBytes;
128 if (expectedResponseLen == 0) {
129 // First two bytes in the response contains the expected response length.
130 expectedResponseLen |= static_cast<ssize_t>(buffer[1] & 0xFF);
131 expectedResponseLen |= static_cast<ssize_t>((buffer[0] << 8) & 0xFF00);
132 // 2 bytes for storing the length.
133 expectedResponseLen += 2;
134 i = 2;
135 }
136 for (; i < numBytes; i++) {
137 output.push_back(buffer[i]);
138 }
139 } while (totalBytesRead < expectedResponseLen);
140
141 return true;
142 }
143
144 } // namespace keymint::javacard
145