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