• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2019, 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 #define LOG_TAG "rkpd_client"
18 
19 #include <atomic>
20 
21 #include <android-base/logging.h>
22 #include <android/security/rkp/BnGetKeyCallback.h>
23 #include <android/security/rkp/BnGetRegistrationCallback.h>
24 #include <android/security/rkp/IGetKeyCallback.h>
25 #include <android/security/rkp/IRemoteProvisioning.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/Status.h>
28 #include <rkp/support/rkpd_client.h>
29 #include <vintf/VintfObject.h>
30 
31 namespace android::security::rkp::support {
32 namespace {
33 
34 using ::android::binder::Status;
35 using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
36 using ::android::hardware::security::keymint::RpcHardwareInfo;
37 using ::android::security::rkp::BnGetKeyCallback;
38 using ::android::security::rkp::BnGetRegistrationCallback;
39 using ::android::security::rkp::IGetKeyCallback;
40 using ::android::security::rkp::IRegistration;
41 using ::android::security::rkp::IRemoteProvisioning;
42 using ::android::security::rkp::RemotelyProvisionedKey;
43 
44 constexpr const char* kRemoteProvisioningServiceName = "remote_provisioning";
45 
getRpcId(const sp<IRemotelyProvisionedComponent> & rpc)46 std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc) {
47     RpcHardwareInfo rpcHwInfo;
48     Status status = rpc->getHardwareInfo(&rpcHwInfo);
49     if (!status.isOk()) {
50         LOG(ERROR) << "Error getting remotely provisioned component hardware info: " << status;
51         return std::nullopt;
52     }
53 
54     if (!rpcHwInfo.uniqueId) {
55         LOG(ERROR) << "Remotely provisioned component is missing a unique id. "
56                    << "This is a bug in the vendor implementation.";
57         return std::nullopt;
58     }
59 
60     return *rpcHwInfo.uniqueId;
61 }
62 
findRpcNameById(std::string_view targetRpcId)63 std::optional<String16> findRpcNameById(std::string_view targetRpcId) {
64     auto deviceManifest = vintf::VintfObject::GetDeviceHalManifest();
65     auto instances = deviceManifest->getAidlInstances("android.hardware.security.keymint",
66                                                       "IRemotelyProvisionedComponent");
67     for (const std::string& instance : instances) {
68         auto rpcName =
69             IRemotelyProvisionedComponent::descriptor + String16("/") + String16(instance.c_str());
70         sp<IRemotelyProvisionedComponent> rpc =
71             android::waitForService<IRemotelyProvisionedComponent>(rpcName);
72 
73         auto rpcId = getRpcId(rpc);
74         if (!rpcId) {
75             continue;
76         }
77         if (*rpcId == targetRpcId) {
78             return rpcName;
79         }
80     }
81 
82     LOG(ERROR) << "Remotely provisioned component with given unique ID: " << targetRpcId
83                << " not found";
84     return std::nullopt;
85 }
86 
getRpcName(const sp<IRemotelyProvisionedComponent> & rpc)87 std::optional<String16> getRpcName(const sp<IRemotelyProvisionedComponent>& rpc) {
88     std::optional<std::string> targetRpcId = getRpcId(rpc);
89     if (!targetRpcId) {
90         return std::nullopt;
91     }
92     return findRpcNameById(*targetRpcId);
93 }
94 
95 class GetKeyCallback : public BnGetKeyCallback {
96   public:
GetKeyCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise)97     GetKeyCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise)
98         : keyPromise_(std::move(keyPromise)), called_() {}
99 
onSuccess(const RemotelyProvisionedKey & key)100     Status onSuccess(const RemotelyProvisionedKey& key) override {
101         if (called_.test_and_set()) {
102             return Status::ok();
103         }
104         keyPromise_.set_value(key);
105         return Status::ok();
106     }
onCancel()107     Status onCancel() override {
108         if (called_.test_and_set()) {
109             return Status::ok();
110         }
111         LOG(ERROR) << "GetKeyCallback cancelled";
112         keyPromise_.set_value(std::nullopt);
113         return Status::ok();
114     }
onError(IGetKeyCallback::ErrorCode error,const String16 & description)115     Status onError(IGetKeyCallback::ErrorCode error, const String16& description) override {
116         if (called_.test_and_set()) {
117             return Status::ok();
118         }
119         LOG(ERROR) << "GetKeyCallback failed: " << static_cast<int>(error) << ", " << description;
120         keyPromise_.set_value(std::nullopt);
121         return Status::ok();
122     }
123 
124   private:
125     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
126     // This callback can only be called into once
127     std::atomic_flag called_;
128 };
129 
130 class GetRegistrationCallback : public BnGetRegistrationCallback {
131   public:
GetRegistrationCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise,uint32_t keyId)132     GetRegistrationCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise,
133                             uint32_t keyId)
134         : keyPromise_(std::move(keyPromise)), keyId_(keyId), called_() {}
135 
onSuccess(const sp<IRegistration> & registration)136     Status onSuccess(const sp<IRegistration>& registration) override {
137         if (called_.test_and_set()) {
138             return Status::ok();
139         }
140         auto cb = sp<GetKeyCallback>::make(std::move(keyPromise_));
141         auto status = registration->getKey(keyId_, cb);
142         if (!status.isOk()) {
143             cb->onError(IGetKeyCallback::ErrorCode::ERROR_UNKNOWN,
144                         String16("Failed to register GetKeyCallback"));
145         }
146         return Status::ok();
147     }
onCancel()148     Status onCancel() override {
149         if (called_.test_and_set()) {
150             return Status::ok();
151         }
152         LOG(ERROR) << "GetRegistrationCallback cancelled";
153         keyPromise_.set_value(std::nullopt);
154         return Status::ok();
155     }
onError(const String16 & error)156     Status onError(const String16& error) override {
157         if (called_.test_and_set()) {
158             return Status::ok();
159         }
160         LOG(ERROR) << "GetRegistrationCallback failed: " << error;
161         keyPromise_.set_value(std::nullopt);
162         return Status::ok();
163     }
164 
165   private:
166     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
167     int32_t keyId_;
168     // This callback can only be called into once
169     std::atomic_flag called_;
170 };
171 
172 }  // namespace
173 
174 std::optional<std::future<std::optional<RemotelyProvisionedKey>>>
getRpcKeyFuture(const sp<IRemotelyProvisionedComponent> & rpc,int32_t keyId)175 getRpcKeyFuture(const sp<IRemotelyProvisionedComponent>& rpc, int32_t keyId) {
176     std::promise<std::optional<RemotelyProvisionedKey>> keyPromise;
177     auto keyFuture = keyPromise.get_future();
178 
179     auto rpcName = getRpcName(rpc);
180     if (!rpcName) {
181         LOG(ERROR) << "Failed to get IRemotelyProvisionedComponent name";
182         return std::nullopt;
183     }
184 
185     sp<IRemoteProvisioning> remoteProvisioning =
186         android::waitForService<IRemoteProvisioning>(String16(kRemoteProvisioningServiceName));
187     if (!remoteProvisioning) {
188         LOG(ERROR) << "Failed to get IRemoteProvisioning HAL";
189         return std::nullopt;
190     }
191 
192     auto cb = sp<GetRegistrationCallback>::make(std::move(keyPromise), keyId);
193     Status status = remoteProvisioning->getRegistration(*rpcName, cb);
194     if (!status.isOk()) {
195         LOG(ERROR) << "Failed getRegistration()";
196         return std::nullopt;
197     }
198 
199     return keyFuture;
200 }
201 
getRpcKey(const sp<IRemotelyProvisionedComponent> & rpc,int32_t keyId,int32_t timeout_sec)202 std::optional<RemotelyProvisionedKey> getRpcKey(const sp<IRemotelyProvisionedComponent>& rpc,
203                                                 int32_t keyId, int32_t timeout_sec) {
204     auto rpcKeyFuture = getRpcKeyFuture(rpc, keyId);
205     if (!rpcKeyFuture) {
206         LOG(ERROR) << "Failed getRpcKeyFuture()";
207         return std::nullopt;
208     }
209 
210     auto timeout = std::chrono::seconds(timeout_sec);
211     if (rpcKeyFuture->wait_for(timeout) != std::future_status::ready) {
212         LOG(ERROR) << "Waiting for remotely provisioned attestation key timed out";
213         return std::nullopt;
214     }
215 
216     return rpcKeyFuture->get();
217 }
218 
219 }  // namespace android::security::rkp::support
220