1 /*
2  * Copyright (C) 2023 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 "DrmRkpAdapter"
18 #include "DrmRkpAdapter.h"
19 #include <aidl/android/hardware/drm/IDrmFactory.h>
20 #include <aidl/android/hardware/drm/IDrmPlugin.h>
21 #include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
22 #include <android/binder_manager.h>
23 #include <log/log.h>
24 #include "DrmRemotelyProvisionedComponent.h"
25 
26 namespace android::mediadrm {
27 using CryptoSchemes = ::aidl::android::hardware::drm::CryptoSchemes;
28 using IDrmFactory = ::aidl::android::hardware::drm::IDrmFactory;
29 using IDrmPlugin = ::aidl::android::hardware::drm::IDrmPlugin;
30 
31 std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>
getDrmRemotelyProvisionedComponents()32 getDrmRemotelyProvisionedComponents() {
33     std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>> comps;
34     AServiceManager_forEachDeclaredInstance(
35             IDrmFactory::descriptor, &comps, [](const char* instance, void* context) {
36                 auto fullName = std::string(IDrmFactory::descriptor) + "/" + std::string(instance);
37                 auto factory = IDrmFactory::fromBinder(
38                         ::ndk::SpAIBinder(AServiceManager_waitForService(fullName.c_str())));
39                 if (factory == nullptr) {
40                     ALOGE("not found IDrmFactory. Instance name:[%s]", fullName.c_str());
41                     return;
42                 }
43 
44                 ALOGI("found IDrmFactory. Instance name:[%s]", fullName.c_str());
45                 CryptoSchemes schemes{};
46                 auto status = factory->getSupportedCryptoSchemes(&schemes);
47                 if (!status.isOk()) {
48                     ALOGE("getSupportedCryptoSchemes failed.Detail: [%s].",
49                           status.getDescription().c_str());
50                     return;
51                 }
52 
53                 if (schemes.uuids.empty()) {
54                     ALOGW("IDrmFactory Instance [%s] has empty supported schemes",
55                           fullName.c_str());
56                     return;
57                 }
58 
59                 std::shared_ptr<IDrmPlugin> mDrm;
60                 status = factory->createDrmPlugin(schemes.uuids[0], "DrmRkpAdapter", &mDrm);
61                 if (!status.isOk()) {
62                     ALOGE("createDrmPlugin failed.Detail: [%s].", status.getDescription().c_str());
63                     return;
64                 }
65 
66                 std::string drmVendor;
67                 status = mDrm->getPropertyString("vendor", &drmVendor);
68                 if (!status.isOk()) {
69                     ALOGE("mDrm->getPropertyString(\"vendor\") failed.Detail: [%s].",
70                           status.getDescription().c_str());
71                     return;
72                 }
73 
74                 std::string drmDesc;
75                 status = mDrm->getPropertyString("description", &drmDesc);
76                 if (!status.isOk()) {
77                     ALOGE("mDrm->getPropertyString(\"description\") failed.Detail: [%s].",
78                           status.getDescription().c_str());
79                     return;
80                 }
81 
82                 std::vector<uint8_t> bcc;
83                 status = mDrm->getPropertyByteArray("bootCertificateChain", &bcc);
84                 if (!status.isOk()) {
85                     ALOGE("mDrm->getPropertyByteArray(\"bootCertificateChain\") failed."
86                           "Detail: [%s].",
87                           status.getDescription().c_str());
88                     return;
89                 }
90 
91                 std::string compName(instance);
92                 auto comps = static_cast<
93                         std::map<std::string, std::shared_ptr<IRemotelyProvisionedComponent>>*>(
94                         context);
95                 (*comps)[compName] = ::ndk::SharedRefBase::make<DrmRemotelyProvisionedComponent>(
96                         mDrm, drmVendor, drmDesc, bcc);
97             });
98     return comps;
99 }
100 }  // namespace android::mediadrm