1 /*
2  * Copyright (C) 2017 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 "drm_hal_vendor_test@1.0"
18 
19 #include <openssl/aes.h>
20 #include <random>
21 
22 #include "drm_hal_vendor_module_api.h"
23 #include "vendor_modules.h"
24 #include <VtsHalHidlTargetCallbackBase.h>
25 
26 #include "android/hardware/drm/1.0/vts/drm_hal_vendor_test.h"
27 
28 using std::random_device;
29 using std::mt19937;
30 
31 static const uint8_t kInvalidUUID[16] = {
32         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
33         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
34 };
35 
__anonc14513810102null36 static drm_vts::VendorModules* gVendorModules = [] {
37 #if defined(__LP64__)
38     const char* kModulePath = "/data/local/tmp/64/lib";
39 #else
40     const char* kModulePath = "/data/local/tmp/32/lib";
41 #endif
42     auto modules = new drm_vts::VendorModules(kModulePath);
43     if (modules->getPathList().size() == 0) {
44         std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
45                 ", all vendor tests will be skipped" << std::endl;
46     }
47     return modules;
48 }();
49 
50 namespace android {
51 namespace hardware {
52 namespace drm {
53 namespace V1_0 {
54 namespace vts {
55 
DrmHalVendorFactoryTest()56 DrmHalVendorFactoryTest::DrmHalVendorFactoryTest()
57      : vendorModule(static_cast<DrmHalVTSVendorModule_V1*>(
58              gVendorModules->getModuleByName(GetParam().instance_))) {} // getModuleByName
59 
TEST_P(DrmHalVendorFactoryTest,ValidateConfigurations)60 TEST_P(DrmHalVendorFactoryTest, ValidateConfigurations) {
61     const char* kVendorStr = "Vendor module ";
62     size_t count = 0;
63     for (const auto& config : contentConfigurations) {
64         ASSERT_TRUE(config.name.size() > 0) << kVendorStr << "has no name";
65         ASSERT_TRUE(config.serverUrl.size() > 0) << kVendorStr
66                                                  << "has no serverUrl";
67         ASSERT_TRUE(config.initData.size() > 0) << kVendorStr
68                                                 << "has no init data";
69         ASSERT_TRUE(config.mimeType.size() > 0) << kVendorStr
70                                                 << "has no mime type";
71         ASSERT_TRUE(config.keys.size() >= 1) << kVendorStr << "has no keys";
72         for (const auto& key : config.keys) {
73             ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr
74                                               << " has zero length keyId";
75             ASSERT_TRUE(key.keyId.size() > 0) << kVendorStr
76                                               << " has zero length key value";
77         }
78         count++;
79     }
80     EXPECT_NE(0u, count);
81 }
82 
83 /**
84  * Ensure the factory doesn't support an invalid scheme UUID
85  */
TEST_P(DrmHalVendorFactoryTest,InvalidPluginNotSupported)86 TEST_P(DrmHalVendorFactoryTest, InvalidPluginNotSupported) {
87     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(kInvalidUUID));
88     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(kInvalidUUID));
89 }
90 
91 /**
92  * Ensure the factory doesn't support an empty UUID
93  */
TEST_P(DrmHalVendorFactoryTest,EmptyPluginUUIDNotSupported)94 TEST_P(DrmHalVendorFactoryTest, EmptyPluginUUIDNotSupported) {
95     hidl_array<uint8_t, 16> emptyUUID;
96     memset(emptyUUID.data(), 0, 16);
97     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(emptyUUID));
98     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(emptyUUID));
99 }
100 
101 /**
102  * Check if the factory supports the scheme uuid in the config.
103  */
TEST_P(DrmHalVendorFactoryTest,PluginConfigUUIDSupported)104 TEST_P(DrmHalVendorFactoryTest, PluginConfigUUIDSupported) {
105     RETURN_IF_SKIPPED;
106     EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(getUUID()));
107     EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(getUUID()));
108 }
109 
110 /**
111  * Ensure empty content type is not supported
112  */
TEST_P(DrmHalVendorFactoryTest,EmptyContentTypeNotSupported)113 TEST_P(DrmHalVendorFactoryTest, EmptyContentTypeNotSupported) {
114     hidl_string empty;
115     EXPECT_FALSE(drmFactory->isContentTypeSupported(empty));
116 }
117 
118 /**
119  * Ensure invalid content type is not supported
120  */
TEST_P(DrmHalVendorFactoryTest,InvalidContentTypeNotSupported)121 TEST_P(DrmHalVendorFactoryTest, InvalidContentTypeNotSupported) {
122     hidl_string invalid("abcdabcd");
123     EXPECT_FALSE(drmFactory->isContentTypeSupported(invalid));
124 }
125 
126 /**
127  * Ensure valid content types in the configs are supported
128  */
TEST_P(DrmHalVendorFactoryTest,ValidContentTypeSupported)129 TEST_P(DrmHalVendorFactoryTest, ValidContentTypeSupported) {
130     RETURN_IF_SKIPPED;
131     for (const auto& config : contentConfigurations) {
132         EXPECT_TRUE(drmFactory->isContentTypeSupported(config.mimeType));
133     }
134 }
135 
136 /**
137  * Ensure vendor drm plugin can be created
138  */
TEST_P(DrmHalVendorFactoryTest,CreateVendorDrmPlugin)139 TEST_P(DrmHalVendorFactoryTest, CreateVendorDrmPlugin) {
140     RETURN_IF_SKIPPED;
141     hidl_string packageName("android.hardware.drm.test");
142     auto res = drmFactory->createPlugin(
143             getUUID(), packageName,
144             [&](Status status, const sp<IDrmPlugin>& plugin) {
145                 EXPECT_EQ(Status::OK, status);
146                 EXPECT_NE(nullptr, plugin.get());
147             });
148     EXPECT_OK(res);
149 }
150 
151 /**
152  * Ensure vendor crypto plugin can be created
153  */
TEST_P(DrmHalVendorFactoryTest,CreateVendorCryptoPlugin)154 TEST_P(DrmHalVendorFactoryTest, CreateVendorCryptoPlugin) {
155     RETURN_IF_SKIPPED;
156     hidl_vec<uint8_t> initVec;
157     auto res = cryptoFactory->createPlugin(
158             getUUID(), initVec,
159             [&](Status status, const sp<ICryptoPlugin>& plugin) {
160                 EXPECT_EQ(Status::OK, status);
161                 EXPECT_NE(nullptr, plugin.get());
162             });
163     EXPECT_OK(res);
164 }
165 
166 /**
167  * Ensure invalid drm plugin can't be created
168  */
TEST_P(DrmHalVendorFactoryTest,CreateInvalidDrmPlugin)169 TEST_P(DrmHalVendorFactoryTest, CreateInvalidDrmPlugin) {
170     RETURN_IF_SKIPPED;
171     hidl_string packageName("android.hardware.drm.test");
172     auto res = drmFactory->createPlugin(
173             kInvalidUUID, packageName,
174             [&](Status status, const sp<IDrmPlugin>& plugin) {
175                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
176                 EXPECT_EQ(nullptr, plugin.get());
177             });
178     EXPECT_OK(res);
179 }
180 
181 /**
182  * Ensure invalid crypto plugin can't be created
183  */
TEST_P(DrmHalVendorFactoryTest,CreateInvalidCryptoPlugin)184 TEST_P(DrmHalVendorFactoryTest, CreateInvalidCryptoPlugin) {
185     RETURN_IF_SKIPPED;
186     hidl_vec<uint8_t> initVec;
187     auto res = cryptoFactory->createPlugin(
188             kInvalidUUID, initVec,
189             [&](Status status, const sp<ICryptoPlugin>& plugin) {
190                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
191                 EXPECT_EQ(nullptr, plugin.get());
192             });
193     EXPECT_OK(res);
194 }
195 
196 /**
197  *  DrmPlugin tests
198  */
199 
200 /**
201  * Test that a DRM plugin can handle provisioning.  While
202  * it is not required that a DRM scheme require provisioning,
203  * it should at least return appropriate status values. If
204  * a provisioning request is returned, it is passed to the
205  * vendor module which should provide a provisioning response
206  * that is delivered back to the HAL.
207  */
208 
TEST_P(DrmHalVendorPluginTest,DoProvisioning)209 TEST_P(DrmHalVendorPluginTest, DoProvisioning) {
210     RETURN_IF_SKIPPED;
211     hidl_string certificateType;
212     hidl_string certificateAuthority;
213     hidl_vec<uint8_t> provisionRequest;
214     hidl_string defaultUrl;
215     auto res = drmPlugin->getProvisionRequest(
216             certificateType, certificateAuthority,
217             [&](Status status, const hidl_vec<uint8_t>& request,
218                 const hidl_string& url) {
219                 if (status == Status::OK) {
220                     EXPECT_NE(request.size(), 0u);
221                     provisionRequest = request;
222                     defaultUrl = url;
223                 } else if (status == Status::ERROR_DRM_CANNOT_HANDLE) {
224                     EXPECT_EQ(0u, request.size());
225                 }
226             });
227     EXPECT_OK(res);
228 
229     if (provisionRequest.size() > 0) {
230         vector<uint8_t> response = vendorModule->handleProvisioningRequest(
231                 provisionRequest, defaultUrl);
232         ASSERT_NE(0u, response.size());
233 
234         auto res = drmPlugin->provideProvisionResponse(
235                 response, [&](Status status, const hidl_vec<uint8_t>&,
236                               const hidl_vec<uint8_t>&) {
237                     EXPECT_EQ(Status::OK, status);
238                 });
239         EXPECT_OK(res);
240     }
241 }
242 
243 /**
244  * The DRM HAL should return BAD_VALUE if an empty provisioning
245  * response is provided.
246  */
TEST_P(DrmHalVendorPluginTest,ProvideEmptyProvisionResponse)247 TEST_P(DrmHalVendorPluginTest, ProvideEmptyProvisionResponse) {
248     RETURN_IF_SKIPPED;
249     hidl_vec<uint8_t> response;
250     auto res = drmPlugin->provideProvisionResponse(
251             response, [&](Status status, const hidl_vec<uint8_t>&,
252                           const hidl_vec<uint8_t>&) {
253                 EXPECT_EQ(Status::BAD_VALUE, status);
254             });
255     EXPECT_OK(res);
256 }
257 
258 /**
259  * Helper method to open a session and verify that a non-empty
260  * session ID is returned
261  */
openSession()262 SessionId DrmHalVendorPluginTest::openSession() {
263     SessionId sessionId;
264 
265     auto res = drmPlugin->openSession([&](Status status, const SessionId& id) {
266         EXPECT_EQ(Status::OK, status);
267         EXPECT_NE(id.size(), 0u);
268         sessionId = id;
269     });
270     EXPECT_OK(res);
271     return sessionId;
272 }
273 
274 /**
275  * Helper method to close a session
276  */
closeSession(const SessionId & sessionId)277 void DrmHalVendorPluginTest::closeSession(const SessionId& sessionId) {
278     Status status = drmPlugin->closeSession(sessionId);
279     EXPECT_EQ(Status::OK, status);
280 }
281 
toHidlKeyedVector(const map<string,string> & params)282 KeyedVector DrmHalVendorPluginTest::toHidlKeyedVector(
283     const map<string, string>& params) {
284     std::vector<KeyValue> stdKeyedVector;
285     for (auto it = params.begin(); it != params.end(); ++it) {
286         KeyValue keyValue;
287         keyValue.key = it->first;
288         keyValue.value = it->second;
289         stdKeyedVector.push_back(keyValue);
290     }
291     return KeyedVector(stdKeyedVector);
292 }
293 
294 /**
295  * Helper method to load keys for subsequent decrypt tests.
296  * These tests use predetermined key request/response to
297  * avoid requiring a round trip to a license server.
298  */
loadKeys(const SessionId & sessionId,const ContentConfiguration & configuration,const KeyType & type=KeyType::STREAMING)299 hidl_vec<uint8_t> DrmHalVendorPluginTest::loadKeys(
300     const SessionId& sessionId, const ContentConfiguration& configuration,
301     const KeyType& type = KeyType::STREAMING) {
302     hidl_vec<uint8_t> keyRequest;
303     auto res = drmPlugin->getKeyRequest(
304         sessionId, configuration.initData, configuration.mimeType, type,
305         toHidlKeyedVector(configuration.optionalParameters),
306         [&](Status status, const hidl_vec<uint8_t>& request,
307             KeyRequestType type, const hidl_string&) {
308             EXPECT_EQ(Status::OK, status) << "Failed to get "
309                                              "key request for configuration "
310                                           << configuration.name;
311             EXPECT_EQ(type, KeyRequestType::INITIAL);
312             EXPECT_NE(request.size(), 0u) << "Expected key request size"
313                                              " to have length > 0 bytes";
314             keyRequest = request;
315         });
316     EXPECT_OK(res);
317 
318     /**
319      * Get key response from vendor module
320      */
321     hidl_vec<uint8_t> keyResponse =
322         vendorModule->handleKeyRequest(keyRequest, configuration.serverUrl);
323 
324     EXPECT_NE(keyResponse.size(), 0u) << "Expected key response size "
325                                          "to have length > 0 bytes";
326 
327     hidl_vec<uint8_t> keySetId;
328     res = drmPlugin->provideKeyResponse(
329         sessionId, keyResponse,
330         [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
331             EXPECT_EQ(Status::OK, status) << "Failure providing "
332                                              "key response for configuration "
333                                           << configuration.name;
334             keySetId = myKeySetId;
335         });
336     EXPECT_OK(res);
337     return keySetId;
338 }
339 
340 /**
341  * Test that a session can be opened and closed
342  */
TEST_P(DrmHalVendorPluginTest,OpenCloseSession)343 TEST_P(DrmHalVendorPluginTest, OpenCloseSession) {
344     RETURN_IF_SKIPPED;
345     auto sessionId = openSession();
346     closeSession(sessionId);
347 }
348 
349 /**
350  * Test that attempting to close an invalid (empty) sessionId
351  * is prohibited with the documented error code.
352  */
TEST_P(DrmHalVendorPluginTest,CloseInvalidSession)353 TEST_P(DrmHalVendorPluginTest, CloseInvalidSession) {
354     RETURN_IF_SKIPPED;
355     SessionId invalidSessionId;
356     Status status = drmPlugin->closeSession(invalidSessionId);
357     EXPECT_EQ(Status::BAD_VALUE, status);
358 }
359 
360 /**
361  * Test that attempting to close a valid session twice
362  * is prohibited with the documented error code.
363  */
TEST_P(DrmHalVendorPluginTest,CloseClosedSession)364 TEST_P(DrmHalVendorPluginTest, CloseClosedSession) {
365     RETURN_IF_SKIPPED;
366     auto sessionId = openSession();
367     closeSession(sessionId);
368     Status status = drmPlugin->closeSession(sessionId);
369     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
370 }
371 
372 /**
373  * A get key request should fail if no sessionId is provided
374  */
TEST_P(DrmHalVendorPluginTest,GetKeyRequestNoSession)375 TEST_P(DrmHalVendorPluginTest, GetKeyRequestNoSession) {
376     RETURN_IF_SKIPPED;
377     SessionId invalidSessionId;
378     hidl_vec<uint8_t> initData;
379     hidl_string mimeType = "video/mp4";
380     KeyedVector optionalParameters;
381     auto res = drmPlugin->getKeyRequest(
382             invalidSessionId, initData, mimeType, KeyType::STREAMING,
383             optionalParameters,
384             [&](Status status, const hidl_vec<uint8_t>&, KeyRequestType,
385                 const hidl_string&) { EXPECT_EQ(Status::BAD_VALUE, status); });
386     EXPECT_OK(res);
387 }
388 
389 /**
390  * Test that an empty sessionID returns BAD_VALUE
391  */
TEST_P(DrmHalVendorPluginTest,ProvideKeyResponseEmptySessionId)392 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptySessionId) {
393     RETURN_IF_SKIPPED;
394     SessionId session;
395 
396     hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65,
397                                      0x79, 0x73, 0x22, 0x3a};
398     auto res = drmPlugin->provideKeyResponse(
399             session, keyResponse,
400             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
401                 EXPECT_EQ(Status::BAD_VALUE, status);
402                 EXPECT_EQ(keySetId.size(), 0u);
403             });
404     EXPECT_OK(res);
405 }
406 
407 /**
408  * Test that an empty key response returns BAD_VALUE
409  */
TEST_P(DrmHalVendorPluginTest,ProvideKeyResponseEmptyResponse)410 TEST_P(DrmHalVendorPluginTest, ProvideKeyResponseEmptyResponse) {
411     RETURN_IF_SKIPPED;
412     SessionId session = openSession();
413     hidl_vec<uint8_t> emptyResponse;
414     auto res = drmPlugin->provideKeyResponse(
415             session, emptyResponse,
416             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
417                 EXPECT_EQ(Status::BAD_VALUE, status);
418                 EXPECT_EQ(keySetId.size(), 0u);
419             });
420     EXPECT_OK(res);
421     closeSession(session);
422 }
423 
424 /**
425  * Test that a removeKeys on an empty sessionID returns BAD_VALUE
426  */
TEST_P(DrmHalVendorPluginTest,RemoveKeysEmptySessionId)427 TEST_P(DrmHalVendorPluginTest, RemoveKeysEmptySessionId) {
428     RETURN_IF_SKIPPED;
429     SessionId sessionId;
430     Status status = drmPlugin->removeKeys(sessionId);
431     EXPECT_TRUE(status == Status::BAD_VALUE);
432 }
433 
434 /**
435  * Test that remove keys returns okay on an initialized session
436  * that has no keys.
437  */
TEST_P(DrmHalVendorPluginTest,RemoveKeysNewSession)438 TEST_P(DrmHalVendorPluginTest, RemoveKeysNewSession) {
439     RETURN_IF_SKIPPED;
440     SessionId sessionId = openSession();
441     Status status = drmPlugin->removeKeys(sessionId);
442     EXPECT_TRUE(status == Status::OK);
443     closeSession(sessionId);
444 }
445 
446 /**
447  * Test that keys are successfully restored to a new session
448  * for all content having a policy that allows offline use.
449  */
TEST_P(DrmHalVendorPluginTest,RestoreKeys)450 TEST_P(DrmHalVendorPluginTest, RestoreKeys) {
451     RETURN_IF_SKIPPED;
452     for (const auto& config : contentConfigurations) {
453         if (config.policy.allowOffline) {
454             auto sessionId = openSession();
455             hidl_vec<uint8_t> keySetId =
456                     loadKeys(sessionId, config, KeyType::OFFLINE);
457             closeSession(sessionId);
458             sessionId = openSession();
459             EXPECT_NE(0u, keySetId.size());
460             Status status = drmPlugin->restoreKeys(sessionId, keySetId);
461             EXPECT_EQ(Status::OK, status);
462             closeSession(sessionId);
463         }
464     }
465 }
466 
467 /**
468  * Test that restoreKeys fails with a null key set ID.
469  * Error message is expected to be Status::BAD_VALUE.
470  */
TEST_P(DrmHalVendorPluginTest,RestoreKeysNull)471 TEST_P(DrmHalVendorPluginTest, RestoreKeysNull) {
472     RETURN_IF_SKIPPED;
473     SessionId sessionId = openSession();
474     hidl_vec<uint8_t> nullKeySetId;
475     Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId);
476     EXPECT_EQ(Status::BAD_VALUE, status);
477     closeSession(sessionId);
478 }
479 
480 /**
481  * Test that restoreKeys fails to restore keys to a closed
482  * session. Error message is expected to be
483  * Status::ERROR_DRM_SESSION_NOT_OPENED.
484  */
TEST_P(DrmHalVendorPluginTest,RestoreKeysClosedSession)485 TEST_P(DrmHalVendorPluginTest, RestoreKeysClosedSession) {
486     RETURN_IF_SKIPPED;
487     for (const auto& config : contentConfigurations) {
488         if (config.policy.allowOffline) {
489             auto sessionId = openSession();
490             hidl_vec<uint8_t> keySetId =
491                     loadKeys(sessionId, config, KeyType::OFFLINE);
492             EXPECT_NE(0u, keySetId.size());
493             closeSession(sessionId);
494             sessionId = openSession();
495             closeSession(sessionId);
496             Status status = drmPlugin->restoreKeys(sessionId, keySetId);
497             EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
498         }
499     }
500 }
501 
502 /**
503  * Test that the plugin either doesn't support getting
504  * secure stops, or has no secure stops available after
505  * clearing them.
506  */
TEST_P(DrmHalVendorPluginTest,GetSecureStops)507 TEST_P(DrmHalVendorPluginTest, GetSecureStops) {
508     RETURN_IF_SKIPPED;
509     // There may be secure stops, depending on if there were keys
510     // loaded and unloaded previously. Clear them to get to a known
511     // state, then make sure there are none.
512     auto res = drmPlugin->getSecureStops(
513             [&](Status status, const hidl_vec<SecureStop>&) {
514                 if (status != Status::OK) {
515                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
516                 }
517             });
518     EXPECT_OK(res);
519 
520     res = drmPlugin->getSecureStops(
521             [&](Status status, const hidl_vec<SecureStop>& secureStops) {
522                 if (status == Status::OK) {
523                     EXPECT_EQ(secureStops.size(), 0u);
524                 } else {
525                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
526                 }
527             });
528     EXPECT_OK(res);
529 }
530 
531 /**
532  * Test that the clearkey plugin returns BAD_VALUE if
533  * an empty ssid is provided.
534  */
TEST_P(DrmHalVendorPluginTest,GetSecureStopEmptySSID)535 TEST_P(DrmHalVendorPluginTest, GetSecureStopEmptySSID) {
536     RETURN_IF_SKIPPED;
537     SecureStopId ssid;
538     auto res = drmPlugin->getSecureStop(
539             ssid, [&](Status status, const SecureStop&) {
540                 EXPECT_EQ(Status::BAD_VALUE, status);
541             });
542     EXPECT_OK(res);
543 }
544 
545 /**
546  * Test that releasing all secure stops either isn't supported
547  * or is completed successfully
548  */
TEST_P(DrmHalVendorPluginTest,ReleaseAllSecureStops)549 TEST_P(DrmHalVendorPluginTest, ReleaseAllSecureStops) {
550     RETURN_IF_SKIPPED;
551     Status status = drmPlugin->releaseAllSecureStops();
552     EXPECT_TRUE(status == Status::OK ||
553                 status == Status::ERROR_DRM_CANNOT_HANDLE);
554 }
555 
556 /**
557  * Releasing a secure stop without first getting one and sending it to the
558  * server to get a valid SSID should return ERROR_DRM_INVALID_STATE.
559  * This is an optional API so it can also return CANNOT_HANDLE.
560  */
TEST_P(DrmHalVendorPluginTest,ReleaseSecureStopSequenceError)561 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopSequenceError) {
562     RETURN_IF_SKIPPED;
563     SecureStopId ssid = {1, 2, 3, 4};
564     Status status = drmPlugin->releaseSecureStop(ssid);
565     EXPECT_TRUE(status == Status::ERROR_DRM_INVALID_STATE ||
566                 status == Status::ERROR_DRM_CANNOT_HANDLE);
567 }
568 
569 /**
570  * Test that releasing a specific secure stop with an empty ssid
571  * return BAD_VALUE. This is an optional API so it can also return
572  * CANNOT_HANDLE.
573  */
TEST_P(DrmHalVendorPluginTest,ReleaseSecureStopEmptySSID)574 TEST_P(DrmHalVendorPluginTest, ReleaseSecureStopEmptySSID) {
575     RETURN_IF_SKIPPED;
576     SecureStopId ssid;
577     Status status = drmPlugin->releaseSecureStop(ssid);
578     EXPECT_TRUE(status == Status::BAD_VALUE ||
579                 status == Status::ERROR_DRM_CANNOT_HANDLE);
580 }
581 
582 /**
583  * The following five tests verify that the properties
584  * defined in the MediaDrm API are supported by
585  * the plugin.
586  */
TEST_P(DrmHalVendorPluginTest,GetVendorProperty)587 TEST_P(DrmHalVendorPluginTest, GetVendorProperty) {
588     RETURN_IF_SKIPPED;
589     auto res = drmPlugin->getPropertyString(
590             "vendor", [&](Status status, const hidl_string& value) {
591                 EXPECT_EQ(Status::OK, status);
592                 EXPECT_NE(value.size(), 0u);
593             });
594     EXPECT_OK(res);
595 }
596 
TEST_P(DrmHalVendorPluginTest,GetVersionProperty)597 TEST_P(DrmHalVendorPluginTest, GetVersionProperty) {
598     RETURN_IF_SKIPPED;
599     auto res = drmPlugin->getPropertyString(
600             "version", [&](Status status, const hidl_string& value) {
601                 EXPECT_EQ(Status::OK, status);
602                 EXPECT_NE(value.size(), 0u);
603             });
604     EXPECT_OK(res);
605 }
606 
TEST_P(DrmHalVendorPluginTest,GetDescriptionProperty)607 TEST_P(DrmHalVendorPluginTest, GetDescriptionProperty) {
608     RETURN_IF_SKIPPED;
609     auto res = drmPlugin->getPropertyString(
610             "description", [&](Status status, const hidl_string& value) {
611                 EXPECT_EQ(Status::OK, status);
612                 EXPECT_NE(value.size(), 0u);
613             });
614     EXPECT_OK(res);
615 }
616 
TEST_P(DrmHalVendorPluginTest,GetAlgorithmsProperty)617 TEST_P(DrmHalVendorPluginTest, GetAlgorithmsProperty) {
618     RETURN_IF_SKIPPED;
619     auto res = drmPlugin->getPropertyString(
620             "algorithms", [&](Status status, const hidl_string& value) {
621                 if (status == Status::OK) {
622                     EXPECT_NE(value.size(), 0u);
623                 } else {
624                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
625                 }
626             });
627     EXPECT_OK(res);
628 }
629 
TEST_P(DrmHalVendorPluginTest,GetPropertyUniqueDeviceID)630 TEST_P(DrmHalVendorPluginTest, GetPropertyUniqueDeviceID) {
631     RETURN_IF_SKIPPED;
632     auto res = drmPlugin->getPropertyByteArray(
633             "deviceUniqueId",
634             [&](Status status, const hidl_vec<uint8_t>& value) {
635                 if (status == Status::OK) {
636                     EXPECT_NE(value.size(), 0u);
637                 } else {
638                     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
639                 }
640             });
641     EXPECT_OK(res);
642 }
643 
644 /**
645  * Test that attempting to read invalid string and byte array
646  * properties returns the documented error code.
647  */
TEST_P(DrmHalVendorPluginTest,GetInvalidStringProperty)648 TEST_P(DrmHalVendorPluginTest, GetInvalidStringProperty) {
649     RETURN_IF_SKIPPED;
650     auto res = drmPlugin->getPropertyString(
651             "invalid", [&](Status status, const hidl_string&) {
652                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
653             });
654     EXPECT_OK(res);
655 }
656 
TEST_P(DrmHalVendorPluginTest,GetInvalidByteArrayProperty)657 TEST_P(DrmHalVendorPluginTest, GetInvalidByteArrayProperty) {
658     RETURN_IF_SKIPPED;
659     auto res = drmPlugin->getPropertyByteArray(
660             "invalid", [&](Status status, const hidl_vec<uint8_t>&) {
661                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
662             });
663     EXPECT_OK(res);
664 }
665 
666 /**
667  * Test that setting invalid string and byte array properties returns
668  * the expected status value.
669  */
TEST_P(DrmHalVendorPluginTest,SetStringPropertyNotSupported)670 TEST_P(DrmHalVendorPluginTest, SetStringPropertyNotSupported) {
671     RETURN_IF_SKIPPED;
672     EXPECT_EQ(drmPlugin->setPropertyString("awefijaeflijwef", "value"),
673               Status::ERROR_DRM_CANNOT_HANDLE);
674 }
675 
TEST_P(DrmHalVendorPluginTest,SetByteArrayPropertyNotSupported)676 TEST_P(DrmHalVendorPluginTest, SetByteArrayPropertyNotSupported) {
677     RETURN_IF_SKIPPED;
678     hidl_vec<uint8_t> value;
679     EXPECT_EQ(drmPlugin->setPropertyByteArray("awefijaeflijwef", value),
680               Status::ERROR_DRM_CANNOT_HANDLE);
681 }
682 
683 /**
684  * Test that setting an invalid cipher algorithm returns
685  * the expected status value.
686  */
TEST_P(DrmHalVendorPluginTest,SetCipherInvalidAlgorithm)687 TEST_P(DrmHalVendorPluginTest, SetCipherInvalidAlgorithm) {
688     RETURN_IF_SKIPPED;
689     SessionId session = openSession();
690     hidl_string algorithm;
691     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
692     EXPECT_EQ(Status::BAD_VALUE, status);
693     closeSession(session);
694 }
695 
696 /**
697  * Test that setting a cipher algorithm with no session returns
698  * the expected status value.
699  */
TEST_P(DrmHalVendorPluginTest,SetCipherAlgorithmNoSession)700 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithmNoSession) {
701     RETURN_IF_SKIPPED;
702     SessionId session;
703     hidl_string algorithm = "AES/CBC/NoPadding";
704     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
705     EXPECT_EQ(Status::BAD_VALUE, status);
706 }
707 
708 /**
709  * Test that setting a valid cipher algorithm returns
710  * the expected status value. It is not required that all
711  * vendor modules support this algorithm, but they must
712  * either accept it or return ERROR_DRM_CANNOT_HANDLE
713  */
TEST_P(DrmHalVendorPluginTest,SetCipherAlgorithm)714 TEST_P(DrmHalVendorPluginTest, SetCipherAlgorithm) {
715     RETURN_IF_SKIPPED;
716     SessionId session = openSession();
717     ;
718     hidl_string algorithm = "AES/CBC/NoPadding";
719     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
720     EXPECT_TRUE(status == Status::OK ||
721                 status == Status::ERROR_DRM_CANNOT_HANDLE);
722     closeSession(session);
723 }
724 
725 /**
726  * Test that setting an invalid mac algorithm returns
727  * the expected status value.
728  */
TEST_P(DrmHalVendorPluginTest,SetMacInvalidAlgorithm)729 TEST_P(DrmHalVendorPluginTest, SetMacInvalidAlgorithm) {
730     RETURN_IF_SKIPPED;
731     SessionId session = openSession();
732     hidl_string algorithm;
733     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
734     EXPECT_EQ(Status::BAD_VALUE, status);
735     closeSession(session);
736 }
737 
738 /**
739  * Test that setting a mac algorithm with no session returns
740  * the expected status value.
741  */
TEST_P(DrmHalVendorPluginTest,SetMacNullAlgorithmNoSession)742 TEST_P(DrmHalVendorPluginTest, SetMacNullAlgorithmNoSession) {
743     RETURN_IF_SKIPPED;
744     SessionId session;
745     hidl_string algorithm = "HmacSHA256";
746     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
747     EXPECT_EQ(Status::BAD_VALUE, status);
748 }
749 
750 /**
751  * Test that setting a valid mac algorithm returns
752  * the expected status value. It is not required that all
753  * vendor modules support this algorithm, but they must
754  * either accept it or return ERROR_DRM_CANNOT_HANDLE
755  */
TEST_P(DrmHalVendorPluginTest,SetMacAlgorithm)756 TEST_P(DrmHalVendorPluginTest, SetMacAlgorithm) {
757     RETURN_IF_SKIPPED;
758     SessionId session = openSession();
759     hidl_string algorithm = "HmacSHA256";
760     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
761     EXPECT_TRUE(status == Status::OK ||
762                 status == Status::ERROR_DRM_CANNOT_HANDLE);
763     closeSession(session);
764 }
765 
766 /**
767  * The Generic* methods provide general purpose crypto operations
768  * that may be used for applications other than DRM. They leverage
769  * the hardware root of trust and secure key distribution mechanisms
770  * of a DRM system to enable app-specific crypto functionality where
771  * the crypto keys are not exposed outside of the trusted execution
772  * environment.
773  *
774  * Generic encrypt/decrypt/sign/verify should fail on invalid
775  * inputs, e.g. empty sessionId
776  */
TEST_P(DrmHalVendorPluginTest,GenericEncryptNoSession)777 TEST_P(DrmHalVendorPluginTest, GenericEncryptNoSession) {
778     RETURN_IF_SKIPPED;
779     SessionId session;
780     hidl_vec<uint8_t> keyId, input, iv;
781     auto res = drmPlugin->encrypt(
782             session, keyId, input, iv,
783             [&](Status status, const hidl_vec<uint8_t>&) {
784                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
785             });
786     EXPECT_OK(res);
787 }
788 
TEST_P(DrmHalVendorPluginTest,GenericDecryptNoSession)789 TEST_P(DrmHalVendorPluginTest, GenericDecryptNoSession) {
790     RETURN_IF_SKIPPED;
791     SessionId session;
792     hidl_vec<uint8_t> keyId, input, iv;
793     auto res = drmPlugin->decrypt(
794             session, keyId, input, iv,
795             [&](Status status, const hidl_vec<uint8_t>&) {
796                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
797             });
798     EXPECT_OK(res);
799 }
800 
TEST_P(DrmHalVendorPluginTest,GenericSignNoSession)801 TEST_P(DrmHalVendorPluginTest, GenericSignNoSession) {
802     RETURN_IF_SKIPPED;
803     SessionId session;
804     hidl_vec<uint8_t> keyId, message;
805     auto res = drmPlugin->sign(
806             session, keyId, message,
807             [&](Status status, const hidl_vec<uint8_t>&) {
808                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
809             });
810     EXPECT_OK(res);
811 }
812 
TEST_P(DrmHalVendorPluginTest,GenericVerifyNoSession)813 TEST_P(DrmHalVendorPluginTest, GenericVerifyNoSession) {
814     RETURN_IF_SKIPPED;
815     SessionId session;
816     hidl_vec<uint8_t> keyId, message, signature;
817     auto res = drmPlugin->verify(
818             session, keyId, message, signature, [&](Status status, bool) {
819                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
820             });
821     EXPECT_OK(res);
822 }
823 
TEST_P(DrmHalVendorPluginTest,GenericSignRSANoSession)824 TEST_P(DrmHalVendorPluginTest, GenericSignRSANoSession) {
825     RETURN_IF_SKIPPED;
826     SessionId session;
827     hidl_string algorithm;
828     hidl_vec<uint8_t> message, wrappedKey;
829     auto res = drmPlugin->signRSA(session, algorithm, message, wrappedKey,
830                                   [&](Status status, const hidl_vec<uint8_t>&) {
831                                       EXPECT_EQ(Status::BAD_VALUE, status);
832                                   });
833     EXPECT_OK(res);
834 }
835 
836 /**
837  * Exercise the requiresSecureDecoderComponent method. Additional tests
838  * will verify positive cases with specific vendor content configurations.
839  * Below we just test the negative cases.
840  */
841 
842 /**
843  * Verify that requiresSecureDecoderComponent handles empty mimetype.
844  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderEmptyMimeType)845 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderEmptyMimeType) {
846     RETURN_IF_SKIPPED;
847     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent(""));
848 }
849 
850 /**
851  * Verify that requiresSecureDecoderComponent handles invalid mimetype.
852  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderInvalidMimeType)853 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderInvalidMimeType) {
854     RETURN_IF_SKIPPED;
855     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("bad"));
856 }
857 
858 /**
859  * Verify that requiresSecureDecoderComponent returns true for secure
860  * configurations
861  */
TEST_P(DrmHalVendorPluginTest,RequiresSecureDecoderConfig)862 TEST_P(DrmHalVendorPluginTest, RequiresSecureDecoderConfig) {
863     RETURN_IF_SKIPPED;
864     for (const auto& config : contentConfigurations) {
865         for (const auto& key : config.keys) {
866             if (key.isSecure) {
867                 EXPECT_TRUE(cryptoPlugin->requiresSecureDecoderComponent(config.mimeType));
868                 break;
869             }
870         }
871     }
872 }
873 
874 /**
875  *  Event Handling tests
876  */
877 struct ListenerEventArgs {
878     EventType eventType;
879     SessionId sessionId;
880     hidl_vec<uint8_t> data;
881     int64_t expiryTimeInMS;
882     hidl_vec<KeyStatus> keyStatusList;
883     bool hasNewUsableKey;
884 };
885 
886 const char *kCallbackEvent = "SendEvent";
887 const char *kCallbackExpirationUpdate = "SendExpirationUpdate";
888 const char *kCallbackKeysChange = "SendKeysChange";
889 
890 class TestDrmPluginListener
891     : public ::testing::VtsHalHidlTargetCallbackBase<ListenerEventArgs>,
892       public IDrmPluginListener {
893 public:
TestDrmPluginListener()894     TestDrmPluginListener() {
895         SetWaitTimeoutDefault(std::chrono::milliseconds(500));
896     }
~TestDrmPluginListener()897     virtual ~TestDrmPluginListener() {}
898 
sendEvent(EventType eventType,const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & data)899     virtual Return<void> sendEvent(EventType eventType, const hidl_vec<uint8_t>& sessionId,
900             const hidl_vec<uint8_t>& data) override {
901         ListenerEventArgs args;
902         args.eventType = eventType;
903         args.sessionId = sessionId;
904         args.data = data;
905         NotifyFromCallback(kCallbackEvent, args);
906         return Void();
907     }
908 
sendExpirationUpdate(const hidl_vec<uint8_t> & sessionId,int64_t expiryTimeInMS)909     virtual Return<void> sendExpirationUpdate(const hidl_vec<uint8_t>& sessionId,
910             int64_t expiryTimeInMS) override {
911         ListenerEventArgs args;
912         args.sessionId = sessionId;
913         args.expiryTimeInMS = expiryTimeInMS;
914         NotifyFromCallback(kCallbackExpirationUpdate, args);
915         return Void();
916     }
917 
sendKeysChange(const hidl_vec<uint8_t> & sessionId,const hidl_vec<KeyStatus> & keyStatusList,bool hasNewUsableKey)918     virtual Return<void> sendKeysChange(const hidl_vec<uint8_t>& sessionId,
919             const hidl_vec<KeyStatus>& keyStatusList, bool hasNewUsableKey) override {
920         ListenerEventArgs args;
921         args.sessionId = sessionId;
922         args.keyStatusList = keyStatusList;
923         args.hasNewUsableKey = hasNewUsableKey;
924         NotifyFromCallback(kCallbackKeysChange, args);
925         return Void();
926     }
927 };
928 
929 
930 /**
931  * Simulate the plugin sending events. Make sure the listener
932  * gets them.
933  */
TEST_P(DrmHalVendorPluginTest,ListenerEvents)934 TEST_P(DrmHalVendorPluginTest, ListenerEvents) {
935     RETURN_IF_SKIPPED;
936     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
937     drmPlugin->setListener(listener);
938     auto sessionId = openSession();
939     hidl_vec<uint8_t> data = {0, 1, 2};
940     EventType eventTypes[] = {EventType::PROVISION_REQUIRED,
941                               EventType::KEY_NEEDED,
942                               EventType::KEY_EXPIRED,
943                               EventType::VENDOR_DEFINED,
944                               EventType::SESSION_RECLAIMED};
945     for (auto eventType : eventTypes) {
946         drmPlugin->sendEvent(eventType, sessionId, data);
947         auto result = listener->WaitForCallback(kCallbackEvent);
948         EXPECT_TRUE(result.no_timeout);
949         EXPECT_TRUE(result.args);
950         EXPECT_EQ(eventType, result.args->eventType);
951         EXPECT_EQ(sessionId, result.args->sessionId);
952         EXPECT_EQ(data, result.args->data);
953     }
954     closeSession(sessionId);
955 }
956 
957 /**
958  * Simulate the plugin sending expiration updates and make sure
959  * the listener gets them.
960  */
TEST_P(DrmHalVendorPluginTest,ListenerExpirationUpdate)961 TEST_P(DrmHalVendorPluginTest, ListenerExpirationUpdate) {
962     RETURN_IF_SKIPPED;
963     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
964     drmPlugin->setListener(listener);
965     auto sessionId = openSession();
966     drmPlugin->sendExpirationUpdate(sessionId, 100);
967     auto result = listener->WaitForCallback(kCallbackExpirationUpdate);
968     EXPECT_TRUE(result.no_timeout);
969     EXPECT_TRUE(result.args);
970     EXPECT_EQ(sessionId, result.args->sessionId);
971     EXPECT_EQ(100, result.args->expiryTimeInMS);
972     closeSession(sessionId);
973 }
974 
975 /**
976  * Simulate the plugin sending keys change and make sure
977  * the listener gets them.
978  */
TEST_P(DrmHalVendorPluginTest,ListenerKeysChange)979 TEST_P(DrmHalVendorPluginTest, ListenerKeysChange) {
980     RETURN_IF_SKIPPED;
981     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
982     drmPlugin->setListener(listener);
983     auto sessionId = openSession();
984     const hidl_vec<KeyStatus> keyStatusList = {
985         {{1}, KeyStatusType::USABLE},
986         {{2}, KeyStatusType::EXPIRED},
987         {{3}, KeyStatusType::OUTPUTNOTALLOWED},
988         {{4}, KeyStatusType::STATUSPENDING},
989         {{5}, KeyStatusType::INTERNALERROR},
990     };
991 
992     drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
993     auto result = listener->WaitForCallback(kCallbackKeysChange);
994     EXPECT_TRUE(result.no_timeout);
995     EXPECT_TRUE(result.args);
996     EXPECT_EQ(sessionId, result.args->sessionId);
997     EXPECT_EQ(keyStatusList, result.args->keyStatusList);
998     closeSession(sessionId);
999 }
1000 
1001 /**
1002  * Negative listener tests. Call send methods with no
1003  * listener set.
1004  */
TEST_P(DrmHalVendorPluginTest,NotListening)1005 TEST_P(DrmHalVendorPluginTest, NotListening) {
1006     RETURN_IF_SKIPPED;
1007     sp<TestDrmPluginListener> listener = new TestDrmPluginListener();
1008     drmPlugin->setListener(listener);
1009     drmPlugin->setListener(nullptr);
1010 
1011     SessionId sessionId;
1012     hidl_vec<uint8_t> data;
1013     hidl_vec<KeyStatus> keyStatusList;
1014     drmPlugin->sendEvent(EventType::PROVISION_REQUIRED, sessionId, data);
1015     drmPlugin->sendExpirationUpdate(sessionId, 100);
1016     drmPlugin->sendKeysChange(sessionId, keyStatusList, true);
1017     auto result = listener->WaitForCallbackAny(
1018             {kCallbackEvent, kCallbackExpirationUpdate, kCallbackKeysChange});
1019     EXPECT_FALSE(result.no_timeout);
1020 }
1021 
1022 
1023 /**
1024  *  CryptoPlugin tests
1025  */
1026 
1027 /**
1028  * Exercise the NotifyResolution API. There is no observable result,
1029  * just call the method for coverage.
1030  */
TEST_P(DrmHalVendorPluginTest,NotifyResolution)1031 TEST_P(DrmHalVendorPluginTest, NotifyResolution) {
1032     RETURN_IF_SKIPPED;
1033     cryptoPlugin->notifyResolution(1920, 1080);
1034 }
1035 
1036 /**
1037  * getDecryptMemory allocates memory for decryption, then sets it
1038  * as a shared buffer base in the crypto hal.  The allocated and
1039  * mapped IMemory is returned.
1040  *
1041  * @param size the size of the memory segment to allocate
1042  * @param the index of the memory segment which will be used
1043  * to refer to it for decryption.
1044  */
getDecryptMemory(size_t size,size_t index)1045 sp<IMemory> DrmHalVendorPluginTest::getDecryptMemory(size_t size,
1046                                                      size_t index) {
1047     sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
1048     EXPECT_NE(nullptr, ashmemAllocator.get());
1049 
1050     hidl_memory hidlMemory;
1051     auto res = ashmemAllocator->allocate(
1052             size, [&](bool success, const hidl_memory& memory) {
1053                 EXPECT_EQ(success, true);
1054                 EXPECT_EQ(memory.size(), size);
1055                 hidlMemory = memory;
1056             });
1057 
1058     EXPECT_OK(res);
1059 
1060     sp<IMemory> mappedMemory = android::hardware::mapMemory(hidlMemory);
1061     EXPECT_NE(nullptr, mappedMemory.get());
1062     res = cryptoPlugin->setSharedBufferBase(hidlMemory, index);
1063     EXPECT_OK(res);
1064     return mappedMemory;
1065 }
1066 
1067 /**
1068  * Exercise the setMediaDrmSession method. setMediaDrmSession
1069  * is used to associate a drm session with a crypto session.
1070  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSession)1071 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSession) {
1072     RETURN_IF_SKIPPED;
1073     auto sessionId = openSession();
1074     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1075     EXPECT_EQ(Status::OK, status);
1076     closeSession(sessionId);
1077 }
1078 
1079 /**
1080  * setMediaDrmSession with a closed session id
1081  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSessionClosedSession)1082 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionClosedSession) {
1083     RETURN_IF_SKIPPED;
1084     auto sessionId = openSession();
1085     closeSession(sessionId);
1086     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1087     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
1088 }
1089 
1090 /**
1091  * setMediaDrmSession with a empty session id: BAD_VALUE
1092  */
TEST_P(DrmHalVendorPluginTest,SetMediaDrmSessionEmptySession)1093 TEST_P(DrmHalVendorPluginTest, SetMediaDrmSessionEmptySession) {
1094     RETURN_IF_SKIPPED;
1095     SessionId sessionId;
1096     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1097     EXPECT_EQ(Status::BAD_VALUE, status);
1098 }
1099 
1100 /**
1101  * Decrypt tests
1102  */
1103 
fillRandom(const sp<IMemory> & memory)1104 void DrmHalVendorDecryptTest::fillRandom(const sp<IMemory>& memory) {
1105     random_device rd;
1106     mt19937 rand(rd());
1107     for (size_t i = 0; i < memory->getSize() / sizeof(uint32_t); i++) {
1108         auto p = static_cast<uint32_t*>(
1109                 static_cast<void*>(memory->getPointer()));
1110         p[i] = rand();
1111     }
1112 }
1113 
queryKeyStatus(SessionId sessionId)1114 hidl_vec<KeyValue> DrmHalVendorDecryptTest::queryKeyStatus(SessionId sessionId) {
1115     hidl_vec<KeyValue> keyStatus;
1116     auto res = drmPlugin->queryKeyStatus(sessionId,
1117             [&](Status status, KeyedVector info) {
1118                 EXPECT_EQ(Status::OK, status);
1119                 keyStatus = info;
1120             });
1121     EXPECT_OK(res);
1122     return keyStatus;
1123 }
1124 
removeKeys(SessionId sessionId)1125 void DrmHalVendorDecryptTest::removeKeys(SessionId sessionId) {
1126     auto res = drmPlugin->removeKeys(sessionId);
1127     EXPECT_OK(res);
1128 }
1129 
decrypt(Mode mode,bool isSecure,const hidl_array<uint8_t,16> & keyId,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const Pattern & pattern,const vector<uint8_t> & key,Status expectedStatus)1130 uint32_t DrmHalVendorDecryptTest::decrypt(Mode mode, bool isSecure,
1131         const hidl_array<uint8_t, 16>& keyId, uint8_t* iv,
1132         const hidl_vec<SubSample>& subSamples, const Pattern& pattern,
1133         const vector<uint8_t>& key, Status expectedStatus) {
1134     const size_t kSegmentIndex = 0;
1135 
1136     uint8_t localIv[AES_BLOCK_SIZE];
1137     memcpy(localIv, iv, AES_BLOCK_SIZE);
1138 
1139     size_t totalSize = 0;
1140     for (size_t i = 0; i < subSamples.size(); i++) {
1141         totalSize += subSamples[i].numBytesOfClearData;
1142         totalSize += subSamples[i].numBytesOfEncryptedData;
1143     }
1144 
1145     // The first totalSize bytes of shared memory is the encrypted
1146     // input, the second totalSize bytes is the decrypted output.
1147     sp<IMemory> sharedMemory =
1148             getDecryptMemory(totalSize * 2, kSegmentIndex);
1149 
1150     SharedBuffer sourceBuffer = {
1151             .bufferId = kSegmentIndex, .offset = 0, .size = totalSize};
1152     fillRandom(sharedMemory);
1153 
1154     DestinationBuffer destBuffer = {.type = BufferType::SHARED_MEMORY,
1155                                     {.bufferId = kSegmentIndex,
1156                                      .offset = totalSize,
1157                                      .size = totalSize},
1158                                     .secureMemory = nullptr};
1159     uint64_t offset = 0;
1160     uint32_t bytesWritten = 0;
1161     auto res = cryptoPlugin->decrypt(isSecure, keyId, localIv, mode, pattern,
1162             subSamples, sourceBuffer, offset, destBuffer,
1163             [&](Status status, uint32_t count, string detailedError) {
1164                 EXPECT_EQ(expectedStatus, status) << "Unexpected decrypt status " <<
1165                 detailedError;
1166                 bytesWritten = count;
1167             });
1168     EXPECT_OK(res);
1169 
1170     if (bytesWritten != totalSize) {
1171         return bytesWritten;
1172     }
1173     uint8_t* base = static_cast<uint8_t*>(
1174             static_cast<void*>(sharedMemory->getPointer()));
1175 
1176     // generate reference vector
1177     vector<uint8_t> reference(totalSize);
1178 
1179     memcpy(localIv, iv, AES_BLOCK_SIZE);
1180     switch (mode) {
1181     case Mode::UNENCRYPTED:
1182         memcpy(&reference[0], base, totalSize);
1183         break;
1184     case Mode::AES_CTR:
1185         aes_ctr_decrypt(&reference[0], base, localIv, subSamples, key);
1186         break;
1187     case Mode::AES_CBC:
1188         aes_cbc_decrypt(&reference[0], base, localIv, subSamples, key);
1189         break;
1190     case Mode::AES_CBC_CTS:
1191         EXPECT_TRUE(false) << "AES_CBC_CTS mode not supported";
1192         break;
1193     }
1194 
1195     // compare reference to decrypted data which is at base + total size
1196     EXPECT_EQ(0, memcmp(static_cast<void*>(&reference[0]),
1197                         static_cast<void*>(base + totalSize), totalSize))
1198             << "decrypt data mismatch";
1199     return totalSize;
1200 }
1201 
1202 /**
1203  * Decrypt a list of clear+encrypted subsamples using the specified key
1204  * in AES-CTR mode
1205  */
aes_ctr_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)1206 void DrmHalVendorDecryptTest::aes_ctr_decrypt(uint8_t* dest, uint8_t* src,
1207         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
1208         const vector<uint8_t>& key) {
1209 
1210     AES_KEY decryptionKey;
1211     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
1212 
1213     size_t offset = 0;
1214     unsigned blockOffset = 0;
1215     uint8_t previousEncryptedCounter[AES_BLOCK_SIZE];
1216     memset(previousEncryptedCounter, 0, AES_BLOCK_SIZE);
1217 
1218     for (size_t i = 0; i < subSamples.size(); i++) {
1219         const SubSample& subSample = subSamples[i];
1220 
1221         if (subSample.numBytesOfClearData > 0) {
1222             memcpy(dest + offset, src + offset, subSample.numBytesOfClearData);
1223             offset += subSample.numBytesOfClearData;
1224         }
1225 
1226         if (subSample.numBytesOfEncryptedData > 0) {
1227             AES_ctr128_encrypt(src + offset, dest + offset,
1228                     subSample.numBytesOfEncryptedData, &decryptionKey,
1229                     iv, previousEncryptedCounter, &blockOffset);
1230             offset += subSample.numBytesOfEncryptedData;
1231         }
1232     }
1233 }
1234 
1235 /**
1236  * Decrypt a list of clear+encrypted subsamples using the specified key
1237  * in AES-CBC mode
1238  */
aes_cbc_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)1239 void DrmHalVendorDecryptTest::aes_cbc_decrypt(uint8_t* dest, uint8_t* src,
1240         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
1241         const vector<uint8_t>& key) {
1242     AES_KEY decryptionKey;
1243     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
1244 
1245     size_t offset = 0;
1246     for (size_t i = 0; i < subSamples.size(); i++) {
1247         const SubSample& subSample = subSamples[i];
1248 
1249         memcpy(dest + offset, src + offset, subSample.numBytesOfClearData);
1250         offset += subSample.numBytesOfClearData;
1251 
1252         AES_cbc_encrypt(src + offset, dest + offset, subSample.numBytesOfEncryptedData,
1253                 &decryptionKey, iv, 0 /* decrypt */);
1254         offset += subSample.numBytesOfEncryptedData;
1255     }
1256 }
1257 
1258 
1259 /**
1260  * Test key status with empty session id, should return BAD_VALUE
1261  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatusInvalidSession)1262 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusInvalidSession) {
1263     RETURN_IF_SKIPPED;
1264     SessionId sessionId;
1265     auto res = drmPlugin->queryKeyStatus(sessionId,
1266             [&](Status status, KeyedVector /* info */) {
1267                 EXPECT_EQ(Status::BAD_VALUE, status);
1268             });
1269     EXPECT_OK(res);
1270 }
1271 
1272 
1273 /**
1274  * Test key status.  There should be no key status prior to loading keys
1275  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatusWithNoKeys)1276 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatusWithNoKeys) {
1277     RETURN_IF_SKIPPED;
1278     auto sessionId = openSession();
1279     auto keyStatus = queryKeyStatus(sessionId);
1280     EXPECT_EQ(0u, keyStatus.size());
1281     closeSession(sessionId);
1282 }
1283 
1284 
1285 /**
1286  * Test key status.  There should be key status after loading keys.
1287  */
TEST_P(DrmHalVendorDecryptTest,QueryKeyStatus)1288 TEST_P(DrmHalVendorDecryptTest, QueryKeyStatus) {
1289     RETURN_IF_SKIPPED;
1290     for (const auto& config : contentConfigurations) {
1291         auto sessionId = openSession();
1292         loadKeys(sessionId, config);
1293         auto keyStatus = queryKeyStatus(sessionId);
1294         EXPECT_NE(0u, keyStatus.size());
1295         closeSession(sessionId);
1296     }
1297 }
1298 
1299 /**
1300  * Positive decrypt test. "Decrypt" a single clear segment and verify.
1301  */
TEST_P(DrmHalVendorDecryptTest,ClearSegmentTest)1302 TEST_P(DrmHalVendorDecryptTest, ClearSegmentTest) {
1303     RETURN_IF_SKIPPED;
1304     for (const auto& config : contentConfigurations) {
1305         for (const auto& key : config.keys) {
1306             const size_t kSegmentSize = 1024;
1307             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1308             const Pattern noPattern = {0, 0};
1309             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
1310                                                    .numBytesOfEncryptedData = 0}};
1311             auto sessionId = openSession();
1312             loadKeys(sessionId, config);
1313 
1314             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1315             EXPECT_EQ(Status::OK, status);
1316 
1317             uint32_t byteCount = decrypt(Mode::UNENCRYPTED, key.isSecure, toHidlArray(key.keyId),
1318                     &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK);
1319             EXPECT_EQ(kSegmentSize, byteCount);
1320 
1321             closeSession(sessionId);
1322         }
1323     }
1324 }
1325 
1326 /**
1327  * Positive decrypt test.  Decrypt a single segment using aes_ctr.
1328  * Verify data matches.
1329  */
TEST_P(DrmHalVendorDecryptTest,EncryptedAesCtrSegmentTest)1330 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTest) {
1331     RETURN_IF_SKIPPED;
1332     for (const auto& config : contentConfigurations) {
1333         for (const auto& key : config.keys) {
1334             const size_t kSegmentSize = 1024;
1335             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1336             const Pattern noPattern = {0, 0};
1337             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
1338                                                    .numBytesOfEncryptedData = 0}};
1339             auto sessionId = openSession();
1340             loadKeys(sessionId, config);
1341 
1342             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1343             EXPECT_EQ(Status::OK, status);
1344 
1345             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, toHidlArray(key.keyId),
1346                     &iv[0], subSamples, noPattern, key.clearContentKey, Status::OK);
1347             EXPECT_EQ(kSegmentSize, byteCount);
1348 
1349             closeSession(sessionId);
1350         }
1351     }
1352 }
1353 
1354 /**
1355  * Negative decrypt test. Decrypt without loading keys.
1356  */
TEST_P(DrmHalVendorDecryptTest,EncryptedAesCtrSegmentTestNoKeys)1357 TEST_P(DrmHalVendorDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
1358     RETURN_IF_SKIPPED;
1359     for (const auto& config : contentConfigurations) {
1360         for (const auto& key : config.keys) {
1361             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1362             const Pattern noPattern = {0, 0};
1363             const vector<SubSample> subSamples = {{.numBytesOfClearData = 256,
1364                                                    .numBytesOfEncryptedData = 256}};
1365             auto sessionId = openSession();
1366 
1367             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1368             EXPECT_EQ(Status::OK, status);
1369 
1370             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
1371                     toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
1372                     key.clearContentKey, Status::ERROR_DRM_NO_LICENSE);
1373             EXPECT_EQ(0u, byteCount);
1374 
1375             closeSession(sessionId);
1376         }
1377     }
1378 }
1379 
1380 /**
1381  * Test key removal.  Load keys then remove them and verify that
1382  * decryption can't be performed.
1383  */
TEST_P(DrmHalVendorDecryptTest,AttemptDecryptWithKeysRemoved)1384 TEST_P(DrmHalVendorDecryptTest, AttemptDecryptWithKeysRemoved) {
1385     RETURN_IF_SKIPPED;
1386     for (const auto& config : contentConfigurations) {
1387         for (const auto& key : config.keys) {
1388             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1389             const Pattern noPattern = {0, 0};
1390             const vector<SubSample> subSamples = {{.numBytesOfClearData = 256,
1391                                                    .numBytesOfEncryptedData = 256}};
1392             auto sessionId = openSession();
1393 
1394             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
1395             EXPECT_EQ(Status::OK, status);
1396 
1397             loadKeys(sessionId, config);
1398             removeKeys(sessionId);
1399 
1400             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
1401                     toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
1402                     key.clearContentKey, Status::ERROR_DRM_NO_LICENSE);
1403             EXPECT_EQ(0u, byteCount);
1404 
1405             closeSession(sessionId);
1406         }
1407     }
1408 }
1409 
1410 }  // namespace vts
1411 }  // namespace V1_0
1412 }  // namespace drm
1413 }  // namespace hardware
1414 }  // namespace android
1415