xref: /aosp_15_r20/external/libese/esed/Weaver.cpp (revision 5c4dab75aa57366379dce576b1a9e082a44e2b3a)
1*5c4dab75SAndroid Build Coastguard Worker /*
2*5c4dab75SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*5c4dab75SAndroid Build Coastguard Worker  *
4*5c4dab75SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*5c4dab75SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*5c4dab75SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*5c4dab75SAndroid Build Coastguard Worker  *
8*5c4dab75SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*5c4dab75SAndroid Build Coastguard Worker  *
10*5c4dab75SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*5c4dab75SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*5c4dab75SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5c4dab75SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*5c4dab75SAndroid Build Coastguard Worker  * limitations under the License.
15*5c4dab75SAndroid Build Coastguard Worker  */
16*5c4dab75SAndroid Build Coastguard Worker 
17*5c4dab75SAndroid Build Coastguard Worker #include "Weaver.h"
18*5c4dab75SAndroid Build Coastguard Worker 
19*5c4dab75SAndroid Build Coastguard Worker #include <algorithm>
20*5c4dab75SAndroid Build Coastguard Worker #include <tuple>
21*5c4dab75SAndroid Build Coastguard Worker 
22*5c4dab75SAndroid Build Coastguard Worker #include <android-base/logging.h>
23*5c4dab75SAndroid Build Coastguard Worker 
24*5c4dab75SAndroid Build Coastguard Worker #include <ese/app/weaver.h>
25*5c4dab75SAndroid Build Coastguard Worker #include "ScopedEseConnection.h"
26*5c4dab75SAndroid Build Coastguard Worker 
27*5c4dab75SAndroid Build Coastguard Worker namespace android {
28*5c4dab75SAndroid Build Coastguard Worker namespace esed {
29*5c4dab75SAndroid Build Coastguard Worker 
30*5c4dab75SAndroid Build Coastguard Worker // libhidl
31*5c4dab75SAndroid Build Coastguard Worker using ::android::hardware::Void;
32*5c4dab75SAndroid Build Coastguard Worker 
33*5c4dab75SAndroid Build Coastguard Worker // HAL
34*5c4dab75SAndroid Build Coastguard Worker using ::android::hardware::weaver::V1_0::WeaverConfig;
35*5c4dab75SAndroid Build Coastguard Worker using ::android::hardware::weaver::V1_0::WeaverReadResponse;
36*5c4dab75SAndroid Build Coastguard Worker using ::android::hardware::weaver::V1_0::WeaverReadStatus;
37*5c4dab75SAndroid Build Coastguard Worker 
38*5c4dab75SAndroid Build Coastguard Worker // Methods from ::android::hardware::weaver::V1_0::IWeaver follow.
getConfig(getConfig_cb _hidl_cb)39*5c4dab75SAndroid Build Coastguard Worker Return<void> Weaver::getConfig(getConfig_cb _hidl_cb) {
40*5c4dab75SAndroid Build Coastguard Worker     LOG(VERBOSE) << "Running Weaver::getNumSlots";
41*5c4dab75SAndroid Build Coastguard Worker     // Open SE session for applet
42*5c4dab75SAndroid Build Coastguard Worker     ScopedEseConnection ese{mEse};
43*5c4dab75SAndroid Build Coastguard Worker     ese.init();
44*5c4dab75SAndroid Build Coastguard Worker     EseWeaverSession ws;
45*5c4dab75SAndroid Build Coastguard Worker     ese_weaver_session_init(&ws);
46*5c4dab75SAndroid Build Coastguard Worker     EseAppResult res = ese_weaver_session_open(mEse.ese_interface(), &ws);
47*5c4dab75SAndroid Build Coastguard Worker     if (EseAppResultValue(res) == ESE_APP_RESULT_ERROR_OS) {
48*5c4dab75SAndroid Build Coastguard Worker         switch (EseAppResultAppValue(res)) {
49*5c4dab75SAndroid Build Coastguard Worker         case 0x6999: // SW_APPLET_SELECT_FAILED
50*5c4dab75SAndroid Build Coastguard Worker         case 0x6A82: // SW_FILE_NOT_FOUND
51*5c4dab75SAndroid Build Coastguard Worker             // No applet means no Weaver storage. Report no slots to prompt
52*5c4dab75SAndroid Build Coastguard Worker             // fallback to software mode.
53*5c4dab75SAndroid Build Coastguard Worker             _hidl_cb(WeaverStatus::OK, WeaverConfig{0, 0, 0});
54*5c4dab75SAndroid Build Coastguard Worker             return Void();
55*5c4dab75SAndroid Build Coastguard Worker         }
56*5c4dab75SAndroid Build Coastguard Worker     } else if (res != ESE_APP_RESULT_OK) {
57*5c4dab75SAndroid Build Coastguard Worker         // Transient error
58*5c4dab75SAndroid Build Coastguard Worker         _hidl_cb(WeaverStatus::FAILED, WeaverConfig{});
59*5c4dab75SAndroid Build Coastguard Worker         return Void();
60*5c4dab75SAndroid Build Coastguard Worker     }
61*5c4dab75SAndroid Build Coastguard Worker 
62*5c4dab75SAndroid Build Coastguard Worker     // Call the applet
63*5c4dab75SAndroid Build Coastguard Worker     uint32_t numSlots;
64*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_get_num_slots(&ws, &numSlots) != ESE_APP_RESULT_OK) {
65*5c4dab75SAndroid Build Coastguard Worker         _hidl_cb(WeaverStatus::FAILED, WeaverConfig{});
66*5c4dab75SAndroid Build Coastguard Worker         return Void();
67*5c4dab75SAndroid Build Coastguard Worker     }
68*5c4dab75SAndroid Build Coastguard Worker 
69*5c4dab75SAndroid Build Coastguard Worker     // Try and close the session
70*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
71*5c4dab75SAndroid Build Coastguard Worker         LOG(WARNING) << "Failed to close Weaver session";
72*5c4dab75SAndroid Build Coastguard Worker     }
73*5c4dab75SAndroid Build Coastguard Worker 
74*5c4dab75SAndroid Build Coastguard Worker     _hidl_cb(WeaverStatus::OK, WeaverConfig{numSlots, kEseWeaverKeySize, kEseWeaverValueSize});
75*5c4dab75SAndroid Build Coastguard Worker     return Void();
76*5c4dab75SAndroid Build Coastguard Worker }
77*5c4dab75SAndroid Build Coastguard Worker 
write(uint32_t slotId,const hidl_vec<uint8_t> & key,const hidl_vec<uint8_t> & value)78*5c4dab75SAndroid Build Coastguard Worker Return<WeaverStatus> Weaver::write(uint32_t slotId, const hidl_vec<uint8_t>& key,
79*5c4dab75SAndroid Build Coastguard Worker                            const hidl_vec<uint8_t>& value) {
80*5c4dab75SAndroid Build Coastguard Worker     LOG(INFO) << "Running Weaver::write on slot " << slotId;
81*5c4dab75SAndroid Build Coastguard Worker     ScopedEseConnection ese{mEse};
82*5c4dab75SAndroid Build Coastguard Worker     ese.init();
83*5c4dab75SAndroid Build Coastguard Worker     // Validate the key and value sizes
84*5c4dab75SAndroid Build Coastguard Worker     if (key.size() != kEseWeaverKeySize) {
85*5c4dab75SAndroid Build Coastguard Worker         LOG(ERROR) << "Key size must be " << kEseWeaverKeySize << ", not" << key.size() << " bytes";
86*5c4dab75SAndroid Build Coastguard Worker         return WeaverStatus::FAILED;
87*5c4dab75SAndroid Build Coastguard Worker     }
88*5c4dab75SAndroid Build Coastguard Worker     if (value.size() != kEseWeaverValueSize) {
89*5c4dab75SAndroid Build Coastguard Worker         LOG(ERROR) << "Value size must be " << kEseWeaverValueSize << ", not" << value.size()
90*5c4dab75SAndroid Build Coastguard Worker                    << " bytes";
91*5c4dab75SAndroid Build Coastguard Worker         return WeaverStatus::FAILED;
92*5c4dab75SAndroid Build Coastguard Worker     }
93*5c4dab75SAndroid Build Coastguard Worker 
94*5c4dab75SAndroid Build Coastguard Worker     // Open SE session for applet
95*5c4dab75SAndroid Build Coastguard Worker     EseWeaverSession ws;
96*5c4dab75SAndroid Build Coastguard Worker     ese_weaver_session_init(&ws);
97*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_session_open(mEse.ese_interface(), &ws) != ESE_APP_RESULT_OK) {
98*5c4dab75SAndroid Build Coastguard Worker         return WeaverStatus::FAILED;
99*5c4dab75SAndroid Build Coastguard Worker     }
100*5c4dab75SAndroid Build Coastguard Worker 
101*5c4dab75SAndroid Build Coastguard Worker     // Call the applet
102*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_write(&ws, slotId, key.data(), value.data()) != ESE_APP_RESULT_OK) {
103*5c4dab75SAndroid Build Coastguard Worker         return WeaverStatus::FAILED;
104*5c4dab75SAndroid Build Coastguard Worker     }
105*5c4dab75SAndroid Build Coastguard Worker 
106*5c4dab75SAndroid Build Coastguard Worker     // Try and close the session
107*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
108*5c4dab75SAndroid Build Coastguard Worker         LOG(WARNING) << "Failed to close Weaver session";
109*5c4dab75SAndroid Build Coastguard Worker     }
110*5c4dab75SAndroid Build Coastguard Worker 
111*5c4dab75SAndroid Build Coastguard Worker     return WeaverStatus::OK;
112*5c4dab75SAndroid Build Coastguard Worker }
113*5c4dab75SAndroid Build Coastguard Worker 
read(uint32_t slotId,const hidl_vec<uint8_t> & key,read_cb _hidl_cb)114*5c4dab75SAndroid Build Coastguard Worker Return<void> Weaver::read(uint32_t slotId, const hidl_vec<uint8_t>& key, read_cb _hidl_cb) {
115*5c4dab75SAndroid Build Coastguard Worker     LOG(VERBOSE) << "Running Weaver::read on slot " << slotId;
116*5c4dab75SAndroid Build Coastguard Worker 
117*5c4dab75SAndroid Build Coastguard Worker     // Validate the key size
118*5c4dab75SAndroid Build Coastguard Worker     if (key.size() != kEseWeaverKeySize) {
119*5c4dab75SAndroid Build Coastguard Worker         LOG(ERROR) << "Key size must be " << kEseWeaverKeySize << ", not" << key.size() << " bytes";
120*5c4dab75SAndroid Build Coastguard Worker         _hidl_cb(WeaverReadStatus::FAILED, WeaverReadResponse{});
121*5c4dab75SAndroid Build Coastguard Worker         return Void();
122*5c4dab75SAndroid Build Coastguard Worker     }
123*5c4dab75SAndroid Build Coastguard Worker 
124*5c4dab75SAndroid Build Coastguard Worker     // Open SE session for applet
125*5c4dab75SAndroid Build Coastguard Worker     ScopedEseConnection ese{mEse};
126*5c4dab75SAndroid Build Coastguard Worker     ese.init();
127*5c4dab75SAndroid Build Coastguard Worker     EseWeaverSession ws;
128*5c4dab75SAndroid Build Coastguard Worker     ese_weaver_session_init(&ws);
129*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_session_open(mEse.ese_interface(), &ws) != ESE_APP_RESULT_OK) {
130*5c4dab75SAndroid Build Coastguard Worker         _hidl_cb(WeaverReadStatus::FAILED, WeaverReadResponse{});
131*5c4dab75SAndroid Build Coastguard Worker         return Void();
132*5c4dab75SAndroid Build Coastguard Worker     }
133*5c4dab75SAndroid Build Coastguard Worker 
134*5c4dab75SAndroid Build Coastguard Worker     // Call the applet
135*5c4dab75SAndroid Build Coastguard Worker     hidl_vec<uint8_t> value;
136*5c4dab75SAndroid Build Coastguard Worker     value.resize(kEseWeaverValueSize);
137*5c4dab75SAndroid Build Coastguard Worker     uint32_t timeout;
138*5c4dab75SAndroid Build Coastguard Worker     const int res = ese_weaver_read(&ws, slotId, key.data(), value.data(), &timeout);
139*5c4dab75SAndroid Build Coastguard Worker     WeaverReadStatus status;
140*5c4dab75SAndroid Build Coastguard Worker     switch (res) {
141*5c4dab75SAndroid Build Coastguard Worker         case ESE_APP_RESULT_OK:
142*5c4dab75SAndroid Build Coastguard Worker             status = WeaverReadStatus::OK;
143*5c4dab75SAndroid Build Coastguard Worker             timeout = 0;
144*5c4dab75SAndroid Build Coastguard Worker             break;
145*5c4dab75SAndroid Build Coastguard Worker         case ESE_WEAVER_READ_WRONG_KEY:
146*5c4dab75SAndroid Build Coastguard Worker             status = WeaverReadStatus::INCORRECT_KEY;
147*5c4dab75SAndroid Build Coastguard Worker             value.resize(0);
148*5c4dab75SAndroid Build Coastguard Worker             break;
149*5c4dab75SAndroid Build Coastguard Worker         case ESE_WEAVER_READ_TIMEOUT:
150*5c4dab75SAndroid Build Coastguard Worker             status = WeaverReadStatus::THROTTLE;
151*5c4dab75SAndroid Build Coastguard Worker             value.resize(0);
152*5c4dab75SAndroid Build Coastguard Worker             break;
153*5c4dab75SAndroid Build Coastguard Worker         default:
154*5c4dab75SAndroid Build Coastguard Worker             status = WeaverReadStatus::FAILED;
155*5c4dab75SAndroid Build Coastguard Worker             timeout = 0;
156*5c4dab75SAndroid Build Coastguard Worker             value.resize(0);
157*5c4dab75SAndroid Build Coastguard Worker             break;
158*5c4dab75SAndroid Build Coastguard Worker     }
159*5c4dab75SAndroid Build Coastguard Worker 
160*5c4dab75SAndroid Build Coastguard Worker     // Try and close the session
161*5c4dab75SAndroid Build Coastguard Worker     if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
162*5c4dab75SAndroid Build Coastguard Worker         LOG(WARNING) << "Failed to close Weaver session";
163*5c4dab75SAndroid Build Coastguard Worker     }
164*5c4dab75SAndroid Build Coastguard Worker 
165*5c4dab75SAndroid Build Coastguard Worker     _hidl_cb(status, WeaverReadResponse{timeout, value});
166*5c4dab75SAndroid Build Coastguard Worker     return Void();
167*5c4dab75SAndroid Build Coastguard Worker }
168*5c4dab75SAndroid Build Coastguard Worker 
169*5c4dab75SAndroid Build Coastguard Worker }  // namespace esed
170*5c4dab75SAndroid Build Coastguard Worker }  // namespace android
171