1 /*
2 *
3 * Copyright (C) 2017 GlobalLogic
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
18 #include <cstring>
19
20 #define LOG_TAG "OpteeIPC"
21 #include <utils/Log.h>
22
23 #include <gatekeeper_ipc.h>
24 #include "optee_ipc.h"
25
26 #undef LOG_TAG
27 #define LOG_TAG "OpteeGatekeeper"
28
29 namespace android {
30 namespace hardware {
31 namespace gatekeeper {
32 namespace V1_0 {
33 namespace optee {
34
OpteeIPC()35 OpteeIPC::OpteeIPC()
36 : inUse(false)
37 {
38 }
39
~OpteeIPC()40 OpteeIPC::~OpteeIPC()
41 {
42 disconnect();
43 finalize();
44 }
45
initialize()46 bool OpteeIPC::initialize()
47 {
48 TEEC_Result res;
49
50 res = TEEC_InitializeContext(NULL, &ctx);
51 if (res != TEEC_SUCCESS) {
52 ALOGE("TEEC_InitializeContext failed with code 0x%x", res);
53 return false;
54 }
55
56 return true;
57 }
58
connect(const TEEC_UUID & uuid)59 bool OpteeIPC::connect(const TEEC_UUID& uuid)
60 {
61 if (inUse) {
62 ALOGE("Is already connected");
63
64 return false;
65 }
66
67 TEEC_Result res;
68
69 uint32_t err_origin;
70 res = TEEC_OpenSession(&ctx, &sess, &uuid, TEEC_LOGIN_PUBLIC,
71 NULL, NULL, &err_origin);
72 if (res != TEEC_SUCCESS) {
73 ALOGE("TEEC_Opensession failed with code 0x%x origin 0x%x",
74 res, err_origin);
75
76 return false;
77 }
78
79 inUse = true;
80
81 return true;
82 }
83
finalize()84 void OpteeIPC::finalize()
85 {
86 TEEC_FinalizeContext(&ctx);
87 }
88
disconnect()89 void OpteeIPC::disconnect()
90 {
91 if (inUse) {
92 TEEC_CloseSession(&sess);
93 }
94
95 inUse = false;
96 }
97
call(uint32_t cmd,const uint8_t * in,uint32_t in_size,uint8_t * out,uint32_t & out_size)98 bool OpteeIPC::call(uint32_t cmd,
99 const uint8_t *in, uint32_t in_size,
100 uint8_t *out, uint32_t& out_size)
101 {
102 TEEC_Operation op;
103 memset(&op, 0, sizeof(op));
104
105 op.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
106 TEEC_MEMREF_TEMP_OUTPUT,
107 TEEC_NONE, TEEC_NONE);
108
109 op.params[0].tmpref.buffer = (void*)in;
110 op.params[0].tmpref.size = in_size;
111
112 op.params[1].tmpref.buffer = out;
113 op.params[1].tmpref.size = out_size;
114
115 uint32_t err_origin;
116 TEEC_Result res = TEEC_InvokeCommand(&sess, cmd, &op, &err_origin);
117 if (res != TEEC_SUCCESS) {
118 ALOGE("TEEC_InvokeCommand failed with code 0x%08x origin 0x%08x",
119 res, err_origin);
120 if (res == TEEC_ERROR_TARGET_DEAD) {
121 disconnect();
122 connect(TA_GATEKEEPER_UUID);
123 }
124 return false;
125 }
126
127 return true;
128 }
129
130 } // namespace optee
131 } // namespace V1_0
132 } // namespace gatekeeper
133 } // namespace hardware
134 } // namespace android
135