xref: /aosp_15_r20/external/libese/esed/OemLock.cpp (revision 5c4dab75aa57366379dce576b1a9e082a44e2b3a)
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