blob: d6cd673067c206a73944674084ac14d93cee4feb [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>
23#include <utils/String8.h>
24
25#include "../apps/weaver/include/ese/app/weaver.h"
26
27// libutils
28using android::String8;
29
30namespace {
31
32const String8 WRONG_KEY_SIZE_MSG = String8{"Key must be 16 bytes"};
33const String8 WRONG_VALUE_SIZE_MSG = String8{"Value must be 16 bytes"};
34
35} // namespace
36
37namespace android {
38namespace esed {
39
40// libhidl
41using ::android::hardware::Status;
42using ::android::hardware::Void;
43
44// HAL
45using ::android::hardware::weaver::V1_0::WeaverConfig;
46using ::android::hardware::weaver::V1_0::WeaverReadResponse;
47using ::android::hardware::weaver::V1_0::WeaverReadStatus;
48
49// Methods from ::android::hardware::weaver::V1_0::IWeaver follow.
50Return<void> Weaver::getConfig(getConfig_cb _hidl_cb) {
51 LOG(VERBOSE) << "Running Weaver::getNumSlots";
52
53 // Open SE session for applet
54 EseWeaverSession ws;
55 ese_weaver_session_init(&ws);
Andrew Scull5ca0a142017-04-19 16:48:14 +010056 EseAppResult res = ese_weaver_session_open(mEse.ese_interface(), &ws);
57 if (EseAppResultValue(res) == ESE_APP_RESULT_ERROR_OS) {
58 switch (EseAppResultAppValue(res)) {
59 case 0x6999: // SW_APPLET_SELECT_FAILED
60 case 0x6A82: // SW_FILE_NOT_FOUND
61 // No applet means no Weaver storage. Report no slots to prompt
62 // fallback to software mode.
63 _hidl_cb(WeaverStatus::OK, WeaverConfig{0, 0, 0});
64 return Void();
65 }
66 } else if (res != ESE_APP_RESULT_OK) {
67 // Transient error
Andrew Scull6024d162017-04-17 18:58:12 +010068 _hidl_cb(WeaverStatus::FAILED, WeaverConfig{});
69 return Void();
70 }
71
72 // Call the applet
73 uint32_t numSlots;
74 if (ese_weaver_get_num_slots(&ws, &numSlots) != ESE_APP_RESULT_OK) {
75 _hidl_cb(WeaverStatus::FAILED, WeaverConfig{});
76 return Void();
77 }
78
79 // Try and close the session
80 if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
81 LOG(WARNING) << "Failed to close Weaver session";
82 }
83
84 _hidl_cb(WeaverStatus::OK, WeaverConfig{numSlots, kEseWeaverKeySize, kEseWeaverValueSize});
85 return Void();
86}
87
88Return<WeaverStatus> Weaver::write(uint32_t slotId, const hidl_vec<uint8_t>& key,
89 const hidl_vec<uint8_t>& value) {
90 LOG(INFO) << "Running Weaver::write on slot " << slotId;
91
92 // Validate the key and value sizes
93 if (key.size() != kEseWeaverKeySize) {
94 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, WRONG_KEY_SIZE_MSG);
95 }
96 if (value.size() != kEseWeaverValueSize) {
97 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, WRONG_VALUE_SIZE_MSG);
98 }
99
100 // Open SE session for applet
101 EseWeaverSession ws;
102 ese_weaver_session_init(&ws);
103 if (ese_weaver_session_open(mEse.ese_interface(), &ws) != ESE_APP_RESULT_OK) {
104 return WeaverStatus::FAILED;
105 }
106
107 // Call the applet
108 if (ese_weaver_write(&ws, slotId, key.data(), value.data()) != ESE_APP_RESULT_OK) {
109 return WeaverStatus::FAILED;
110 }
111
112 // Try and close the session
113 if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
114 LOG(WARNING) << "Failed to close Weaver session";
115 }
116
117 return WeaverStatus::OK;
118}
119
120Return<void> Weaver::read(uint32_t slotId, const hidl_vec<uint8_t>& key, read_cb _hidl_cb) {
121 LOG(VERBOSE) << "Running Weaver::read on slot " << slotId;
122
123 // Validate the key size
124 if (key.size() != kEseWeaverKeySize) {
125 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, WRONG_KEY_SIZE_MSG);
126 }
127
128 // Open SE session for applet
129 EseWeaverSession ws;
130 ese_weaver_session_init(&ws);
131 if (ese_weaver_session_open(mEse.ese_interface(), &ws) != ESE_APP_RESULT_OK) {
132 _hidl_cb(WeaverReadStatus::FAILED, WeaverReadResponse{});
133 return Void();
134 }
135
136 // Call the applet
137 hidl_vec<uint8_t> value;
138 value.resize(kEseWeaverValueSize);
139 uint32_t timeout;
140 const int res = ese_weaver_read(&ws, slotId, key.data(), value.data(), &timeout);
141 WeaverReadStatus status;
142 switch (res) {
143 case ESE_APP_RESULT_OK:
144 status = WeaverReadStatus::OK;
145 timeout = 0;
146 break;
147 case ESE_WEAVER_READ_WRONG_KEY:
148 status = WeaverReadStatus::INCORRECT_KEY;
149 value.resize(0);
150 break;
151 case ESE_WEAVER_READ_TIMEOUT:
152 status = WeaverReadStatus::THROTTLE;
153 value.resize(0);
154 break;
155 default:
156 status = WeaverReadStatus::FAILED;
157 timeout = 0;
158 value.resize(0);
159 break;
160 }
161
162 // Try and close the session
163 if (ese_weaver_session_close(&ws) != ESE_APP_RESULT_OK) {
164 LOG(WARNING) << "Failed to close Weaver session";
165 }
166
167 _hidl_cb(status, WeaverReadResponse{timeout, value});
168 return Void();
169}
170
171} // namespace esed
172} // namespace android