blob: 7e90d634c4ae256e1df768dbe179ab6b92c1fdb9 [file] [log] [blame]
Tri Vo3ab6f052022-11-22 10:26:16 -08001/*
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 "credstore"
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/IRemoteProvisioning.h>
25#include <binder/IServiceManager.h>
26#include <binder/Status.h>
27#include <vintf/VintfObject.h>
28
29#include "RemotelyProvisionedKey.h"
30
31namespace android {
32namespace security {
33namespace identity {
34namespace {
35
36using ::android::binder::Status;
37using ::android::hardware::security::keymint::IRemotelyProvisionedComponent;
38using ::android::hardware::security::keymint::RpcHardwareInfo;
39using ::android::security::rkp::BnGetKeyCallback;
40using ::android::security::rkp::BnGetRegistrationCallback;
41using ::android::security::rkp::IRegistration;
42using ::android::security::rkp::IRemoteProvisioning;
43using ::android::security::rkp::RemotelyProvisionedKey;
44
Tri Vo71e8cc12023-01-17 15:37:50 -080045constexpr const char* kRemoteProvisioningServiceName = "remote_provisioning";
46
Tri Vo3ab6f052022-11-22 10:26:16 -080047std::optional<String16> findRpcNameById(std::string_view targetRpcId) {
48 auto deviceManifest = vintf::VintfObject::GetDeviceHalManifest();
49 auto instances = deviceManifest->getAidlInstances("android.hardware.security.keymint",
50 "IRemotelyProvisionedComponent");
51 for (const std::string& instance : instances) {
52 auto rpcName =
53 IRemotelyProvisionedComponent::descriptor + String16("/") + String16(instance.c_str());
54 sp<IRemotelyProvisionedComponent> rpc =
55 android::waitForService<IRemotelyProvisionedComponent>(rpcName);
56
57 auto rpcId = getRpcId(rpc);
58 if (!rpcId) {
59 continue;
60 }
61 if (*rpcId == targetRpcId) {
62 return rpcName;
63 }
64 }
65
66 LOG(ERROR) << "Remotely provisioned component with given unique ID: " << targetRpcId
67 << " not found";
68 return std::nullopt;
69}
70
71std::optional<String16> getRpcName(const sp<IRemotelyProvisionedComponent>& rpc) {
72 std::optional<std::string> targetRpcId = getRpcId(rpc);
73 if (!targetRpcId) {
74 return std::nullopt;
75 }
76 return findRpcNameById(*targetRpcId);
77}
78
79class GetKeyCallback : public BnGetKeyCallback {
80 public:
81 GetKeyCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise)
82 : keyPromise_(std::move(keyPromise)), called_() {}
83
84 Status onSuccess(const RemotelyProvisionedKey& key) override {
85 if (called_.test_and_set()) {
86 return Status::ok();
87 }
88 keyPromise_.set_value(key);
89 return Status::ok();
90 }
91 Status onCancel() override {
92 if (called_.test_and_set()) {
93 return Status::ok();
94 }
95 LOG(ERROR) << "GetKeyCallback cancelled";
96 keyPromise_.set_value(std::nullopt);
97 return Status::ok();
98 }
99 Status onError(const String16& error) override {
100 if (called_.test_and_set()) {
101 return Status::ok();
102 }
103 LOG(ERROR) << "GetKeyCallback failed: " << error;
104 keyPromise_.set_value(std::nullopt);
105 return Status::ok();
106 }
107
108 private:
109 std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
110 // This callback can only be called into once
111 std::atomic_flag called_;
112};
113
114class GetRegistrationCallback : public BnGetRegistrationCallback {
115 public:
116 GetRegistrationCallback(std::promise<std::optional<RemotelyProvisionedKey>> keyPromise,
117 uint32_t keyId)
118 : keyPromise_(std::move(keyPromise)), keyId_(keyId), called_() {}
119
120 Status onSuccess(const sp<IRegistration>& registration) override {
121 if (called_.test_and_set()) {
122 return Status::ok();
123 }
124 auto cb = sp<GetKeyCallback>::make(std::move(keyPromise_));
125 auto status = registration->getKey(keyId_, cb);
126 if (!status.isOk()) {
127 cb->onError(String16("Failed to register GetKeyCallback"));
128 }
129 return Status::ok();
130 }
131 Status onCancel() override {
132 if (called_.test_and_set()) {
133 return Status::ok();
134 }
135 LOG(ERROR) << "GetRegistrationCallback cancelled";
136 keyPromise_.set_value(std::nullopt);
137 return Status::ok();
138 }
139 Status onError(const String16& error) override {
140 if (called_.test_and_set()) {
141 return Status::ok();
142 }
143 LOG(ERROR) << "GetRegistrationCallback failed: " << error;
144 keyPromise_.set_value(std::nullopt);
145 return Status::ok();
146 }
147
148 private:
149 std::promise<std::optional<RemotelyProvisionedKey>> keyPromise_;
150 int32_t keyId_;
151 // This callback can only be called into once
152 std::atomic_flag called_;
153};
154
155} // namespace
156
157std::optional<std::string> getRpcId(const sp<IRemotelyProvisionedComponent>& rpc) {
158 RpcHardwareInfo rpcHwInfo;
159 Status status = rpc->getHardwareInfo(&rpcHwInfo);
160 if (!status.isOk()) {
161 LOG(ERROR) << "Error getting remotely provisioned component hardware info: " << status;
162 return std::nullopt;
163 }
164
165 if (!rpcHwInfo.uniqueId) {
166 LOG(ERROR) << "Remotely provisioned component is missing a unique id, which is "
167 << "required for credential key remotely provisioned attestation keys. "
168 << "This is a bug in the vendor implementation.";
169 return std::nullopt;
170 }
171
172 return *rpcHwInfo.uniqueId;
173}
174
175std::optional<std::future<std::optional<RemotelyProvisionedKey>>>
176getRpcKeyFuture(const sp<IRemotelyProvisionedComponent>& rpc, int32_t keyId) {
177 std::promise<std::optional<RemotelyProvisionedKey>> keyPromise;
178 auto keyFuture = keyPromise.get_future();
179
180 auto rpcName = getRpcName(rpc);
181 if (!rpcName) {
182 LOG(ERROR) << "Failed to get IRemotelyProvisionedComponent name";
183 return std::nullopt;
184 }
185
186 sp<IRemoteProvisioning> remoteProvisioning =
Tri Vo71e8cc12023-01-17 15:37:50 -0800187 android::waitForService<IRemoteProvisioning>(String16(kRemoteProvisioningServiceName));
Tri Vo3ab6f052022-11-22 10:26:16 -0800188 if (!remoteProvisioning) {
189 LOG(ERROR) << "Failed to get IRemoteProvisioning HAL";
190 return std::nullopt;
191 }
192
193 auto cb = sp<GetRegistrationCallback>::make(std::move(keyPromise), keyId);
194 Status status = remoteProvisioning->getRegistration(*rpcName, cb);
195 if (!status.isOk()) {
196 LOG(ERROR) << "Failed getRegistration()";
197 return std::nullopt;
198 }
199
200 return keyFuture;
201}
202
203} // namespace identity
204} // namespace security
205} // namespace android