1 /*
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 
25 namespace android {
26 namespace esed {
27 
28 // libhidl
29 using ::android::hardware::Void;
30 
31 // Methods from ::android::hardware::oemlock::V1_0::IOemLock follow.
getName(getName_cb _hidl_cb)32 Return<void> OemLock::getName(getName_cb _hidl_cb) {
33   _hidl_cb(OemLockStatus::OK, {"01"});
34   return Void();
35 }
36 
setOemUnlockAllowedByCarrier(bool allowed,const hidl_vec<uint8_t> & signature)37 Return<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 
isOemUnlockAllowedByCarrier(isOemUnlockAllowedByCarrier_cb _hidl_cb)84 Return<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 
setOemUnlockAllowedByDevice(bool allowed)122 Return<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 
isOemUnlockAllowedByDevice(isOemUnlockAllowedByDevice_cb _hidl_cb)154 Return<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
190