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 <memory>
20
21 #include <android-base/endian.h>
22 #include <android-base/logging.h>
23
24 #include <avb.h>
25
26 namespace android {
27 namespace hardware {
28 namespace oemlock {
29
30 // libhidl
31 using ::android::hardware::Void;
32
33 // AVB app
34 using ::nugget::app::avb::CarrierUnlock;
35 using ::nugget::app::avb::CarrierUnlockRequest;
36 using ::nugget::app::avb::CarrierUnlockResponse;
37 using ::nugget::app::avb::GetLockRequest;
38 using ::nugget::app::avb::GetLockResponse;
39 using ::nugget::app::avb::LockIndex;
40 using ::nugget::app::avb::SetDeviceLockRequest;
41 using ::nugget::app::avb::SetDeviceLockResponse;
42
43 // Methods from ::android::hardware::oemlock::V1_0::IOemLock follow.
getName(getName_cb _hidl_cb)44 Return<void> OemLock::getName(getName_cb _hidl_cb) {
45 LOG(VERBOSE) << "Running OemLock::getName";
46 _hidl_cb(OemLockStatus::OK, {"01"});
47 return Void();
48 }
49
setOemUnlockAllowedByCarrier(bool allowed,const hidl_vec<uint8_t> & signature)50 Return<OemLockSecureStatus> OemLock::setOemUnlockAllowedByCarrier(
51 bool allowed, const hidl_vec<uint8_t>& signature) {
52 LOG(INFO) << "Running OemLock::setOemUnlockAllowedByCarrier: " << allowed;
53
54 if (!allowed) {
55 // Locking is only performed in the factory
56 LOG(ERROR) << "Cannot carrier lock the device";
57 return OemLockSecureStatus::FAILED;
58 }
59
60 auto unlock = std::make_unique<CarrierUnlock>();
61 if (!carrierUnlockFromSignature(signature, unlock.get())) {
62 return OemLockSecureStatus::INVALID_SIGNATURE;
63 }
64
65 CarrierUnlockRequest request;
66 request.set_allocated_token(unlock.release());
67 CarrierUnlockResponse response;
68 const uint32_t appStatus =_avbApp.CarrierUnlock(request, &response);
69
70 if (appStatus == APP_ERROR_AVB_AUTHORIZATION) {
71 LOG(WARNING) << "Carrier unlock signature rejected by app";
72 return OemLockSecureStatus::INVALID_SIGNATURE;
73 }
74
75 if (appStatus != APP_SUCCESS) {
76 LOG(ERROR) << "App CarrierUnlock request failed with status " << appStatus;
77 return OemLockSecureStatus::FAILED;
78 }
79
80 return OemLockSecureStatus::OK;
81 }
82
isOemUnlockAllowedByCarrier(isOemUnlockAllowedByCarrier_cb _hidl_cb)83 Return<void> OemLock::isOemUnlockAllowedByCarrier(isOemUnlockAllowedByCarrier_cb _hidl_cb) {
84 LOG(VERBOSE) << "Running OemLock::isOemUnlockAllowedByCarrier";
85
86 GetLockRequest request;
87 request.set_lock(LockIndex::CARRIER);
88 GetLockResponse response;
89 const uint32_t appStatus = _avbApp.GetLock(request, &response);
90
91 if (appStatus != APP_SUCCESS) {
92 LOG(ERROR) << "App GetLock request for CARRIER failed with status " << appStatus;
93 _hidl_cb(OemLockStatus::FAILED, false);
94 return Void();
95 }
96
97 const bool allowed = response.locked() == 0;
98 _hidl_cb(OemLockStatus::OK, allowed);
99 return Void();
100 }
101
setOemUnlockAllowedByDevice(bool allowed)102 Return<OemLockStatus> OemLock::setOemUnlockAllowedByDevice(bool allowed) {
103 LOG(INFO) << "Running OemLock::setOemUnlockAllowedByDevice: " << allowed;
104
105 SetDeviceLockRequest request;
106 request.set_locked(allowed ? 0 : 1);
107 SetDeviceLockResponse response;
108 const uint32_t appStatus = _avbApp.SetDeviceLock(request, &response);
109
110 if (appStatus != APP_SUCCESS) {
111 LOG(ERROR) << "App SetDeviceLock failed with status " << appStatus;
112 return OemLockStatus::FAILED;
113 }
114
115 return OemLockStatus::OK;
116 }
117
isOemUnlockAllowedByDevice(isOemUnlockAllowedByDevice_cb _hidl_cb)118 Return<void> OemLock::isOemUnlockAllowedByDevice(isOemUnlockAllowedByDevice_cb _hidl_cb) {
119 LOG(VERBOSE) << "Running OemLock::isOemUnlockAllowedByDevice";
120
121 GetLockRequest request;
122 request.set_lock(LockIndex::DEVICE);
123 GetLockResponse response;
124 const uint32_t appStatus = _avbApp.GetLock(request, &response);
125
126 if (appStatus != APP_SUCCESS) {
127 LOG(ERROR) << "App GetLock request for DEVICE failed with status " << appStatus;
128 _hidl_cb(OemLockStatus::FAILED, false);
129 return Void();
130 }
131
132 const bool allowed = response.locked() == 0;
133 _hidl_cb(OemLockStatus::OK, allowed);
134 return Void();
135 }
136
137 /**
138 * Decompose the signature into:
139 * 1. 64-bit version
140 * 2. 64-bit nonce
141 * 3. unlock token bytes
142 *
143 * @param signature The signature to parse.
144 * @param unlock The message to populate with the parsed data.
145 * @return whether the signature could be parsed.
146 */
carrierUnlockFromSignature(const hidl_vec<uint8_t> & signature,CarrierUnlock * unlock)147 bool OemLock::carrierUnlockFromSignature(const hidl_vec<uint8_t>& signature,
148 CarrierUnlock* unlock) {
149 CHECK(unlock != nullptr);
150
151 // Ensure there is enough data to decode. Not checking details of the token
152 // in the HAL.
153 if (signature.size() < (sizeof(uint64_t) * 2)) {
154 return false;
155 }
156
157 auto it = signature.begin();
158
159 // Get the version
160 uint64_t version;
161 memcpy(&version, &(*it), sizeof(uint64_t));
162 it += sizeof(uint64_t);
163 unlock->set_version(letoh64(version));
164
165 // Get the nonce
166 uint64_t nonce;
167 memcpy(&nonce, &(*it), sizeof(uint64_t));
168 it += sizeof(uint64_t);
169 unlock->set_nonce(letoh64(nonce));
170
171 // Remaining is the unlock token
172 unlock->set_signature(&(*it), std::distance(it, signature.end()));
173
174 return true;
175 }
176
177 } // namespace oemlock
178 } // namespace hardware
179 } // namespace android
180