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