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