• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #define LOG_TAG "drm_hal_test@1.2"
18 
19 #include <gtest/gtest.h>
20 #include <hidl/HidlSupport.h>
21 #include <log/log.h>
22 #include <openssl/aes.h>
23 
24 #include "drm_hal_common.h"
25 
26 using ::android::hardware::drm::V1_0::Status;
27 using ::android::hardware::drm::V1_1::KeyRequestType;
28 using ::android::hardware::drm::V1_1::SecurityLevel;
29 using ::android::hardware::drm::V1_2::HdcpLevel;
30 using ::android::hardware::drm::V1_2::KeySetId;
31 using ::android::hardware::drm::V1_2::KeyStatus;
32 using ::android::hardware::drm::V1_2::KeyStatusType;
33 using ::android::hardware::drm::V1_2::OfflineLicenseState;
34 
35 using ::android::hardware::drm::V1_2::vts::DrmHalClearkeyTest;
36 using ::android::hardware::drm::V1_2::vts::DrmHalPluginListener;
37 using ::android::hardware::drm::V1_2::vts::DrmHalTest;
38 using ::android::hardware::drm::V1_2::vts::DrmHidlEnvironment;
39 using ::android::hardware::drm::V1_2::vts::kCallbackLostState;
40 using ::android::hardware::drm::V1_2::vts::kCallbackKeysChange;
41 
42 using ::android::hardware::hidl_string;
43 
44 static const char* const kVideoMp4 = "video/mp4";
45 static const char* const kBadMime = "video/unknown";
46 static const char* const kDrmErrorTestKey = "drmErrorTest";
47 static const char* const kDrmErrorInvalidState = "invalidState";
48 static const char* const kDrmErrorResourceContention = "resourceContention";
49 static const SecurityLevel kSwSecureCrypto = SecurityLevel::SW_SECURE_CRYPTO;
50 
51 /**
52  * Ensure drm factory supports module UUID Scheme
53  */
TEST_P(DrmHalTest,VendorUuidSupported)54 TEST_P(DrmHalTest, VendorUuidSupported) {
55     auto res = drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kVideoMp4, kSwSecureCrypto);
56     ALOGI("kVideoMp4 = %s res %d", kVideoMp4, (bool)res);
57     EXPECT_TRUE(res);
58 }
59 
60 /**
61  * Ensure drm factory doesn't support an invalid scheme UUID
62  */
TEST_P(DrmHalTest,InvalidPluginNotSupported)63 TEST_P(DrmHalTest, InvalidPluginNotSupported) {
64     const uint8_t kInvalidUUID[16] = {
65         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
66         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
67     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(kInvalidUUID, kVideoMp4, kSwSecureCrypto));
68 }
69 
70 /**
71  * Ensure drm factory doesn't support an empty UUID
72  */
TEST_P(DrmHalTest,EmptyPluginUUIDNotSupported)73 TEST_P(DrmHalTest, EmptyPluginUUIDNotSupported) {
74     hidl_array<uint8_t, 16> emptyUUID;
75     memset(emptyUUID.data(), 0, 16);
76     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(emptyUUID, kVideoMp4, kSwSecureCrypto));
77 }
78 
79 /**
80  * Ensure drm factory doesn't support an invalid mime type
81  */
TEST_P(DrmHalTest,BadMimeNotSupported)82 TEST_P(DrmHalTest, BadMimeNotSupported) {
83     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kBadMime, kSwSecureCrypto));
84 }
85 
86 /**
87  *  DrmPlugin tests
88  */
89 
90 /**
91  * Test that a DRM plugin can handle provisioning.  While
92  * it is not required that a DRM scheme require provisioning,
93  * it should at least return appropriate status values. If
94  * a provisioning request is returned, it is passed to the
95  * vendor module which should provide a provisioning response
96  * that is delivered back to the HAL.
97  */
TEST_P(DrmHalTest,DoProvisioning)98 TEST_P(DrmHalTest, DoProvisioning) {
99     RETURN_IF_SKIPPED;
100     hidl_string certificateType;
101     hidl_string certificateAuthority;
102     hidl_vec<uint8_t> provisionRequest;
103     hidl_string defaultUrl;
104     auto res = drmPlugin->getProvisionRequest_1_2(
105             certificateType, certificateAuthority,
106             [&](StatusV1_2 status, const hidl_vec<uint8_t>& request,
107                 const hidl_string& url) {
108                 if (status == StatusV1_2::OK) {
109                     EXPECT_NE(request.size(), 0u);
110                     provisionRequest = request;
111                     defaultUrl = url;
112                 } else if (status == StatusV1_2::ERROR_DRM_CANNOT_HANDLE) {
113                     EXPECT_EQ(0u, request.size());
114                 }
115             });
116     EXPECT_OK(res);
117 
118     if (provisionRequest.size() > 0) {
119         vector<uint8_t> response = vendorModule->handleProvisioningRequest(
120                 provisionRequest, defaultUrl);
121         ASSERT_NE(0u, response.size());
122 
123         auto res = drmPlugin->provideProvisionResponse(
124                 response, [&](Status status, const hidl_vec<uint8_t>&,
125                               const hidl_vec<uint8_t>&) {
126                     EXPECT_EQ(Status::OK, status);
127                 });
128         EXPECT_OK(res);
129     }
130 }
131 
132 /**
133  * A get key request should fail if no sessionId is provided
134  */
TEST_P(DrmHalTest,GetKeyRequestNoSession)135 TEST_P(DrmHalTest, GetKeyRequestNoSession) {
136     SessionId invalidSessionId;
137     hidl_vec<uint8_t> initData;
138     KeyedVector optionalParameters;
139     auto res = drmPlugin->getKeyRequest_1_2(
140             invalidSessionId, initData, kVideoMp4, KeyType::STREAMING,
141             optionalParameters,
142             [&](StatusV1_2 status, const hidl_vec<uint8_t>&, KeyRequestType,
143                 const hidl_string&) { EXPECT_EQ(StatusV1_2::BAD_VALUE, status); });
144     EXPECT_OK(res);
145 }
146 
147 /**
148  * Test that the plugin returns the documented error for the
149  * case of attempting to generate a key request using an
150  * invalid mime type
151  */
TEST_P(DrmHalTest,GetKeyRequestBadMime)152 TEST_P(DrmHalTest, GetKeyRequestBadMime) {
153     auto sessionId = openSession();
154     hidl_vec<uint8_t> initData;
155     KeyedVector optionalParameters;
156     auto res = drmPlugin->getKeyRequest_1_2(
157             sessionId, initData, kBadMime, KeyType::STREAMING,
158             optionalParameters, [&](StatusV1_2 status, const hidl_vec<uint8_t>&,
159                                     KeyRequestType, const hidl_string&) {
160                 EXPECT_NE(StatusV1_2::OK, status);
161             });
162     EXPECT_OK(res);
163     closeSession(sessionId);
164 }
165 
166 template <Status S, size_t N>
checkKeySetIds(Status status,const hidl_vec<KeySetId> & keySetIds)167 void checkKeySetIds(Status status, const hidl_vec<KeySetId>& keySetIds) {
168     EXPECT_EQ(S, status);
169     if (S == Status::OK) {
170         EXPECT_EQ(N, keySetIds.size());
171     }
172 }
173 
174 template <Status S, OfflineLicenseState T>
checkKeySetIdState(Status status,OfflineLicenseState state)175 void checkKeySetIdState(Status status, OfflineLicenseState state) {
176     if (S == Status::OK) {
177         EXPECT_TRUE(T == OfflineLicenseState::USABLE || T == OfflineLicenseState::INACTIVE);
178     } else {
179         EXPECT_TRUE(T == OfflineLicenseState::UNKNOWN);
180     }
181     EXPECT_EQ(S, status);
182     EXPECT_EQ(T, state);
183 }
184 
185 /**
186  * Test drm plugin offline key support
187  */
TEST_P(DrmHalTest,OfflineLicenseTest)188 TEST_P(DrmHalTest, OfflineLicenseTest) {
189     auto sessionId = openSession();
190     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
191 
192     auto res = drmPlugin->getOfflineLicenseKeySetIds(
193             [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
194                 bool found = false;
195                 EXPECT_EQ(Status::OK, status);
196                 for (KeySetId keySetId2: keySetIds) {
197                     if (keySetId == keySetId2) {
198                         found = true;
199                         break;
200                     }
201                 }
202                 EXPECT_TRUE(found) << "keySetId not found";
203             });
204     EXPECT_OK(res);
205 
206     Status err = drmPlugin->removeOfflineLicense(keySetId);
207     EXPECT_EQ(Status::OK, err);
208 
209     res = drmPlugin->getOfflineLicenseKeySetIds(
210             [&](Status status, const hidl_vec<KeySetId>& keySetIds) {
211                 EXPECT_EQ(Status::OK, status);
212                 for (KeySetId keySetId2: keySetIds) {
213                     EXPECT_NE(keySetId, keySetId2);
214                 }
215             });
216     EXPECT_OK(res);
217 
218     err = drmPlugin->removeOfflineLicense(keySetId);
219     EXPECT_EQ(Status::BAD_VALUE, err);
220 
221     closeSession(sessionId);
222 }
223 
224 /**
225  * Test drm plugin offline key state
226  */
TEST_P(DrmHalTest,OfflineLicenseStateTest)227 TEST_P(DrmHalTest, OfflineLicenseStateTest) {
228     auto sessionId = openSession();
229     DrmHalVTSVendorModule_V1::ContentConfiguration content = getContent(KeyType::OFFLINE);
230     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, content, KeyType::OFFLINE);
231     drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<Status::OK, OfflineLicenseState::USABLE>);
232 
233     hidl_vec<uint8_t> keyRequest = getKeyRequest(keySetId, content, KeyType::RELEASE);
234     drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<Status::OK, OfflineLicenseState::INACTIVE>);
235 
236     /**
237      * Get key response from vendor module
238      */
239     hidl_vec<uint8_t> keyResponse =
240         vendorModule->handleKeyRequest(keyRequest, content.serverUrl);
241     EXPECT_GT(keyResponse.size(), 0u);
242 
243     provideKeyResponse(keySetId, keyResponse);
244     drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<Status::BAD_VALUE, OfflineLicenseState::UNKNOWN>);
245     closeSession(sessionId);
246 }
247 
248 /**
249  * Negative offline license test. Remove empty keySetId
250  */
TEST_P(DrmHalTest,RemoveEmptyKeySetId)251 TEST_P(DrmHalTest, RemoveEmptyKeySetId) {
252     KeySetId emptyKeySetId;
253     Status err = drmPlugin->removeOfflineLicense(emptyKeySetId);
254     EXPECT_EQ(Status::BAD_VALUE, err);
255 }
256 
257 /**
258  * Negative offline license test. Get empty keySetId state
259  */
TEST_P(DrmHalTest,GetEmptyKeySetIdState)260 TEST_P(DrmHalTest, GetEmptyKeySetIdState) {
261     KeySetId emptyKeySetId;
262     auto res = drmPlugin->getOfflineLicenseState(emptyKeySetId, checkKeySetIdState<Status::BAD_VALUE, OfflineLicenseState::UNKNOWN>);
263     EXPECT_OK(res);
264 }
265 
266 /**
267  * Test that the plugin returns valid connected and max HDCP levels
268  */
TEST_P(DrmHalTest,GetHdcpLevels)269 TEST_P(DrmHalTest, GetHdcpLevels) {
270     auto res = drmPlugin->getHdcpLevels_1_2(
271             [&](StatusV1_2 status, const HdcpLevel &connectedLevel,
272                 const HdcpLevel &maxLevel) {
273                 EXPECT_EQ(StatusV1_2::OK, status);
274                 EXPECT_GE(connectedLevel, HdcpLevel::HDCP_NONE);
275                 EXPECT_LE(maxLevel, HdcpLevel::HDCP_V2_3);
276             });
277     EXPECT_OK(res);
278 }
279 
280 /**
281  * Simulate the plugin sending keys change and make sure
282  * the listener gets them.
283  */
TEST_P(DrmHalTest,ListenerKeysChange)284 TEST_P(DrmHalTest, ListenerKeysChange) {
285     RETURN_IF_SKIPPED;
286     sp<DrmHalPluginListener> listener = new DrmHalPluginListener();
287     auto res = drmPlugin->setListener(listener);
288     EXPECT_OK(res);
289 
290     auto sessionId = openSession();
291     const hidl_vec<KeyStatus> keyStatusList = {
292         {{1}, KeyStatusType::USABLE},
293         {{2}, KeyStatusType::EXPIRED},
294         {{3}, KeyStatusType::OUTPUTNOTALLOWED},
295         {{4}, KeyStatusType::STATUSPENDING},
296         {{5}, KeyStatusType::INTERNALERROR},
297         {{6}, KeyStatusType::USABLEINFUTURE},
298     };
299 
300     drmPlugin->sendKeysChange_1_2(sessionId, keyStatusList, true);
301     auto result = listener->WaitForCallback(kCallbackKeysChange);
302     EXPECT_TRUE(result.no_timeout);
303     EXPECT_TRUE(result.args);
304     EXPECT_EQ(sessionId, result.args->sessionId);
305     EXPECT_EQ(keyStatusList, result.args->keyStatusList);
306     closeSession(sessionId);
307 }
308 
309 /**
310  *  CryptoPlugin Decrypt tests
311  */
312 
313 /**
314  * Positive decrypt test.  "Decrypt" a single clear segment
315  */
TEST_P(DrmHalTest,ClearSegmentTest)316 TEST_P(DrmHalTest, ClearSegmentTest) {
317     RETURN_IF_SKIPPED;
318     for (const auto& config : contentConfigurations) {
319         for (const auto& key : config.keys) {
320             const size_t kSegmentSize = 1024;
321             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
322             const Pattern noPattern = {0, 0};
323             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
324                                                    .numBytesOfEncryptedData = 0}};
325             auto sessionId = openSession();
326             loadKeys(sessionId, config);
327 
328             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
329             EXPECT_EQ(Status::OK, status);
330 
331             uint32_t byteCount = decrypt(Mode::UNENCRYPTED, key.isSecure, toHidlArray(key.keyId),
332                     &iv[0], subSamples, noPattern, key.clearContentKey, StatusV1_2::OK);
333             EXPECT_EQ(kSegmentSize, byteCount);
334 
335             closeSession(sessionId);
336         }
337     }
338 }
339 
340 /**
341  * Positive decrypt test.  Decrypt a single segment using aes_ctr.
342  * Verify data matches.
343  */
TEST_P(DrmHalTest,EncryptedAesCtrSegmentTest)344 TEST_P(DrmHalTest, EncryptedAesCtrSegmentTest) {
345     RETURN_IF_SKIPPED;
346     for (const auto& config : contentConfigurations) {
347         for (const auto& key : config.keys) {
348             const size_t kSegmentSize = 1024;
349             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
350             const Pattern noPattern = {0, 0};
351             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
352                                                    .numBytesOfEncryptedData = 0}};
353             auto sessionId = openSession();
354             loadKeys(sessionId, config);
355 
356             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
357             EXPECT_EQ(Status::OK, status);
358 
359             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure, toHidlArray(key.keyId),
360                     &iv[0], subSamples, noPattern, key.clearContentKey, StatusV1_2::OK);
361             EXPECT_EQ(kSegmentSize, byteCount);
362 
363             closeSession(sessionId);
364         }
365     }
366 }
367 
368 /**
369  * Negative decrypt test.  Decrypted frame too large to fit in output buffer
370  */
TEST_P(DrmHalTest,ErrorFrameTooLarge)371 TEST_P(DrmHalTest, ErrorFrameTooLarge) {
372     RETURN_IF_SKIPPED;
373     for (const auto& config : contentConfigurations) {
374         for (const auto& key : config.keys) {
375             const size_t kSegmentSize = 1024;
376             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
377             const Pattern noPattern = {0, 0};
378             const vector<SubSample> subSamples = {{.numBytesOfClearData = kSegmentSize,
379                                                    .numBytesOfEncryptedData = 0}};
380             auto sessionId = openSession();
381             loadKeys(sessionId, config);
382 
383             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
384             EXPECT_EQ(Status::OK, status);
385 
386             decrypt(Mode::UNENCRYPTED, key.isSecure, toHidlArray(key.keyId),
387                     &iv[0], subSamples, noPattern, key.clearContentKey, StatusV1_2::ERROR_DRM_FRAME_TOO_LARGE);
388 
389             closeSession(sessionId);
390         }
391     }
392 }
393 
394 /**
395  * Negative decrypt test. Decrypt without loading keys.
396  */
TEST_P(DrmHalTest,EncryptedAesCtrSegmentTestNoKeys)397 TEST_P(DrmHalTest, EncryptedAesCtrSegmentTestNoKeys) {
398     RETURN_IF_SKIPPED;
399     for (const auto& config : contentConfigurations) {
400         for (const auto& key : config.keys) {
401             vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
402             const Pattern noPattern = {0, 0};
403             const vector<SubSample> subSamples = {{.numBytesOfClearData = 256,
404                                                    .numBytesOfEncryptedData = 256}};
405             auto sessionId = openSession();
406 
407             Status status = cryptoPlugin->setMediaDrmSession(sessionId);
408             EXPECT_EQ(Status::OK, status);
409 
410             uint32_t byteCount = decrypt(Mode::AES_CTR, key.isSecure,
411                     toHidlArray(key.keyId), &iv[0], subSamples, noPattern,
412                     key.clearContentKey, StatusV1_2::ERROR_DRM_NO_LICENSE);
413             EXPECT_EQ(0u, byteCount);
414 
415             closeSession(sessionId);
416         }
417     }
418 }
419 
420 /**
421  * Ensure clearkey drm factory doesn't support security level higher than supported
422  */
TEST_P(DrmHalClearkeyTest,BadLevelNotSupported)423 TEST_P(DrmHalClearkeyTest, BadLevelNotSupported) {
424     const SecurityLevel kHwSecureAll = SecurityLevel::HW_SECURE_ALL;
425     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kVideoMp4, kHwSecureAll));
426 }
427 
428 /**
429  * Test resource contention during attempt to generate key request
430  */
TEST_P(DrmHalClearkeyTest,GetKeyRequestResourceContention)431 TEST_P(DrmHalClearkeyTest, GetKeyRequestResourceContention) {
432     Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorResourceContention);
433     EXPECT_EQ(Status::OK, status);
434     auto sessionId = openSession();
435     hidl_vec<uint8_t> initData;
436     KeyedVector optionalParameters;
437     auto res = drmPlugin->getKeyRequest_1_2(
438             sessionId, initData, kVideoMp4, KeyType::STREAMING,
439             optionalParameters, [&](StatusV1_2 status, const hidl_vec<uint8_t>&,
440                                     KeyRequestType, const hidl_string&) {
441                 EXPECT_EQ(StatusV1_2::ERROR_DRM_RESOURCE_CONTENTION, status);
442             });
443     EXPECT_OK(res);
444 
445     status = drmPlugin->closeSession(sessionId);
446     EXPECT_NE(Status::OK, status);
447 }
448 
449 /**
450  * Test clearkey plugin offline key with mock error
451  */
TEST_P(DrmHalClearkeyTest,OfflineLicenseInvalidState)452 TEST_P(DrmHalClearkeyTest, OfflineLicenseInvalidState) {
453     auto sessionId = openSession();
454     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
455     Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorInvalidState);
456     EXPECT_EQ(Status::OK, status);
457 
458     // everything should start failing
459     const Status kInvalidState = Status::ERROR_DRM_INVALID_STATE;
460     const OfflineLicenseState kUnknownState = OfflineLicenseState::UNKNOWN;
461     auto res = drmPlugin->getOfflineLicenseKeySetIds(checkKeySetIds<kInvalidState, 0u>);
462     EXPECT_OK(res);
463     res = drmPlugin->getOfflineLicenseState(keySetId, checkKeySetIdState<kInvalidState, kUnknownState>);
464     EXPECT_OK(res);
465     Status err = drmPlugin->removeOfflineLicense(keySetId);
466     EXPECT_EQ(kInvalidState, err);
467     closeSession(sessionId);
468 }
469 
470 /**
471  * Test SessionLostState is triggered on error
472  */
TEST_P(DrmHalClearkeyTest,SessionLostState)473 TEST_P(DrmHalClearkeyTest, SessionLostState) {
474     sp<DrmHalPluginListener> listener = new DrmHalPluginListener();
475     auto res = drmPlugin->setListener(listener);
476     EXPECT_OK(res);
477 
478     Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorInvalidState);
479     EXPECT_EQ(Status::OK, status);
480 
481     auto sessionId = openSession();
482     drmPlugin->closeSession(sessionId);
483 
484     auto result = listener->WaitForCallback(kCallbackLostState);
485     EXPECT_TRUE(result.no_timeout);
486     EXPECT_TRUE(result.args);
487     EXPECT_EQ(sessionId, result.args->sessionId);
488 }
489 
490 /**
491  * Negative decrypt test. Decrypt with invalid key.
492  */
TEST_P(DrmHalClearkeyTest,DecryptWithEmptyKey)493 TEST_P(DrmHalClearkeyTest, DecryptWithEmptyKey) {
494     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
495     const Pattern noPattern = {0, 0};
496     const uint32_t kClearBytes = 512;
497     const uint32_t kEncryptedBytes = 512;
498     const vector<SubSample> subSamples = {
499         {.numBytesOfClearData = kClearBytes,
500          .numBytesOfEncryptedData = kEncryptedBytes}};
501 
502     // base 64 encoded JSON response string, must not contain padding character '='
503     const hidl_string emptyKeyResponse =
504             "{\"keys\":[" \
505                 "{" \
506                     "\"kty\":\"oct\"" \
507                     "\"alg\":\"A128KW2\"" \
508                     "\"k\":\"SGVsbG8gRnJpZW5kIQ\"" \
509                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAyAy\"" \
510                 "}" \
511                 "{" \
512                     "\"kty\":\"oct\"," \
513                     "\"alg\":\"A128KW2\"" \
514                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
515                     // empty key follows
516                     "\"k\":\"R\"" \
517                 "}]" \
518             "}";
519     const size_t kEmptyKeyResponseSize = emptyKeyResponse.size();
520 
521     hidl_vec<uint8_t> invalidResponse;
522     invalidResponse.resize(kEmptyKeyResponseSize);
523     memcpy(invalidResponse.data(), emptyKeyResponse.c_str(), kEmptyKeyResponseSize);
524     decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
525 }
526 
527 /**
528  * Negative decrypt test. Decrypt with a key exceeds AES_BLOCK_SIZE.
529  */
TEST_P(DrmHalClearkeyTest,DecryptWithKeyTooLong)530 TEST_P(DrmHalClearkeyTest, DecryptWithKeyTooLong) {
531     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
532     const Pattern noPattern = {0, 0};
533     const uint32_t kClearBytes = 512;
534     const uint32_t kEncryptedBytes = 512;
535     const vector<SubSample> subSamples = {
536         {.numBytesOfClearData = kClearBytes,
537          .numBytesOfEncryptedData = kEncryptedBytes}};
538 
539     // base 64 encoded JSON response string, must not contain padding character '='
540     const hidl_string keyTooLongResponse =
541             "{\"keys\":[" \
542                 "{" \
543                     "\"kty\":\"oct\"," \
544                     "\"alg\":\"A128KW2\"" \
545                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
546                     // key too long
547                     "\"k\":\"V2lubmllIHRoZSBwb29oIVdpbm5pZSB0aGUgcG9vaCE=\"" \
548                 "}]" \
549             "}";
550     const size_t kKeyTooLongResponseSize = keyTooLongResponse.size();
551 
552     hidl_vec<uint8_t> invalidResponse;
553     invalidResponse.resize(kKeyTooLongResponseSize);
554     memcpy(invalidResponse.data(), keyTooLongResponse.c_str(), kKeyTooLongResponseSize);
555     decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
556 }
557 
558 /**
559  * Instantiate the set of test cases for each vendor module
560  */
561 
562 INSTANTIATE_TEST_CASE_P(
563         DrmHalTestClearkey, DrmHalTest,
564         testing::Values("clearkey"));
565 
566 INSTANTIATE_TEST_CASE_P(
567         DrmHalTestClearkeyExtended, DrmHalClearkeyTest,
568         testing::Values("clearkey"));
569 
570 INSTANTIATE_TEST_CASE_P(
571         DrmHalTestVendor, DrmHalTest,
572         testing::ValuesIn(DrmHalTest::gVendorModules->getPathList()));
573 
main(int argc,char ** argv)574 int main(int argc, char** argv) {
575 #if defined(__LP64__)
576     const char* kModulePath = "/data/local/tmp/64/lib";
577 #else
578     const char* kModulePath = "/data/local/tmp/32/lib";
579 #endif
580     DrmHalTest::gVendorModules = new drm_vts::VendorModules(kModulePath);
581     if (DrmHalTest::gVendorModules->getPathList().size() == 0) {
582         std::cerr << "WARNING: No vendor modules found in " << kModulePath <<
583                 ", all vendor tests will be skipped" << std::endl;
584     }
585     ::testing::AddGlobalTestEnvironment(DrmHidlEnvironment::Instance());
586     ::testing::InitGoogleTest(&argc, argv);
587     DrmHidlEnvironment::Instance()->init(&argc, argv);
588     int status = RUN_ALL_TESTS();
589     ALOGI("Test result = %d", status);
590     return status;
591 }
592