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