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_clearkey_test@1.0"
18 
19 #include <android/hardware/drm/1.0/ICryptoFactory.h>
20 #include <android/hardware/drm/1.0/ICryptoPlugin.h>
21 #include <android/hardware/drm/1.0/IDrmFactory.h>
22 #include <android/hardware/drm/1.0/IDrmPlugin.h>
23 #include <android/hardware/drm/1.0/types.h>
24 #include <android/hidl/allocator/1.0/IAllocator.h>
25 #include <gtest/gtest.h>
26 #include <hidl/HidlSupport.h>
27 #include <hidlmemory/mapping.h>
28 #include <log/log.h>
29 #include <memory>
30 #include <openssl/aes.h>
31 #include <random>
32 
33 #include "VtsHalHidlTargetTestBase.h"
34 
35 using ::android::hardware::drm::V1_0::BufferType;
36 using ::android::hardware::drm::V1_0::DestinationBuffer;
37 using ::android::hardware::drm::V1_0::ICryptoFactory;
38 using ::android::hardware::drm::V1_0::ICryptoPlugin;
39 using ::android::hardware::drm::V1_0::IDrmFactory;
40 using ::android::hardware::drm::V1_0::IDrmPlugin;
41 using ::android::hardware::drm::V1_0::KeyedVector;
42 using ::android::hardware::drm::V1_0::KeyValue;
43 using ::android::hardware::drm::V1_0::KeyRequestType;
44 using ::android::hardware::drm::V1_0::KeyType;
45 using ::android::hardware::drm::V1_0::Mode;
46 using ::android::hardware::drm::V1_0::Pattern;
47 using ::android::hardware::drm::V1_0::SecureStop;
48 using ::android::hardware::drm::V1_0::SecureStopId;
49 using ::android::hardware::drm::V1_0::SessionId;
50 using ::android::hardware::drm::V1_0::SharedBuffer;
51 using ::android::hardware::drm::V1_0::Status;
52 using ::android::hardware::drm::V1_0::SubSample;
53 
54 using ::android::hardware::hidl_array;
55 using ::android::hardware::hidl_string;
56 using ::android::hardware::hidl_memory;
57 using ::android::hardware::hidl_vec;
58 using ::android::hardware::Return;
59 using ::android::hidl::allocator::V1_0::IAllocator;
60 using ::android::hidl::memory::V1_0::IMemory;
61 using ::android::sp;
62 
63 using std::string;
64 using std::unique_ptr;
65 using std::random_device;
66 using std::map;
67 using std::mt19937;
68 using std::vector;
69 
70 /**
71  * These clearkey tests use white box knowledge of the legacy clearkey
72  * plugin to verify that the HIDL HAL services and interfaces are working.
73  * It is not intended to verify any vendor's HAL implementation. If you
74  * are looking for vendor HAL tests, see drm_hal_vendor_test.cpp
75  */
76 #define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
77 #define EXPECT_OK(ret) EXPECT_TRUE(ret.isOk())
78 
79 static const uint8_t kCommonPsshBoxUUID[16] = {
80     0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02,
81     0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B};
82 
83 // To be used in mpd to specify drm scheme for players
84 static const uint8_t kClearKeyUUID[16] = {
85     0xE2, 0x71, 0x9D, 0x58, 0xA9, 0x85, 0xB3, 0xC9,
86     0x78, 0x1A, 0xB0, 0x30, 0xAF, 0x78, 0xD3, 0x0E};
87 
88 static const uint8_t kInvalidUUID[16] = {
89     0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
90     0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
91 
92 class DrmHalClearkeyFactoryTest : public ::testing::VtsHalHidlTargetTestBase {
93    public:
SetUp()94     virtual void SetUp() override {
95         const ::testing::TestInfo* const test_info =
96                 ::testing::UnitTest::GetInstance()->current_test_info();
97         ALOGD("Running test %s.%s", test_info->test_case_name(),
98               test_info->name());
99 
100         drmFactory =
101                 ::testing::VtsHalHidlTargetTestBase::getService<IDrmFactory>();
102         ASSERT_NE(nullptr, drmFactory.get());
103         cryptoFactory =
104                 ::testing::VtsHalHidlTargetTestBase::getService<ICryptoFactory>();
105         ASSERT_NE(nullptr, cryptoFactory.get());
106     }
107 
TearDown()108     virtual void TearDown() override {}
109 
110    protected:
111     sp<IDrmFactory> drmFactory;
112     sp<ICryptoFactory> cryptoFactory;
113 };
114 
115 /**
116  * Ensure the factory supports both Common Pssh Box UUID and Clearkey Scheme UUID
117  */
TEST_F(DrmHalClearkeyFactoryTest,ClearKeyPluginSupported)118 TEST_F(DrmHalClearkeyFactoryTest, ClearKeyPluginSupported) {
119     EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID));
120     EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(kCommonPsshBoxUUID));
121 
122     EXPECT_TRUE(drmFactory->isCryptoSchemeSupported(kClearKeyUUID));
123     EXPECT_TRUE(cryptoFactory->isCryptoSchemeSupported(kClearKeyUUID));
124 }
125 
126 /**
127  * Ensure the factory doesn't support an invalid scheme UUID
128  */
TEST_F(DrmHalClearkeyFactoryTest,InvalidPluginNotSupported)129 TEST_F(DrmHalClearkeyFactoryTest, InvalidPluginNotSupported) {
130     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(kInvalidUUID));
131     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(kInvalidUUID));
132 }
133 
134 /**
135  * Ensure the factory doesn't support an empty UUID
136  */
TEST_F(DrmHalClearkeyFactoryTest,EmptyPluginUUIDNotSupported)137 TEST_F(DrmHalClearkeyFactoryTest, EmptyPluginUUIDNotSupported) {
138     hidl_array<uint8_t, 16> emptyUUID;
139     memset(emptyUUID.data(), 0, 16);
140     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported(emptyUUID));
141     EXPECT_FALSE(cryptoFactory->isCryptoSchemeSupported(emptyUUID));
142 }
143 
144 /**
145  * Ensure empty content type is not supported
146  */
TEST_F(DrmHalClearkeyFactoryTest,EmptyContentTypeNotSupported)147 TEST_F(DrmHalClearkeyFactoryTest, EmptyContentTypeNotSupported) {
148     hidl_string empty;
149     EXPECT_FALSE(drmFactory->isContentTypeSupported(empty));
150 }
151 
152 /**
153  * Ensure invalid content type is not supported
154  */
TEST_F(DrmHalClearkeyFactoryTest,InvalidContentTypeNotSupported)155 TEST_F(DrmHalClearkeyFactoryTest, InvalidContentTypeNotSupported) {
156     hidl_string invalid("abcdabcd");
157     EXPECT_FALSE(drmFactory->isContentTypeSupported(invalid));
158 }
159 
160 /**
161  * Ensure valid content type is supported
162  */
TEST_F(DrmHalClearkeyFactoryTest,ValidContentTypeSupported)163 TEST_F(DrmHalClearkeyFactoryTest, ValidContentTypeSupported) {
164     hidl_string cencType("cenc");
165     EXPECT_TRUE(drmFactory->isContentTypeSupported(cencType));
166 }
167 
168 /**
169  * Ensure clearkey drm plugin can be created using Common Pssh Box UUID
170  */
TEST_F(DrmHalClearkeyFactoryTest,CreateClearKeyDrmPluginUsingCommonPsshBoxUuid)171 TEST_F(DrmHalClearkeyFactoryTest, CreateClearKeyDrmPluginUsingCommonPsshBoxUuid) {
172     hidl_string packageName("android.hardware.drm.test");
173     auto res = drmFactory->createPlugin(
174             kCommonPsshBoxUUID, packageName,
175             [&](Status status, const sp<IDrmPlugin>& plugin) {
176                 EXPECT_EQ(Status::OK, status);
177                 EXPECT_NE(nullptr, plugin.get());
178             });
179     EXPECT_OK(res);
180 }
181 
182 /**
183  * Ensure clearkey drm plugin can be created using ClearKey UUID
184  */
TEST_F(DrmHalClearkeyFactoryTest,CreateClearKeyDrmPluginUsingClearKeyUuid)185  TEST_F(DrmHalClearkeyFactoryTest, CreateClearKeyDrmPluginUsingClearKeyUuid) {
186     hidl_string packageName("android.hardware.drm.test");
187     auto res = drmFactory->createPlugin(
188             kClearKeyUUID, packageName,
189             [&](Status status, const sp<IDrmPlugin>& plugin) {
190                 EXPECT_EQ(Status::OK, status);
191                 EXPECT_NE(nullptr, plugin.get());
192             });
193     EXPECT_OK(res);
194 }
195 
196 /**
197  * Ensure clearkey crypto plugin can be created using Common Pssh Box UUID
198  */
TEST_F(DrmHalClearkeyFactoryTest,CreateClearKeyCryptoPluginUsingCommonPsshBoxUuid)199 TEST_F(DrmHalClearkeyFactoryTest, CreateClearKeyCryptoPluginUsingCommonPsshBoxUuid) {
200     hidl_vec<uint8_t> initVec;
201     auto res = cryptoFactory->createPlugin(
202             kCommonPsshBoxUUID, initVec,
203             [&](Status status, const sp<ICryptoPlugin>& plugin) {
204                 EXPECT_EQ(Status::OK, status);
205                 EXPECT_NE(nullptr, plugin.get());
206             });
207     EXPECT_OK(res);
208 }
209 
210 /**
211  * Ensure clearkey crypto plugin can be created using ClearKey UUID
212  */
TEST_F(DrmHalClearkeyFactoryTest,CreateClearKeyCryptoPluginUsingClearKeyUuid)213 TEST_F(DrmHalClearkeyFactoryTest, CreateClearKeyCryptoPluginUsingClearKeyUuid) {
214     hidl_vec<uint8_t> initVec;
215     auto res = cryptoFactory->createPlugin(
216             kClearKeyUUID, initVec,
217             [&](Status status, const sp<ICryptoPlugin>& plugin) {
218                 EXPECT_EQ(Status::OK, status);
219                 EXPECT_NE(nullptr, plugin.get());
220             });
221     EXPECT_OK(res);
222 }
223 
224 /**
225  * Ensure invalid drm plugin can't be created
226  */
TEST_F(DrmHalClearkeyFactoryTest,CreateInvalidDrmPlugin)227 TEST_F(DrmHalClearkeyFactoryTest, CreateInvalidDrmPlugin) {
228     hidl_string packageName("android.hardware.drm.test");
229     auto res = drmFactory->createPlugin(
230             kInvalidUUID, packageName,
231             [&](Status status, const sp<IDrmPlugin>& plugin) {
232                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
233                 EXPECT_EQ(nullptr, plugin.get());
234             });
235     EXPECT_OK(res);
236 }
237 
238 /**
239  * Ensure invalid crypto plugin can't be created
240  */
TEST_F(DrmHalClearkeyFactoryTest,CreateInvalidCryptoPlugin)241 TEST_F(DrmHalClearkeyFactoryTest, CreateInvalidCryptoPlugin) {
242     hidl_vec<uint8_t> initVec;
243     auto res = cryptoFactory->createPlugin(
244             kInvalidUUID, initVec,
245             [&](Status status, const sp<ICryptoPlugin>& plugin) {
246                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
247                 EXPECT_EQ(nullptr, plugin.get());
248             });
249     EXPECT_OK(res);
250 }
251 
252 class DrmHalClearkeyPluginTest : public DrmHalClearkeyFactoryTest {
253    public:
SetUp()254     virtual void SetUp() override {
255         // Create factories
256         DrmHalClearkeyFactoryTest::SetUp();
257 
258         ASSERT_NE(nullptr, drmFactory.get());
259         hidl_string packageName("android.hardware.drm.test");
260         auto res = drmFactory->createPlugin(
261                 kClearKeyUUID, packageName,
262                 [this](Status status, const sp<IDrmPlugin>& plugin) {
263                     EXPECT_EQ(Status::OK, status);
264                     ASSERT_NE(nullptr, plugin.get());
265                     drmPlugin = plugin;
266                 });
267         ASSERT_OK(res);
268 
269         hidl_vec<uint8_t> initVec;
270         res = cryptoFactory->createPlugin(
271                 kClearKeyUUID, initVec,
272                 [this](Status status, const sp<ICryptoPlugin>& plugin) {
273                     EXPECT_EQ(Status::OK, status);
274                     ASSERT_NE(nullptr, plugin.get());
275                     cryptoPlugin = plugin;
276                 });
277         ASSERT_OK(res);
278     }
279 
TearDown()280     virtual void TearDown() override {}
281 
282     SessionId openSession();
283     void closeSession(const SessionId& sessionId);
284     hidl_vec<uint8_t> loadKeys(const SessionId& sessionId, const KeyType& type);
285     sp<IMemory> getDecryptMemory(size_t size, size_t index);
286 
287    protected:
288     sp<IDrmPlugin> drmPlugin;
289     sp<ICryptoPlugin> cryptoPlugin;
290 };
291 
292 /**
293  *  DrmPlugin tests
294  */
295 
296 /**
297  * Test that the plugin can return a provision request.  Since
298  * the clearkey plugin doesn't support provisioning, it is
299  * expected to return Status::ERROR_DRM_CANNOT_HANDLE.
300  */
TEST_F(DrmHalClearkeyPluginTest,GetProvisionRequest)301 TEST_F(DrmHalClearkeyPluginTest, GetProvisionRequest) {
302     hidl_string certificateType;
303     hidl_string certificateAuthority;
304     auto res = drmPlugin->getProvisionRequest(
305             certificateType, certificateAuthority,
306             [&](Status status, const hidl_vec<uint8_t>&, const hidl_string&) {
307                 // clearkey doesn't require provisioning
308                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
309             });
310     EXPECT_OK(res);
311 }
312 
313 /**
314  * The DRM HAL should return BAD_VALUE if an empty provisioning
315  * response is provided.
316  */
TEST_F(DrmHalClearkeyPluginTest,ProvideEmptyProvisionResponse)317 TEST_F(DrmHalClearkeyPluginTest, ProvideEmptyProvisionResponse) {
318     hidl_vec<uint8_t> response;
319     auto res = drmPlugin->provideProvisionResponse(
320             response, [&](Status status, const hidl_vec<uint8_t>&,
321                           const hidl_vec<uint8_t>&) {
322                 EXPECT_EQ(Status::BAD_VALUE, status);
323             });
324     EXPECT_OK(res);
325 }
326 
327 /**
328  * Helper method to open a session and verify that a non-empty
329  * session ID is returned
330  */
openSession()331 SessionId DrmHalClearkeyPluginTest::openSession() {
332     SessionId sessionId;
333 
334     auto res = drmPlugin->openSession(
335             [&sessionId](Status status, const SessionId& id) {
336                 EXPECT_EQ(Status::OK, status);
337                 EXPECT_NE(0u, id.size());
338                 sessionId = id;
339             });
340     EXPECT_OK(res);
341     return sessionId;
342 }
343 
344 /**
345  * Helper method to close a session
346  */
closeSession(const SessionId & sessionId)347 void DrmHalClearkeyPluginTest::closeSession(const SessionId& sessionId) {
348     EXPECT_TRUE(drmPlugin->closeSession(sessionId).isOk());
349 }
350 
351 /**
352  * Helper method to load keys for subsequent decrypt tests.
353  * These tests use predetermined key request/response to
354  * avoid requiring a round trip to a license server.
355  */
loadKeys(const SessionId & sessionId,const KeyType & type=KeyType::STREAMING)356 hidl_vec<uint8_t> DrmHalClearkeyPluginTest::loadKeys(
357     const SessionId& sessionId, const KeyType& type = KeyType::STREAMING) {
358     hidl_vec<uint8_t> initData = {
359         // BMFF box header (4 bytes size + 'pssh')
360         0x00, 0x00, 0x00, 0x34, 0x70, 0x73, 0x73, 0x68,
361         // full box header (version = 1 flags = 0)
362         0x01, 0x00, 0x00, 0x00,
363         // system id
364         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, 0xac, 0xe3, 0x3c,
365         0x1e, 0x52, 0xe2, 0xfb, 0x4b,
366         // number of key ids
367         0x00, 0x00, 0x00, 0x01,
368         // key id
369         0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47, 0x7e, 0x87, 0x7e, 0x57, 0xd0,
370         0x0d, 0x1e, 0xd0, 0x0d, 0x1e,
371         // size of data, must be zero
372         0x00, 0x00, 0x00, 0x00};
373 
374     hidl_vec<uint8_t> expectedKeyRequest = {
375         0x7b, 0x22, 0x6b, 0x69, 0x64, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x59, 0x41, 0x59, 0x65,
376         0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e, 0x48, 0x74,
377         0x41, 0x4e, 0x48, 0x67, 0x22, 0x5d, 0x2c, 0x22, 0x74, 0x79, 0x70, 0x65, 0x22, 0x3a,
378         0x22, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x22, 0x7d};
379 
380     hidl_vec<uint8_t> knownKeyResponse = {
381         0x7b, 0x22, 0x6b, 0x65, 0x79, 0x73, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x6b, 0x74, 0x79, 0x22,
382         0x3a, 0x22, 0x6f, 0x63, 0x74, 0x22, 0x2c, 0x22, 0x6b, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x59,
383         0x41, 0x59, 0x65, 0x41, 0x58, 0x35, 0x48, 0x66, 0x6f, 0x64, 0x2d, 0x56, 0x39, 0x41, 0x4e,
384         0x48, 0x74, 0x41, 0x4e, 0x48, 0x67, 0x22, 0x2c, 0x22, 0x6b, 0x22, 0x3a, 0x22, 0x47, 0x6f,
385         0x6f, 0x67, 0x6c, 0x65, 0x54, 0x65, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x42, 0x61, 0x73, 0x65,
386         0x36, 0x34, 0x67, 0x67, 0x67, 0x22, 0x7d, 0x5d, 0x7d, 0x0a};
387 
388     hidl_string mimeType = "video/mp4";
389     KeyedVector optionalParameters;
390     auto res = drmPlugin->getKeyRequest(
391         sessionId, initData, mimeType, type, optionalParameters,
392         [&](Status status, const hidl_vec<uint8_t>& request,
393             KeyRequestType requestType, const hidl_string&) {
394             EXPECT_EQ(Status::OK, status);
395             EXPECT_EQ(KeyRequestType::INITIAL, requestType);
396             EXPECT_EQ(request, expectedKeyRequest);
397         });
398     EXPECT_OK(res);
399 
400     hidl_vec<uint8_t> keySetId;
401     res = drmPlugin->provideKeyResponse(
402         sessionId, knownKeyResponse,
403         [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
404             EXPECT_EQ(Status::OK, status);
405             EXPECT_EQ(0u, myKeySetId.size());
406             keySetId = myKeySetId;
407         });
408     EXPECT_OK(res);
409     return keySetId;
410 }
411 
412 /**
413  * Test that a session can be opened and closed
414  */
TEST_F(DrmHalClearkeyPluginTest,OpenCloseSession)415 TEST_F(DrmHalClearkeyPluginTest, OpenCloseSession) {
416     auto sessionId = openSession();
417     closeSession(sessionId);
418 }
419 
420 /**
421  * Test that attempting to close an invalid (empty) sessionId
422  * is prohibited with the documented error code.
423  */
TEST_F(DrmHalClearkeyPluginTest,CloseInvalidSession)424 TEST_F(DrmHalClearkeyPluginTest, CloseInvalidSession) {
425     SessionId invalidSessionId;
426     Status result = drmPlugin->closeSession(invalidSessionId);
427     EXPECT_EQ(Status::BAD_VALUE, result);
428 }
429 
430 /**
431  * Test that attempting to close a session that is already closed
432  * is prohibited with the documented error code.
433  */
TEST_F(DrmHalClearkeyPluginTest,CloseClosedSession)434 TEST_F(DrmHalClearkeyPluginTest, CloseClosedSession) {
435     SessionId sessionId = openSession();
436     closeSession(sessionId);
437     Status result = drmPlugin->closeSession(sessionId);
438     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, result);
439 }
440 
441 /**
442  * A get key request should fail if no sessionId is provided
443  */
TEST_F(DrmHalClearkeyPluginTest,GetKeyRequestNoSession)444 TEST_F(DrmHalClearkeyPluginTest, GetKeyRequestNoSession) {
445     SessionId invalidSessionId;
446     hidl_vec<uint8_t> initData;
447     hidl_string mimeType = "video/mp4";
448     KeyedVector optionalParameters;
449     auto res = drmPlugin->getKeyRequest(
450             invalidSessionId, initData, mimeType, KeyType::STREAMING,
451             optionalParameters,
452             [&](Status status, const hidl_vec<uint8_t>&, KeyRequestType,
453                 const hidl_string&) { EXPECT_EQ(Status::BAD_VALUE, status); });
454     EXPECT_OK(res);
455 }
456 
457 /**
458  * The clearkey plugin doesn't support offline key requests.
459  * Test that the plugin returns the expected error code in
460  * this case.
461  */
TEST_F(DrmHalClearkeyPluginTest,GetKeyRequestOfflineKeyTypeNotSupported)462 TEST_F(DrmHalClearkeyPluginTest, GetKeyRequestOfflineKeyTypeNotSupported) {
463     auto sessionId = openSession();
464     hidl_vec<uint8_t> initData;
465     hidl_string mimeType = "video/mp4";
466     KeyedVector optionalParameters;
467 
468     auto res = drmPlugin->getKeyRequest(
469             sessionId, initData, mimeType, KeyType::OFFLINE, optionalParameters,
470             [&](Status status, const hidl_vec<uint8_t>&, KeyRequestType,
471                 const hidl_string&) {
472                 // Clearkey plugin doesn't support offline key type
473                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
474             });
475     EXPECT_OK(res);
476     closeSession(sessionId);
477 }
478 
479 /**
480  * Test that the plugin returns the documented error for the
481  * case of attempting to generate a key request using an
482  * invalid mime type
483  */
TEST_F(DrmHalClearkeyPluginTest,GetKeyRequestBadMime)484 TEST_F(DrmHalClearkeyPluginTest, GetKeyRequestBadMime) {
485     auto sessionId = openSession();
486     hidl_vec<uint8_t> initData;
487     hidl_string mimeType = "video/unknown";
488     KeyedVector optionalParameters;
489     auto res = drmPlugin->getKeyRequest(
490             sessionId, initData, mimeType, KeyType::STREAMING,
491             optionalParameters, [&](Status status, const hidl_vec<uint8_t>&,
492                                     KeyRequestType, const hidl_string&) {
493                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
494             });
495     EXPECT_OK(res);
496     closeSession(sessionId);
497 }
498 
499 /**
500  * Test that a closed sessionID returns SESSION_NOT_OPENED
501  */
TEST_F(DrmHalClearkeyPluginTest,ProvideKeyResponseClosedSession)502 TEST_F(DrmHalClearkeyPluginTest, ProvideKeyResponseClosedSession) {
503     SessionId session = openSession();
504     closeSession(session);
505 
506     hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65,
507                                      0x79, 0x73, 0x22, 0x3a};
508     auto res = drmPlugin->provideKeyResponse(
509             session, keyResponse,
510             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
511                 EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
512                 EXPECT_EQ(0u, keySetId.size());
513             });
514     EXPECT_OK(res);
515 }
516 
517 /**
518  * Test that an empty sessionID returns BAD_VALUE
519  */
TEST_F(DrmHalClearkeyPluginTest,ProvideKeyResponseInvalidSessionId)520 TEST_F(DrmHalClearkeyPluginTest, ProvideKeyResponseInvalidSessionId) {
521     SessionId session;
522 
523     hidl_vec<uint8_t> keyResponse = {0x7b, 0x22, 0x6b, 0x65,
524                                      0x79, 0x73, 0x22, 0x3a};
525     auto res = drmPlugin->provideKeyResponse(
526             session, keyResponse,
527             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
528                 EXPECT_EQ(Status::BAD_VALUE, status);
529                 EXPECT_EQ(0u, keySetId.size());
530             });
531     EXPECT_OK(res);
532 }
533 
534 /**
535  * Test that an empty key response returns BAD_VALUE
536  */
TEST_F(DrmHalClearkeyPluginTest,ProvideKeyResponseEmptyResponse)537 TEST_F(DrmHalClearkeyPluginTest, ProvideKeyResponseEmptyResponse) {
538     SessionId session = openSession();
539     hidl_vec<uint8_t> emptyResponse;
540     auto res = drmPlugin->provideKeyResponse(
541             session, emptyResponse,
542             [&](Status status, const hidl_vec<uint8_t>& keySetId) {
543                 EXPECT_EQ(Status::BAD_VALUE, status);
544                 EXPECT_EQ(0u, keySetId.size());
545             });
546     EXPECT_OK(res);
547     closeSession(session);
548 }
549 
550 /**
551  * Test that a removeKeys on an empty sessionID returns BAD_VALUE
552  */
TEST_F(DrmHalClearkeyPluginTest,RemoveKeysEmptySessionId)553 TEST_F(DrmHalClearkeyPluginTest, RemoveKeysEmptySessionId) {
554     SessionId sessionId;
555     Status status = drmPlugin->removeKeys(sessionId);
556     EXPECT_TRUE(status == Status::BAD_VALUE);
557 }
558 
559 /**
560  * Remove keys is not supported for clearkey.
561  */
TEST_F(DrmHalClearkeyPluginTest,RemoveKeysNewSession)562 TEST_F(DrmHalClearkeyPluginTest, RemoveKeysNewSession) {
563     SessionId sessionId = openSession();
564     Status status = drmPlugin->removeKeys(sessionId);
565     // Clearkey plugin doesn't support remove keys
566     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
567     closeSession(sessionId);
568 }
569 
570 /**
571  * Test that ClearKey cannot handle key restoring.
572  * Expected message is Status::ERROR_DRM_CANNOT_HANDLE.
573  */
TEST_F(DrmHalClearkeyPluginTest,RestoreKeysCannotHandle)574 TEST_F(DrmHalClearkeyPluginTest, RestoreKeysCannotHandle) {
575     hidl_vec<uint8_t> keySetId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
576     SessionId sessionId = openSession();
577     Status status = drmPlugin->restoreKeys(sessionId, keySetId);
578     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
579     closeSession(sessionId);
580 }
581 
582 /**
583  * Test that restoreKeys fails with a null key set ID.
584  * Error message is expected to be Status::BAD_VALUE.
585  */
TEST_F(DrmHalClearkeyPluginTest,RestoreKeysNull)586 TEST_F(DrmHalClearkeyPluginTest, RestoreKeysNull) {
587     SessionId sessionId = openSession();
588     hidl_vec<uint8_t> nullKeySetId;
589     Status status = drmPlugin->restoreKeys(sessionId, nullKeySetId);
590     EXPECT_EQ(Status::BAD_VALUE, status);
591     closeSession(sessionId);
592 }
593 
594 /**
595  * Test that the clearkey plugin doesn't support getting
596  * secure stops.
597  */
TEST_F(DrmHalClearkeyPluginTest,GetSecureStops)598 TEST_F(DrmHalClearkeyPluginTest, GetSecureStops) {
599     auto res = drmPlugin->getSecureStops(
600             [&](Status status, const hidl_vec<SecureStop>&) {
601                 // Clearkey plugin doesn't support secure stops
602                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
603             });
604     EXPECT_OK(res);
605 }
606 
607 /**
608  * Test that the clearkey plugin returns BAD_VALUE if
609  * an empty ssid is provided.
610  */
TEST_F(DrmHalClearkeyPluginTest,GetSecureStopEmptySSID)611 TEST_F(DrmHalClearkeyPluginTest, GetSecureStopEmptySSID) {
612     SecureStopId ssid;
613     auto res = drmPlugin->getSecureStop(
614             ssid, [&](Status status, const SecureStop&) {
615                 EXPECT_EQ(Status::BAD_VALUE, status);
616             });
617     EXPECT_OK(res);
618 }
619 
620 /**
621  * Test that releasing all secure stops isn't handled by
622  * clearkey.
623  */
TEST_F(DrmHalClearkeyPluginTest,ReleaseAllSecureStops)624 TEST_F(DrmHalClearkeyPluginTest, ReleaseAllSecureStops) {
625     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE,
626               drmPlugin->releaseAllSecureStops());
627 }
628 
629 /**
630  * Test that releasing a specific secure stop with an empty
631  * SSID returns BAD_VALUE.
632  */
TEST_F(DrmHalClearkeyPluginTest,ReleaseSecureStopEmptySSID)633 TEST_F(DrmHalClearkeyPluginTest, ReleaseSecureStopEmptySSID) {
634     SecureStopId ssid;
635     Status status = drmPlugin->releaseSecureStop(ssid);
636     EXPECT_EQ(Status::BAD_VALUE, status);
637 }
638 
639 /**
640  * The following four tests verify that the properties
641  * defined in the MediaDrm API are supported by
642  * the plugin.
643  */
TEST_F(DrmHalClearkeyPluginTest,GetVendorProperty)644 TEST_F(DrmHalClearkeyPluginTest, GetVendorProperty) {
645     auto res = drmPlugin->getPropertyString(
646             "vendor", [&](Status status, const hidl_string& value) {
647                 EXPECT_EQ(Status::OK, status);
648                 EXPECT_EQ("Google", value);
649             });
650     EXPECT_OK(res);
651 }
652 
TEST_F(DrmHalClearkeyPluginTest,GetVersionProperty)653 TEST_F(DrmHalClearkeyPluginTest, GetVersionProperty) {
654     auto res = drmPlugin->getPropertyString(
655             "version", [&](Status status, const hidl_string& value) {
656                 EXPECT_EQ(Status::OK, status);
657                 EXPECT_EQ("1.0", value);
658             });
659     EXPECT_OK(res);
660 }
661 
TEST_F(DrmHalClearkeyPluginTest,GetDescriptionProperty)662 TEST_F(DrmHalClearkeyPluginTest, GetDescriptionProperty) {
663     auto res = drmPlugin->getPropertyString(
664             "description", [&](Status status, const hidl_string& value) {
665                 EXPECT_EQ(Status::OK, status);
666                 EXPECT_EQ("ClearKey CDM", value);
667             });
668     EXPECT_OK(res);
669 }
670 
TEST_F(DrmHalClearkeyPluginTest,GetAlgorithmsProperty)671 TEST_F(DrmHalClearkeyPluginTest, GetAlgorithmsProperty) {
672     auto res = drmPlugin->getPropertyString(
673             "algorithms", [&](Status status, const hidl_string& value) {
674                 EXPECT_EQ(Status::OK, status);
675                 EXPECT_EQ("", value);
676             });
677     EXPECT_OK(res);
678 }
679 
680 /**
681  * Test that attempting to read invalid string and byte array
682  * properties returns the documented error code.
683  */
TEST_F(DrmHalClearkeyPluginTest,GetInvalidStringProperty)684 TEST_F(DrmHalClearkeyPluginTest, GetInvalidStringProperty) {
685     auto res = drmPlugin->getPropertyString(
686             "invalid", [&](Status status, const hidl_string&) {
687                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
688             });
689     EXPECT_OK(res);
690 }
691 
TEST_F(DrmHalClearkeyPluginTest,GetByteArrayPropertyNotSupported)692 TEST_F(DrmHalClearkeyPluginTest, GetByteArrayPropertyNotSupported) {
693     auto res = drmPlugin->getPropertyByteArray(
694             "deviceUniqueId", [&](Status status, const hidl_vec<uint8_t>&) {
695                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
696             });
697     EXPECT_OK(res);
698 }
699 
700 /**
701  * Clearkey doesn't support setting string or byte array properties,
702  * particularly an undefined one.
703  */
TEST_F(DrmHalClearkeyPluginTest,SetStringPropertyNotSupported)704 TEST_F(DrmHalClearkeyPluginTest, SetStringPropertyNotSupported) {
705     Status status = drmPlugin->setPropertyString("property", "value");
706     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
707 }
708 
TEST_F(DrmHalClearkeyPluginTest,SetByteArrayPropertyNotSupported)709 TEST_F(DrmHalClearkeyPluginTest, SetByteArrayPropertyNotSupported) {
710     hidl_vec<uint8_t> value;
711     Status status = drmPlugin->setPropertyByteArray("property", value);
712     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
713 }
714 
715 /**
716  * Clearkey doesn't support setting cipher algorithms, verify it
717  */
TEST_F(DrmHalClearkeyPluginTest,SetCipherAlgorithmNotSupported)718 TEST_F(DrmHalClearkeyPluginTest, SetCipherAlgorithmNotSupported) {
719     SessionId session = openSession();
720     hidl_string algorithm = "AES/CBC/NoPadding";
721     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
722     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
723     closeSession(session);
724 }
725 
726 /**
727  * Setting an empty algorithm should return BAD_VALUE
728  */
TEST_F(DrmHalClearkeyPluginTest,SetCipherEmptyAlgorithm)729 TEST_F(DrmHalClearkeyPluginTest, SetCipherEmptyAlgorithm) {
730     SessionId session = openSession();
731     hidl_string algorithm;
732     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
733     EXPECT_EQ(Status::BAD_VALUE, status);
734     closeSession(session);
735 }
736 
737 /**
738  * Setting a cipher algorithm with no session returns BAD_VALUE
739  */
TEST_F(DrmHalClearkeyPluginTest,SetCipherAlgorithmNoSession)740 TEST_F(DrmHalClearkeyPluginTest, SetCipherAlgorithmNoSession) {
741     SessionId session;
742     hidl_string algorithm = "AES/CBC/NoPadding";
743     Status status = drmPlugin->setCipherAlgorithm(session, algorithm);
744     EXPECT_EQ(Status::BAD_VALUE, status);
745 }
746 
747 /**
748  * Clearkey doesn't support setting mac algorithms, verify it
749  */
TEST_F(DrmHalClearkeyPluginTest,SetMacAlgorithmNotSupported)750 TEST_F(DrmHalClearkeyPluginTest, SetMacAlgorithmNotSupported) {
751     SessionId session = openSession();
752     hidl_string algorithm = "HmacSHA256";
753     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
754     EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
755     closeSession(session);
756 }
757 
758 /**
759  * Setting an empty algorithm should return BAD_VALUE
760  */
TEST_F(DrmHalClearkeyPluginTest,SetMacEmptyAlgorithm)761 TEST_F(DrmHalClearkeyPluginTest, SetMacEmptyAlgorithm) {
762     SessionId session = openSession();
763     hidl_string algorithm;
764     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
765     EXPECT_EQ(Status::BAD_VALUE, status);
766     closeSession(session);
767 }
768 
769 /**
770  * Setting a mac algorithm with no session should return BAD_VALUE
771  */
TEST_F(DrmHalClearkeyPluginTest,SetMacAlgorithmNoSession)772 TEST_F(DrmHalClearkeyPluginTest, SetMacAlgorithmNoSession) {
773     SessionId session;
774     hidl_string algorithm = "HmacSHA256";
775     Status status = drmPlugin->setMacAlgorithm(session, algorithm);
776     EXPECT_EQ(Status::BAD_VALUE, status);
777 }
778 
779 /**
780  * The Generic* methods provide general purpose crypto operations
781  * that may be used for applications other than DRM. They leverage
782  * the hardware root of trust and secure key distribution mechanisms
783  * of a DRM system to enable app-specific crypto functionality where
784  * the crypto keys are not exposed outside of the trusted execution
785  * environment.
786  *
787  * Clearkey doesn't support generic encrypt/decrypt/sign/verify.
788  */
TEST_F(DrmHalClearkeyPluginTest,GenericEncryptNotSupported)789 TEST_F(DrmHalClearkeyPluginTest, GenericEncryptNotSupported) {
790     SessionId session = openSession();
791 
792     hidl_vec<uint8_t> keyId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
793     hidl_vec<uint8_t> input = {1, 2, 3, 4, 5};
794     hidl_vec<uint8_t> iv = std::vector<uint8_t>(AES_BLOCK_SIZE, 0);
795     auto res = drmPlugin->encrypt(session, keyId, input, iv,
796                                   [&](Status status, const hidl_vec<uint8_t>&) {
797                                       EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE,
798                                                 status);
799                                   });
800     EXPECT_OK(res);
801     closeSession(session);
802 }
803 
TEST_F(DrmHalClearkeyPluginTest,GenericDecryptNotSupported)804 TEST_F(DrmHalClearkeyPluginTest, GenericDecryptNotSupported) {
805     SessionId session = openSession();
806     hidl_vec<uint8_t> keyId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
807     hidl_vec<uint8_t> input = {1, 2, 3, 4, 5};
808     hidl_vec<uint8_t> iv = std::vector<uint8_t>(AES_BLOCK_SIZE, 0);
809     auto res = drmPlugin->decrypt(session, keyId, input, iv,
810                                   [&](Status status, const hidl_vec<uint8_t>&) {
811                                       EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE,
812                                                 status);
813                                   });
814     EXPECT_OK(res);
815     closeSession(session);
816 }
817 
TEST_F(DrmHalClearkeyPluginTest,GenericSignNotSupported)818 TEST_F(DrmHalClearkeyPluginTest, GenericSignNotSupported) {
819     SessionId session = openSession();
820 
821     hidl_vec<uint8_t> keyId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
822     hidl_vec<uint8_t> message = {1, 2, 3, 4, 5};
823     auto res = drmPlugin->sign(session, keyId, message,
824                                [&](Status status, const hidl_vec<uint8_t>&) {
825                                    EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE,
826                                              status);
827                                });
828     EXPECT_OK(res);
829     closeSession(session);
830 }
831 
TEST_F(DrmHalClearkeyPluginTest,GenericVerifyNotSupported)832 TEST_F(DrmHalClearkeyPluginTest, GenericVerifyNotSupported) {
833     SessionId session = openSession();
834 
835     hidl_vec<uint8_t> keyId = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
836     hidl_vec<uint8_t> message = {1, 2, 3, 4, 5};
837     hidl_vec<uint8_t> signature = {0, 0, 0, 0, 0, 0, 0, 0,
838                                    0, 0, 0, 0, 0, 0, 0, 0};
839     auto res = drmPlugin->verify(
840             session, keyId, message, signature, [&](Status status, bool) {
841                 EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE, status);
842             });
843     EXPECT_OK(res);
844     closeSession(session);
845 }
846 
TEST_F(DrmHalClearkeyPluginTest,GenericSignRSANotSupported)847 TEST_F(DrmHalClearkeyPluginTest, GenericSignRSANotSupported) {
848     SessionId session = openSession();
849     hidl_string algorithm = "RSASSA-PSS-SHA1";
850     hidl_vec<uint8_t> message = {1, 2, 3, 4, 5};
851     hidl_vec<uint8_t> wrappedKey = {0, 0, 0, 0, 0, 0, 0, 0,
852                                     0, 0, 0, 0, 0, 0, 0, 0};
853     auto res = drmPlugin->signRSA(session, algorithm, message, wrappedKey,
854                                   [&](Status status, const hidl_vec<uint8_t>&) {
855                                       EXPECT_EQ(Status::ERROR_DRM_CANNOT_HANDLE,
856                                                 status);
857                                   });
858     EXPECT_OK(res);
859     closeSession(session);
860 }
861 
862 /**
863  *  CryptoPlugin tests
864  */
865 
866 /**
867  * Clearkey doesn't support secure decoder and is expected to
868  * return false.
869  */
TEST_F(DrmHalClearkeyPluginTest,RequiresSecureDecoder)870 TEST_F(DrmHalClearkeyPluginTest, RequiresSecureDecoder) {
871     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent("cenc"));
872 }
873 
874 /**
875  * Verify that requiresSecureDecoderComponent handles empty mimetype
876  */
TEST_F(DrmHalClearkeyPluginTest,RequiresSecureDecoderEmptyMimeType)877 TEST_F(DrmHalClearkeyPluginTest, RequiresSecureDecoderEmptyMimeType) {
878     EXPECT_FALSE(cryptoPlugin->requiresSecureDecoderComponent(""));
879 }
880 
881 /**
882  * Exercise the NotifyResolution API. There is no observable result,
883  * just call the method for coverage.
884  */
TEST_F(DrmHalClearkeyPluginTest,NotifyResolution)885 TEST_F(DrmHalClearkeyPluginTest, NotifyResolution) {
886     cryptoPlugin->notifyResolution(1920, 1080);
887 }
888 
889 /**
890  * getDecryptMemory allocates memory for decryption, then sets it
891  * as a shared buffer base in the crypto hal.  The allocated and
892  * mapped IMemory is returned.
893  *
894  * @param size the size of the memory segment to allocate
895  * @param the index of the memory segment which will be used
896  * to refer to it for decryption.
897  */
getDecryptMemory(size_t size,size_t index)898 sp<IMemory> DrmHalClearkeyPluginTest::getDecryptMemory(size_t size,
899                                                        size_t index) {
900     sp<IAllocator> ashmemAllocator = IAllocator::getService("ashmem");
901     EXPECT_NE(nullptr, ashmemAllocator.get());
902 
903     hidl_memory hidlMemory;
904     auto res = ashmemAllocator->allocate(
905             size, [&](bool success, const hidl_memory& memory) {
906                 EXPECT_EQ(true, success);
907                 EXPECT_OK(cryptoPlugin->setSharedBufferBase(memory, index));
908                 hidlMemory = memory;
909             });
910     EXPECT_OK(res);
911 
912     sp<IMemory> mappedMemory = mapMemory(hidlMemory);
913     EXPECT_NE(nullptr, mappedMemory.get());
914     EXPECT_OK(cryptoPlugin->setSharedBufferBase(hidlMemory, index));
915     return mappedMemory;
916 }
917 
918 /**
919  * Exercise the setMediaDrmSession method. setMediaDrmSession
920  * is used to associate a drm session with a crypto session.
921  */
TEST_F(DrmHalClearkeyPluginTest,SetMediaDrmSession)922 TEST_F(DrmHalClearkeyPluginTest, SetMediaDrmSession) {
923     auto sessionId = openSession();
924     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
925     closeSession(sessionId);
926 }
927 
928 /**
929  * setMediaDrmSession with a closed session id
930  */
TEST_F(DrmHalClearkeyPluginTest,SetMediaDrmSessionClosedSession)931 TEST_F(DrmHalClearkeyPluginTest, SetMediaDrmSessionClosedSession) {
932     auto sessionId = openSession();
933     closeSession(sessionId);
934     Status status = cryptoPlugin->setMediaDrmSession(sessionId);
935     EXPECT_EQ(Status::ERROR_DRM_SESSION_NOT_OPENED, status);
936 }
937 
938 /**
939  * setMediaDrmSession with an empty session id: BAD_VALUE.  An
940  * empty session clears the previously set session and should
941  * return OK.
942  */
TEST_F(DrmHalClearkeyPluginTest,SetMediaDrmSessionEmptySession)943 TEST_F(DrmHalClearkeyPluginTest, SetMediaDrmSessionEmptySession) {
944     SessionId sessionId;
945     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
946 }
947 
948 /**
949  * Decrypt tests
950  */
951 
952 class DrmHalClearkeyDecryptTest : public DrmHalClearkeyPluginTest {
953    public:
954     void fillRandom(const sp<IMemory>& memory);
toHidlArray(const vector<uint8_t> & vec)955     hidl_array<uint8_t, 16> toHidlArray(const vector<uint8_t>& vec) {
956         EXPECT_EQ(16u, vec.size());
957         return hidl_array<uint8_t, 16>(&vec[0]);
958     }
959     uint32_t decrypt(Mode mode, uint8_t* iv, const hidl_vec<SubSample>& subSamples,
960             const Pattern& pattern, Status status);
961     void aes_ctr_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
962             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
963     void aes_cbc_decrypt(uint8_t* dest, uint8_t* src, uint8_t* iv,
964             const hidl_vec<SubSample>& subSamples, const vector<uint8_t>& key);
965     void decryptWithInvalidKeys(hidl_vec<uint8_t>& invalidResponse,
966             vector<uint8_t>& iv, const Pattern& noPattern, const vector<SubSample>& subSamples);
967 };
968 
fillRandom(const sp<IMemory> & memory)969 void DrmHalClearkeyDecryptTest::fillRandom(const sp<IMemory>& memory) {
970     random_device rd;
971     mt19937 rand(rd());
972     for (size_t i = 0; i < memory->getSize() / sizeof(uint32_t); i++) {
973         auto p = static_cast<uint32_t*>(
974                 static_cast<void*>(memory->getPointer()));
975         p[i] = rand();
976     }
977 }
978 
decrypt(Mode mode,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const Pattern & pattern,Status expectedStatus)979 uint32_t DrmHalClearkeyDecryptTest::decrypt(Mode mode,
980         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
981         const Pattern& pattern, Status expectedStatus) {
982     const size_t kSegmentIndex = 0;
983     const vector<uint8_t> keyId = {0x60, 0x06, 0x1e, 0x01, 0x7e, 0x47,
984                                    0x7e, 0x87, 0x7e, 0x57, 0xd0, 0x0d,
985                                    0x1e, 0xd0, 0x0d, 0x1e};
986     const vector<uint8_t> contentKey = {0x1a, 0x8a, 0x20, 0x95, 0xe4,
987                                         0xde, 0xb2, 0xd2, 0x9e, 0xc8,
988                                         0x16, 0xac, 0x7b, 0xae, 0x20, 0x82};
989     uint8_t localIv[AES_BLOCK_SIZE];
990     memcpy(localIv, iv, AES_BLOCK_SIZE);
991 
992     size_t totalSize = 0;
993     for (size_t i = 0; i < subSamples.size(); i++) {
994         totalSize += subSamples[i].numBytesOfClearData;
995         totalSize += subSamples[i].numBytesOfEncryptedData;
996     }
997 
998     // The first totalSize bytes of shared memory is the encrypted
999     // input, the second totalSize bytes is the decrypted output.
1000     sp<IMemory> sharedMemory =
1001             getDecryptMemory(totalSize * 2, kSegmentIndex);
1002 
1003     const SharedBuffer sourceBuffer = {
1004         .bufferId = kSegmentIndex, .offset = 0, .size = totalSize};
1005     fillRandom(sharedMemory);
1006 
1007     const DestinationBuffer destBuffer = {.type = BufferType::SHARED_MEMORY,
1008                                           {.bufferId = kSegmentIndex,
1009                                            .offset = totalSize,
1010                                            .size = totalSize},
1011                                           .secureMemory = nullptr};
1012     const uint64_t offset = 0;
1013     const bool kNotSecure = false;
1014     uint32_t bytesWritten = 0;
1015     auto res = cryptoPlugin->decrypt(kNotSecure, toHidlArray(keyId), localIv, mode,
1016             pattern, subSamples, sourceBuffer, offset, destBuffer,
1017             [&](Status status, uint32_t count, string detailedError) {
1018                 EXPECT_EQ(expectedStatus, status) << "Unexpected decrypt status " <<
1019                 detailedError;
1020                 bytesWritten = count;
1021             });
1022     EXPECT_OK(res);
1023 
1024     if (bytesWritten != totalSize) {
1025         return bytesWritten;
1026     }
1027     uint8_t* base = static_cast<uint8_t*>(
1028             static_cast<void*>(sharedMemory->getPointer()));
1029 
1030     // generate reference vector
1031     vector<uint8_t> reference(totalSize);
1032 
1033     memcpy(localIv, iv, AES_BLOCK_SIZE);
1034     switch (mode) {
1035     case Mode::UNENCRYPTED:
1036         memcpy(&reference[0], base, totalSize);
1037         break;
1038     case Mode::AES_CTR:
1039         aes_ctr_decrypt(&reference[0], base, localIv, subSamples, contentKey);
1040         break;
1041     case Mode::AES_CBC:
1042         aes_cbc_decrypt(&reference[0], base, localIv, subSamples, contentKey);
1043         break;
1044     case Mode::AES_CBC_CTS:
1045         EXPECT_TRUE(false) << "AES_CBC_CTS mode not supported";
1046         break;
1047     }
1048 
1049     // compare reference to decrypted data which is at base + total size
1050     EXPECT_EQ(0, memcmp(static_cast<void *>(&reference[0]),
1051                         static_cast<void*>(base + totalSize), totalSize))
1052             << "decrypt data mismatch";
1053     return totalSize;
1054 }
1055 
1056 /**
1057  * Decrypt a list of clear+encrypted subsamples using the specified key
1058  * in AES-CTR mode
1059  */
aes_ctr_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)1060 void DrmHalClearkeyDecryptTest::aes_ctr_decrypt(uint8_t* dest, uint8_t* src,
1061         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
1062         const vector<uint8_t>& key) {
1063     AES_KEY decryptionKey;
1064     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
1065 
1066     size_t offset = 0;
1067     unsigned int blockOffset = 0;
1068     uint8_t previousEncryptedCounter[AES_BLOCK_SIZE];
1069     memset(previousEncryptedCounter, 0, AES_BLOCK_SIZE);
1070 
1071     for (size_t i = 0; i < subSamples.size(); i++) {
1072         const SubSample& subSample = subSamples[i];
1073 
1074         if (subSample.numBytesOfClearData > 0) {
1075             memcpy(dest + offset, src + offset, subSample.numBytesOfClearData);
1076             offset += subSample.numBytesOfClearData;
1077         }
1078 
1079         if (subSample.numBytesOfEncryptedData > 0) {
1080             AES_ctr128_encrypt(src + offset, dest + offset,
1081                     subSample.numBytesOfEncryptedData, &decryptionKey,
1082                     iv, previousEncryptedCounter, &blockOffset);
1083             offset += subSample.numBytesOfEncryptedData;
1084         }
1085     }
1086 }
1087 
1088 /**
1089  * Decrypt a list of clear+encrypted subsamples using the specified key
1090  * in AES-CBC mode
1091  */
aes_cbc_decrypt(uint8_t * dest,uint8_t * src,uint8_t * iv,const hidl_vec<SubSample> & subSamples,const vector<uint8_t> & key)1092 void DrmHalClearkeyDecryptTest::aes_cbc_decrypt(uint8_t* dest, uint8_t* src,
1093         uint8_t* iv, const hidl_vec<SubSample>& subSamples,
1094         const vector<uint8_t>& key) {
1095     AES_KEY decryptionKey;
1096     AES_set_encrypt_key(&key[0], 128, &decryptionKey);
1097 
1098     size_t offset = 0;
1099     for (size_t i = 0; i < subSamples.size(); i++) {
1100         memcpy(dest + offset, src + offset, subSamples[i].numBytesOfClearData);
1101         offset += subSamples[i].numBytesOfClearData;
1102 
1103         AES_cbc_encrypt(src + offset, dest + offset, subSamples[i].numBytesOfEncryptedData,
1104                 &decryptionKey, iv, 0 /* decrypt */);
1105         offset += subSamples[i].numBytesOfEncryptedData;
1106     }
1107 }
1108 
1109 /**
1110  * Test query key status
1111  */
TEST_F(DrmHalClearkeyDecryptTest,TestQueryKeyStatus)1112 TEST_F(DrmHalClearkeyDecryptTest, TestQueryKeyStatus) {
1113     auto sessionId = openSession();
1114     auto res = drmPlugin->queryKeyStatus(
1115         sessionId, [&](Status status, KeyedVector /* info */) { EXPECT_EQ(Status::OK, status); });
1116     EXPECT_OK(res);
1117 
1118     closeSession(sessionId);
1119 }
1120 
1121 /**
1122  * Positive decrypt test.  "Decrypt" a single clear segment
1123  */
TEST_F(DrmHalClearkeyDecryptTest,ClearSegmentTest)1124 TEST_F(DrmHalClearkeyDecryptTest, ClearSegmentTest) {
1125     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1126     const Pattern noPattern = {0, 0};
1127     const uint32_t kByteCount = 256;
1128     const vector<SubSample> subSamples = {
1129         {.numBytesOfClearData = kByteCount,
1130          .numBytesOfEncryptedData = 0}};
1131     auto sessionId = openSession();
1132     loadKeys(sessionId);
1133     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
1134 
1135     uint32_t byteCount = decrypt(Mode::UNENCRYPTED, &iv[0], subSamples,
1136             noPattern, Status::OK);
1137     EXPECT_EQ(kByteCount, byteCount);
1138 
1139     closeSession(sessionId);
1140 }
1141 
1142 /**
1143  * Positive decrypt test.  Decrypt a single segment using AES_CTR.
1144  * Verify data matches.
1145  */
TEST_F(DrmHalClearkeyDecryptTest,EncryptedAesCtrSegmentTest)1146 TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTest) {
1147     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1148     const Pattern noPattern = {0, 0};
1149     const uint32_t kClearBytes = 512;
1150     const uint32_t kEncryptedBytes = 512;
1151     const vector<SubSample> subSamples = {
1152         {.numBytesOfClearData = kClearBytes,
1153          .numBytesOfEncryptedData = kEncryptedBytes}};
1154     auto sessionId = openSession();
1155     loadKeys(sessionId);
1156     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
1157 
1158     uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
1159             noPattern, Status::OK);
1160     EXPECT_EQ(kClearBytes + kEncryptedBytes, byteCount);
1161 
1162     closeSession(sessionId);
1163 }
1164 
1165 /**
1166  * Negative decrypt test. Decrypt without loading keys.
1167  */
TEST_F(DrmHalClearkeyDecryptTest,EncryptedAesCtrSegmentTestNoKeys)1168 TEST_F(DrmHalClearkeyDecryptTest, EncryptedAesCtrSegmentTestNoKeys) {
1169     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1170     const Pattern noPattern = {0, 0};
1171     const vector<SubSample> subSamples = {
1172         {.numBytesOfClearData = 256,
1173          .numBytesOfEncryptedData = 256}};
1174     auto sessionId = openSession();
1175     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
1176 
1177     uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
1178             noPattern, Status::ERROR_DRM_NO_LICENSE);
1179     EXPECT_EQ(0u, byteCount);
1180 
1181     closeSession(sessionId);
1182 }
1183 
1184 /**
1185  * Helper method to test decryption with invalid keys is returned
1186  */
decryptWithInvalidKeys(hidl_vec<uint8_t> & invalidResponse,vector<uint8_t> & iv,const Pattern & noPattern,const vector<SubSample> & subSamples)1187 void DrmHalClearkeyDecryptTest::decryptWithInvalidKeys(
1188         hidl_vec<uint8_t>& invalidResponse,
1189         vector<uint8_t>& iv,
1190         const Pattern& noPattern,
1191         const vector<SubSample>& subSamples) {
1192     auto sessionId = openSession();
1193 
1194     auto res = drmPlugin->provideKeyResponse(
1195         sessionId, invalidResponse,
1196         [&](Status status, const hidl_vec<uint8_t>& myKeySetId) {
1197             EXPECT_EQ(Status::OK, status);
1198             EXPECT_EQ(0u, myKeySetId.size());
1199         });
1200     EXPECT_OK(res);
1201 
1202     EXPECT_TRUE(cryptoPlugin->setMediaDrmSession(sessionId).isOk());
1203 
1204     uint32_t byteCount = decrypt(Mode::AES_CTR, &iv[0], subSamples,
1205             noPattern, Status::ERROR_DRM_NO_LICENSE);
1206     EXPECT_EQ(0u, byteCount);
1207 
1208     closeSession(sessionId);
1209 }
1210 
1211 /**
1212  * Negative decrypt test. Decrypt with invalid key.
1213  */
TEST_F(DrmHalClearkeyDecryptTest,DecryptWithEmptyKey)1214 TEST_F(DrmHalClearkeyDecryptTest, DecryptWithEmptyKey) {
1215     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1216     const Pattern noPattern = {0, 0};
1217     const uint32_t kClearBytes = 512;
1218     const uint32_t kEncryptedBytes = 512;
1219     const vector<SubSample> subSamples = {
1220         {.numBytesOfClearData = kClearBytes,
1221          .numBytesOfEncryptedData = kEncryptedBytes}};
1222 
1223     // base 64 encoded JSON response string, must not contain padding character '='
1224     const hidl_string emptyKeyResponse =
1225             "{\"keys\":[" \
1226                 "{" \
1227                     "\"kty\":\"oct\"" \
1228                     "\"alg\":\"A128KW2\"" \
1229                     "\"k\":\"SGVsbG8gRnJpZW5kIQ\"" \
1230                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAyAy\"" \
1231                 "}" \
1232                 "{" \
1233                     "\"kty\":\"oct\"," \
1234                     "\"alg\":\"A128KW2\"" \
1235                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
1236                     // empty key follows
1237                     "\"k\":\"R\"" \
1238                 "}]" \
1239             "}";
1240     const size_t kEmptyKeyResponseSize = emptyKeyResponse.size();
1241 
1242     hidl_vec<uint8_t> invalidResponse;
1243     invalidResponse.resize(kEmptyKeyResponseSize);
1244     memcpy(invalidResponse.data(), emptyKeyResponse.c_str(), kEmptyKeyResponseSize);
1245     decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
1246 }
1247 
1248 /**
1249  * Negative decrypt test. Decrypt with a key exceeds AES_BLOCK_SIZE.
1250  */
TEST_F(DrmHalClearkeyDecryptTest,DecryptWithKeyTooLong)1251 TEST_F(DrmHalClearkeyDecryptTest, DecryptWithKeyTooLong) {
1252     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
1253     const Pattern noPattern = {0, 0};
1254     const uint32_t kClearBytes = 512;
1255     const uint32_t kEncryptedBytes = 512;
1256     const vector<SubSample> subSamples = {
1257         {.numBytesOfClearData = kClearBytes,
1258          .numBytesOfEncryptedData = kEncryptedBytes}};
1259 
1260     // base 64 encoded JSON response string, must not contain padding character '='
1261     const hidl_string keyTooLongResponse =
1262             "{\"keys\":[" \
1263                 "{" \
1264                     "\"kty\":\"oct\"," \
1265                     "\"alg\":\"A128KW2\"" \
1266                     "\"kid\":\"Y2xlYXJrZXlrZXlpZDAzAy\"," \
1267                     // key too long
1268                     "\"k\":\"V2lubmllIHRoZSBwb29oIVdpbm5pZSB0aGUgcG9vaCE=\"" \
1269                 "}]" \
1270             "}";
1271     const size_t kKeyTooLongResponseSize = keyTooLongResponse.size();
1272 
1273     hidl_vec<uint8_t> invalidResponse;
1274     invalidResponse.resize(kKeyTooLongResponseSize);
1275     memcpy(invalidResponse.data(), keyTooLongResponse.c_str(), kKeyTooLongResponseSize);
1276     decryptWithInvalidKeys(invalidResponse, iv, noPattern, subSamples);
1277 }
1278