blob: 4a7974d518a4319c1ba516fcf8157e655f7b5496 [file] [log] [blame]
Will Drewrye47ba832017-04-18 17:08:09 -05001/*
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 "OemLock.h"
18
19#include <vector>
20
21#include <android-base/logging.h>
22#include "../apps/boot/include/ese/app/boot.h"
23#include "ScopedEseConnection.h"
24
25namespace android {
26namespace esed {
27
28// libhidl
29using ::android::hardware::Void;
30
31// Methods from ::android::hardware::oemlock::V1_0::IOemLock follow.
32Return<void> OemLock::getName(getName_cb _hidl_cb) {
33 _hidl_cb(OemLockStatus::OK, {"01"});
34 return Void();
35}
36
37Return<OemLockSecureStatus> OemLock::setOemUnlockAllowedByCarrier(
38 bool allowed, const hidl_vec<uint8_t>& signature) {
39 LOG(INFO) << "Running OemLock::setOemUnlockAllowedByCarrier: " << allowed;
40 ScopedEseConnection ese{mEse};
41 ese.init();
42 // In general, setting the carrier lock to locked is only done in factory,
43 // but there is no reason the HAL could not be used in factory to do it.
44 // As such, the signature would actually be a specially formatted string of
45 // identifiers. Unlocking requires a signature packaged in a simple format
46 // as well.
47 //
48 // See ../apps/boot/README.md for details.
49 std::vector<uint8_t> data(signature);
50 // "allowed" == unlocked == 0.
51 uint8_t lock_byte = allowed ? 0 : 1;
52 // xset expects the lock value as the first byte.
53 data.insert(data.cbegin(), lock_byte);
54
55 // Open SE session for applet
56 EseBootSession session;
57 ese_boot_session_init(&session);
58 EseAppResult res = ese_boot_session_open(mEse.ese_interface(), &session);
59 if (res != ESE_APP_RESULT_OK) {
60 LOG(ERROR) << "Failed to open a boot session: " << res;
61 return OemLockSecureStatus::FAILED;
62 }
63 res = ese_boot_lock_xset(&session, kEseBootLockIdCarrier,
64 data.data(), data.size());
65 if (res != ESE_APP_RESULT_OK) {
66 LOG(ERROR) << "Failed to change lock state (allowed="
67 << allowed << "): " << res;
68 }
69
70 // Try and close the session without perturbing our result value.
71 if (ese_boot_session_close(&session) != ESE_APP_RESULT_OK) {
72 LOG(WARNING) << "Failed to close boot session";
73 }
74
75 if (EseAppResultValue(res) == ESE_APP_RESULT_ERROR_APPLET) {
76 // 0004 and 0005 are invalid signature and invalid nonce respectively.
77 return OemLockSecureStatus::INVALID_SIGNATURE;
78 } else if (res != ESE_APP_RESULT_OK) {
79 return OemLockSecureStatus::FAILED;
80 }
81 return OemLockSecureStatus::OK;
82}
83
84Return<void> OemLock::isOemUnlockAllowedByCarrier(isOemUnlockAllowedByCarrier_cb _hidl_cb) {
85 LOG(VERBOSE) << "Running OemLock::isOemUnlockAllowedByCarrier";
86 ScopedEseConnection ese{mEse};
87 ese.init();
88 // Open SE session for applet
89 EseBootSession session;
90 ese_boot_session_init(&session);
91 EseAppResult res = ese_boot_session_open(mEse.ese_interface(), &session);
92 if (res != ESE_APP_RESULT_OK) {
93 LOG(ERROR) << "Failed to open a boot session: " << res;
94 _hidl_cb(OemLockStatus::FAILED, false);
95 return Void();
96 }
97 std::vector<uint8_t> data;
98 data.resize(1024);
99 uint16_t actualData = 0;
100 res = ese_boot_lock_xget(&session, kEseBootLockIdCarrier,
101 &data[0], data.size(),
102 &actualData);
103 if (res != ESE_APP_RESULT_OK || actualData == 0) {
104 LOG(ERROR) << "Failed to get lock state: " << res;
105 }
106
107 // Try and close the session without perturbing our result value.
108 if (ese_boot_session_close(&session) != ESE_APP_RESULT_OK) {
109 LOG(WARNING) << "Failed to close boot session";
110 }
111
112 if (res != ESE_APP_RESULT_OK) {
113 // Fail closed.
114 _hidl_cb(OemLockStatus::FAILED, false);
115 return Void();
116 }
117 // if data[0] == 1, lock == true, so allowed == false.
118 _hidl_cb(OemLockStatus::OK, data[0] != 0 ? false : true);
119 return Void();
120}
121
122Return<OemLockStatus> OemLock::setOemUnlockAllowedByDevice(bool allowed) {
123 LOG(INFO) << "Running OemLock::setOemUnlockAllowedByDevice: " << allowed;
124 ScopedEseConnection ese{mEse};
125 ese.init();
126 // "allowed" == unlocked == 0.
127 uint8_t lock_byte = allowed ? 0 : 1;
128
129 // Open SE session for applet
130 EseBootSession session;
131 ese_boot_session_init(&session);
132 EseAppResult res = ese_boot_session_open(mEse.ese_interface(), &session);
133 if (res != ESE_APP_RESULT_OK) {
134 LOG(ERROR) << "Failed to open a boot session: " << res;
135 return OemLockStatus::FAILED;
136 }
137 res = ese_boot_lock_set(&session, kEseBootLockIdDevice, lock_byte);
138 if (res != ESE_APP_RESULT_OK) {
139 LOG(ERROR) << "Failed to change device lock state (allowed="
140 << allowed << "): " << res;
141 }
142
143 // Try and close the session without perturbing our result value.
144 if (ese_boot_session_close(&session) != ESE_APP_RESULT_OK) {
145 LOG(WARNING) << "Failed to close boot session";
146 }
147
148 if (res != ESE_APP_RESULT_OK) {
149 return OemLockStatus::FAILED;
150 }
151 return OemLockStatus::OK;
152}
153
154Return<void> OemLock::isOemUnlockAllowedByDevice(isOemUnlockAllowedByDevice_cb _hidl_cb) {
155 LOG(VERBOSE) << "Running OemLock::isOemUnlockAllowedByDevice";
156 ScopedEseConnection ese{mEse};
157 ese.init();
158 // Open SE session for applet
159 EseBootSession session;
160 ese_boot_session_init(&session);
161 EseAppResult res = ese_boot_session_open(mEse.ese_interface(), &session);
162 if (res != ESE_APP_RESULT_OK) {
163 LOG(ERROR) << "Failed to open a boot session: " << res;
164 _hidl_cb(OemLockStatus::FAILED, false);
165 return Void();
166 }
167 uint8_t lock_byte = 0;
168 res = ese_boot_lock_get(&session, kEseBootLockIdDevice, &lock_byte);
169 if (res != ESE_APP_RESULT_OK) {
170 LOG(ERROR) << "Failed to get device lock state: " << res;
171 }
172
173 // Try and close the session without perturbing our result value.
174 if (ese_boot_session_close(&session) != ESE_APP_RESULT_OK) {
175 LOG(WARNING) << "Failed to close boot session";
176 }
177
178 if (res != ESE_APP_RESULT_OK) {
179 // Fail closed.
180 _hidl_cb(OemLockStatus::FAILED, false);
181 return Void();
182 }
183 // if data[0] == 1, lock == true, so allowed == false.
184 _hidl_cb(OemLockStatus::OK, lock_byte != 0 ? false : true);
185 return Void();
186}
187
188} // namespace esed
189} // namespace android