• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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