xref: /aosp_15_r20/system/security/provisioner/support/rkpd_client.cpp (revision e1997b9af69e3155ead6e072d106a0077849ffba)
1*e1997b9aSAndroid Build Coastguard Worker /*
2*e1997b9aSAndroid Build Coastguard Worker  * Copyright (c) 2019, The Android Open Source Project
3*e1997b9aSAndroid Build Coastguard Worker  *
4*e1997b9aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*e1997b9aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*e1997b9aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*e1997b9aSAndroid Build Coastguard Worker  *
8*e1997b9aSAndroid Build Coastguard Worker  *     http://www.apache.org/licenses/LICENSE-2.0
9*e1997b9aSAndroid Build Coastguard Worker  *
10*e1997b9aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*e1997b9aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*e1997b9aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1997b9aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*e1997b9aSAndroid Build Coastguard Worker  * limitations under the License.
15*e1997b9aSAndroid Build Coastguard Worker  */
16*e1997b9aSAndroid Build Coastguard Worker 
17*e1997b9aSAndroid Build Coastguard Worker #define LOG_TAG "rkpd_client"
18*e1997b9aSAndroid Build Coastguard Worker 
19*e1997b9aSAndroid Build Coastguard Worker #include <atomic>
20*e1997b9aSAndroid Build Coastguard Worker 
21*e1997b9aSAndroid Build Coastguard Worker #include <android-base/logging.h>
22*e1997b9aSAndroid Build Coastguard Worker #include <android/security/rkp/BnGetKeyCallback.h>
23*e1997b9aSAndroid Build Coastguard Worker #include <android/security/rkp/BnGetRegistrationCallback.h>
24*e1997b9aSAndroid Build Coastguard Worker #include <android/security/rkp/IGetKeyCallback.h>
25*e1997b9aSAndroid Build Coastguard Worker #include <android/security/rkp/IRemoteProvisioning.h>
26*e1997b9aSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
27*e1997b9aSAndroid Build Coastguard Worker #include <binder/Status.h>
28*e1997b9aSAndroid Build Coastguard Worker #include <rkp/support/rkpd_client.h>
29*e1997b9aSAndroid Build Coastguard Worker 
30*e1997b9aSAndroid Build Coastguard Worker namespace android::security::rkp::support {
31*e1997b9aSAndroid Build Coastguard Worker namespace {
32*e1997b9aSAndroid Build Coastguard Worker 
33*e1997b9aSAndroid Build Coastguard Worker using ::android::binder::Status;
34*e1997b9aSAndroid Build Coastguard Worker using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
35*e1997b9aSAndroid Build Coastguard Worker using ::android::hardware::security::keymint::RpcHardwareInfo;
36*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::BnGetKeyCallback;
37*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::BnGetRegistrationCallback;
38*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::IGetKeyCallback;
39*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::IRegistration;
40*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::IRemoteProvisioning;
41*e1997b9aSAndroid Build Coastguard Worker using ::android::security::rkp::RemotelyProvisionedKey;
42*e1997b9aSAndroid Build Coastguard Worker 
43*e1997b9aSAndroid Build Coastguard Worker constexpr const char* kRemoteProvisioningServiceName = "remote_provisioning";
44*e1997b9aSAndroid Build Coastguard Worker 
getRpcId(const sp<IRemotelyProvisionedComponent> & rpc)45*e1997b9aSAndroid Build Coastguard Worker std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc) {
46*e1997b9aSAndroid Build Coastguard Worker     RpcHardwareInfo rpcHwInfo;
47*e1997b9aSAndroid Build Coastguard Worker     Status status = rpc->getHardwareInfo(&rpcHwInfo);
48*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
49*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Error getting remotely provisioned component hardware info: " << status;
50*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
51*e1997b9aSAndroid Build Coastguard Worker     }
52*e1997b9aSAndroid Build Coastguard Worker 
53*e1997b9aSAndroid Build Coastguard Worker     if (!rpcHwInfo.uniqueId) {
54*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Remotely provisioned component is missing a unique id. "
55*e1997b9aSAndroid Build Coastguard Worker                    << "This is a bug in the vendor implementation.";
56*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
57*e1997b9aSAndroid Build Coastguard Worker     }
58*e1997b9aSAndroid Build Coastguard Worker 
59*e1997b9aSAndroid Build Coastguard Worker     return *rpcHwInfo.uniqueId;
60*e1997b9aSAndroid Build Coastguard Worker }
61*e1997b9aSAndroid Build Coastguard Worker 
findRpcNameById(std::string_view targetRpcId)62*e1997b9aSAndroid Build Coastguard Worker std::optional<String16> findRpcNameById(std::string_view targetRpcId) {
63*e1997b9aSAndroid Build Coastguard Worker     auto instances = android::defaultServiceManager()->getDeclaredInstances(
64*e1997b9aSAndroid Build Coastguard Worker         IRemotelyProvisionedComponent::descriptor);
65*e1997b9aSAndroid Build Coastguard Worker     for (const auto& instance : instances) {
66*e1997b9aSAndroid Build Coastguard Worker         auto rpcName = IRemotelyProvisionedComponent::descriptor + String16("/") + instance;
67*e1997b9aSAndroid Build Coastguard Worker         sp<IRemotelyProvisionedComponent> rpc =
68*e1997b9aSAndroid Build Coastguard Worker             android::waitForService<IRemotelyProvisionedComponent>(rpcName);
69*e1997b9aSAndroid Build Coastguard Worker 
70*e1997b9aSAndroid Build Coastguard Worker         auto rpcId = getRpcId(rpc);
71*e1997b9aSAndroid Build Coastguard Worker         if (!rpcId) {
72*e1997b9aSAndroid Build Coastguard Worker             continue;
73*e1997b9aSAndroid Build Coastguard Worker         }
74*e1997b9aSAndroid Build Coastguard Worker         if (*rpcId == targetRpcId) {
75*e1997b9aSAndroid Build Coastguard Worker             return rpcName;
76*e1997b9aSAndroid Build Coastguard Worker         }
77*e1997b9aSAndroid Build Coastguard Worker     }
78*e1997b9aSAndroid Build Coastguard Worker 
79*e1997b9aSAndroid Build Coastguard Worker     LOG(ERROR) << "Remotely provisioned component with given unique ID: " << targetRpcId
80*e1997b9aSAndroid Build Coastguard Worker                << " not found";
81*e1997b9aSAndroid Build Coastguard Worker     return std::nullopt;
82*e1997b9aSAndroid Build Coastguard Worker }
83*e1997b9aSAndroid Build Coastguard Worker 
getRpcName(const sp<IRemotelyProvisionedComponent> & rpc)84*e1997b9aSAndroid Build Coastguard Worker std::optional<String16> getRpcName(const sp<IRemotelyProvisionedComponent>& rpc) {
85*e1997b9aSAndroid Build Coastguard Worker     std::optional<std::string> targetRpcId = getRpcId(rpc);
86*e1997b9aSAndroid Build Coastguard Worker     if (!targetRpcId) {
87*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
88*e1997b9aSAndroid Build Coastguard Worker     }
89*e1997b9aSAndroid Build Coastguard Worker     return findRpcNameById(*targetRpcId);
90*e1997b9aSAndroid Build Coastguard Worker }
91*e1997b9aSAndroid Build Coastguard Worker 
92*e1997b9aSAndroid Build Coastguard Worker class GetKeyCallback : public BnGetKeyCallback {
93*e1997b9aSAndroid Build Coastguard Worker   public:
GetKeyCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise)94*e1997b9aSAndroid Build Coastguard Worker     GetKeyCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise)
95*e1997b9aSAndroid Build Coastguard Worker         : keyPromise_(std::move(keyPromise)), called_() {}
96*e1997b9aSAndroid Build Coastguard Worker 
onSuccess(const RemotelyProvisionedKey & key)97*e1997b9aSAndroid Build Coastguard Worker     Status onSuccess(const RemotelyProvisionedKey& key) override {
98*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
99*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
100*e1997b9aSAndroid Build Coastguard Worker         }
101*e1997b9aSAndroid Build Coastguard Worker         keyPromise_.set_value(key);
102*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
103*e1997b9aSAndroid Build Coastguard Worker     }
onCancel()104*e1997b9aSAndroid Build Coastguard Worker     Status onCancel() override {
105*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
106*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
107*e1997b9aSAndroid Build Coastguard Worker         }
108*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "GetKeyCallback cancelled";
109*e1997b9aSAndroid Build Coastguard Worker         keyPromise_.set_value(std::nullopt);
110*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
111*e1997b9aSAndroid Build Coastguard Worker     }
onError(IGetKeyCallback::ErrorCode error,const String16 & description)112*e1997b9aSAndroid Build Coastguard Worker     Status onError(IGetKeyCallback::ErrorCode error, const String16& description) override {
113*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
114*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
115*e1997b9aSAndroid Build Coastguard Worker         }
116*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "GetKeyCallback failed: " << static_cast<int>(error) << ", " << description;
117*e1997b9aSAndroid Build Coastguard Worker         keyPromise_.set_value(std::nullopt);
118*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
119*e1997b9aSAndroid Build Coastguard Worker     }
120*e1997b9aSAndroid Build Coastguard Worker 
121*e1997b9aSAndroid Build Coastguard Worker   private:
122*e1997b9aSAndroid Build Coastguard Worker     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
123*e1997b9aSAndroid Build Coastguard Worker     // This callback can only be called into once
124*e1997b9aSAndroid Build Coastguard Worker     std::atomic_flag called_;
125*e1997b9aSAndroid Build Coastguard Worker };
126*e1997b9aSAndroid Build Coastguard Worker 
127*e1997b9aSAndroid Build Coastguard Worker class GetRegistrationCallback : public BnGetRegistrationCallback {
128*e1997b9aSAndroid Build Coastguard Worker   public:
GetRegistrationCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise,uint32_t keyId)129*e1997b9aSAndroid Build Coastguard Worker     GetRegistrationCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise,
130*e1997b9aSAndroid Build Coastguard Worker                             uint32_t keyId)
131*e1997b9aSAndroid Build Coastguard Worker         : keyPromise_(std::move(keyPromise)), keyId_(keyId), called_() {}
132*e1997b9aSAndroid Build Coastguard Worker 
onSuccess(const sp<IRegistration> & registration)133*e1997b9aSAndroid Build Coastguard Worker     Status onSuccess(const sp<IRegistration>& registration) override {
134*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
135*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
136*e1997b9aSAndroid Build Coastguard Worker         }
137*e1997b9aSAndroid Build Coastguard Worker         auto cb = sp<GetKeyCallback>::make(std::move(keyPromise_));
138*e1997b9aSAndroid Build Coastguard Worker         auto status = registration->getKey(keyId_, cb);
139*e1997b9aSAndroid Build Coastguard Worker         if (!status.isOk()) {
140*e1997b9aSAndroid Build Coastguard Worker             cb->onError(IGetKeyCallback::ErrorCode::ERROR_UNKNOWN,
141*e1997b9aSAndroid Build Coastguard Worker                         String16("Failed to register GetKeyCallback"));
142*e1997b9aSAndroid Build Coastguard Worker         }
143*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
144*e1997b9aSAndroid Build Coastguard Worker     }
onCancel()145*e1997b9aSAndroid Build Coastguard Worker     Status onCancel() override {
146*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
147*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
148*e1997b9aSAndroid Build Coastguard Worker         }
149*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "GetRegistrationCallback cancelled";
150*e1997b9aSAndroid Build Coastguard Worker         keyPromise_.set_value(std::nullopt);
151*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
152*e1997b9aSAndroid Build Coastguard Worker     }
onError(const String16 & error)153*e1997b9aSAndroid Build Coastguard Worker     Status onError(const String16& error) override {
154*e1997b9aSAndroid Build Coastguard Worker         if (called_.test_and_set()) {
155*e1997b9aSAndroid Build Coastguard Worker             return Status::ok();
156*e1997b9aSAndroid Build Coastguard Worker         }
157*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "GetRegistrationCallback failed: " << error;
158*e1997b9aSAndroid Build Coastguard Worker         keyPromise_.set_value(std::nullopt);
159*e1997b9aSAndroid Build Coastguard Worker         return Status::ok();
160*e1997b9aSAndroid Build Coastguard Worker     }
161*e1997b9aSAndroid Build Coastguard Worker 
162*e1997b9aSAndroid Build Coastguard Worker   private:
163*e1997b9aSAndroid Build Coastguard Worker     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
164*e1997b9aSAndroid Build Coastguard Worker     int32_t keyId_;
165*e1997b9aSAndroid Build Coastguard Worker     // This callback can only be called into once
166*e1997b9aSAndroid Build Coastguard Worker     std::atomic_flag called_;
167*e1997b9aSAndroid Build Coastguard Worker };
168*e1997b9aSAndroid Build Coastguard Worker 
169*e1997b9aSAndroid Build Coastguard Worker }  // namespace
170*e1997b9aSAndroid Build Coastguard Worker 
171*e1997b9aSAndroid Build Coastguard Worker std::optional<std::future<std::optional<RemotelyProvisionedKey>>>
getRpcKeyFuture(const sp<IRemotelyProvisionedComponent> & rpc,int32_t keyId)172*e1997b9aSAndroid Build Coastguard Worker getRpcKeyFuture(const sp<IRemotelyProvisionedComponent>& rpc, int32_t keyId) {
173*e1997b9aSAndroid Build Coastguard Worker     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise;
174*e1997b9aSAndroid Build Coastguard Worker     auto keyFuture = keyPromise.get_future();
175*e1997b9aSAndroid Build Coastguard Worker 
176*e1997b9aSAndroid Build Coastguard Worker     auto rpcName = getRpcName(rpc);
177*e1997b9aSAndroid Build Coastguard Worker     if (!rpcName) {
178*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to get IRemotelyProvisionedComponent name";
179*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
180*e1997b9aSAndroid Build Coastguard Worker     }
181*e1997b9aSAndroid Build Coastguard Worker 
182*e1997b9aSAndroid Build Coastguard Worker     sp<IRemoteProvisioning> remoteProvisioning =
183*e1997b9aSAndroid Build Coastguard Worker         android::waitForService<IRemoteProvisioning>(String16(kRemoteProvisioningServiceName));
184*e1997b9aSAndroid Build Coastguard Worker     if (!remoteProvisioning) {
185*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed to get IRemoteProvisioning HAL";
186*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
187*e1997b9aSAndroid Build Coastguard Worker     }
188*e1997b9aSAndroid Build Coastguard Worker 
189*e1997b9aSAndroid Build Coastguard Worker     auto cb = sp<GetRegistrationCallback>::make(std::move(keyPromise), keyId);
190*e1997b9aSAndroid Build Coastguard Worker     Status status = remoteProvisioning->getRegistration(*rpcName, cb);
191*e1997b9aSAndroid Build Coastguard Worker     if (!status.isOk()) {
192*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed getRegistration()";
193*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
194*e1997b9aSAndroid Build Coastguard Worker     }
195*e1997b9aSAndroid Build Coastguard Worker 
196*e1997b9aSAndroid Build Coastguard Worker     return keyFuture;
197*e1997b9aSAndroid Build Coastguard Worker }
198*e1997b9aSAndroid Build Coastguard Worker 
getRpcKey(const sp<IRemotelyProvisionedComponent> & rpc,int32_t keyId,int32_t timeout_sec)199*e1997b9aSAndroid Build Coastguard Worker std::optional<RemotelyProvisionedKey> getRpcKey(const sp<IRemotelyProvisionedComponent>& rpc,
200*e1997b9aSAndroid Build Coastguard Worker                                                 int32_t keyId, int32_t timeout_sec) {
201*e1997b9aSAndroid Build Coastguard Worker     auto rpcKeyFuture = getRpcKeyFuture(rpc, keyId);
202*e1997b9aSAndroid Build Coastguard Worker     if (!rpcKeyFuture) {
203*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Failed getRpcKeyFuture()";
204*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
205*e1997b9aSAndroid Build Coastguard Worker     }
206*e1997b9aSAndroid Build Coastguard Worker 
207*e1997b9aSAndroid Build Coastguard Worker     auto timeout = std::chrono::seconds(timeout_sec);
208*e1997b9aSAndroid Build Coastguard Worker     if (rpcKeyFuture->wait_for(timeout) != std::future_status::ready) {
209*e1997b9aSAndroid Build Coastguard Worker         LOG(ERROR) << "Waiting for remotely provisioned attestation key timed out";
210*e1997b9aSAndroid Build Coastguard Worker         return std::nullopt;
211*e1997b9aSAndroid Build Coastguard Worker     }
212*e1997b9aSAndroid Build Coastguard Worker 
213*e1997b9aSAndroid Build Coastguard Worker     return rpcKeyFuture->get();
214*e1997b9aSAndroid Build Coastguard Worker }
215*e1997b9aSAndroid Build Coastguard Worker 
216*e1997b9aSAndroid Build Coastguard Worker }  // namespace android::security::rkp::support
217