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