1 /*
2 * Copyright (C) 2018 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_NDEBUG 0
18 #define LOG_TAG "hidl_ClearKeyPlugin"
19 #include <utils/Log.h>
20
21 #include <chrono>
22 #include <stdio.h>
23 #include <inttypes.h>
24
25 #include "DrmPlugin.h"
26 #include "ClearKeyDrmProperties.h"
27 #include "Session.h"
28 #include "TypeConvert.h"
29 #include "Utils.h"
30
31 namespace {
32 const std::string kKeySetIdPrefix("ckid");
33 const int kKeySetIdLength = 16;
34 const int kSecureStopIdStart = 100;
35 const std::string kOfflineLicense("\"type\":\"persistent-license\"");
36 const std::string kStreaming("Streaming");
37 const std::string kTemporaryLicense("\"type\":\"temporary\"");
38 const std::string kTrue("True");
39
40 const std::string kQueryKeyLicenseType("LicenseType");
41 // Value: "Streaming" or "Offline"
42 const std::string kQueryKeyPlayAllowed("PlayAllowed");
43 // Value: "True" or "False"
44 const std::string kQueryKeyRenewAllowed("RenewAllowed");
45 // Value: "True" or "False"
46
47 const int kSecureStopIdSize = 10;
48
uint32ToVector(uint32_t value)49 std::vector<uint8_t> uint32ToVector(uint32_t value) {
50 // 10 bytes to display max value 4294967295 + one byte null terminator
51 char buffer[kSecureStopIdSize];
52 memset(buffer, 0, kSecureStopIdSize);
53 snprintf(buffer, kSecureStopIdSize, "%" PRIu32, value);
54 return std::vector<uint8_t>(buffer, buffer + sizeof(buffer));
55 }
56
57 }; // unnamed namespace
58
59 namespace android {
60 namespace hardware {
61 namespace drm {
62 namespace V1_4 {
63 namespace clearkey {
64
toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType)65 KeyRequestType toKeyRequestType_V1_0(KeyRequestType_V1_1 keyRequestType) {
66 switch (keyRequestType) {
67 case KeyRequestType_V1_1::NONE:
68 case KeyRequestType_V1_1::UPDATE:
69 return KeyRequestType::UNKNOWN;
70 default:
71 return static_cast<KeyRequestType>(keyRequestType);
72 }
73 }
74
DrmPlugin(SessionLibrary * sessionLibrary)75 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
76 : mSessionLibrary(sessionLibrary),
77 mOpenSessionOkCount(0),
78 mCloseSessionOkCount(0),
79 mCloseSessionNotOpenedCount(0),
80 mNextSecureStopId(kSecureStopIdStart),
81 mMockError(Status_V1_2::OK) {
82 mPlayPolicy.clear();
83 initProperties();
84 mSecureStops.clear();
85 mReleaseKeysMap.clear();
86 std::srand(std::time(nullptr));
87 }
88
initProperties()89 void DrmPlugin::initProperties() {
90 mStringProperties.clear();
91 mStringProperties[kVendorKey] = kVendorValue;
92 mStringProperties[kVersionKey] = kVersionValue;
93 mStringProperties[kPluginDescriptionKey] = kPluginDescriptionValue;
94 mStringProperties[kAlgorithmsKey] = kAlgorithmsValue;
95 mStringProperties[kListenerTestSupportKey] = kListenerTestSupportValue;
96 mStringProperties[kDrmErrorTestKey] = kDrmErrorTestValue;
97
98 std::vector<uint8_t> valueVector;
99 valueVector.clear();
100 valueVector.insert(valueVector.end(),
101 kTestDeviceIdData, kTestDeviceIdData + sizeof(kTestDeviceIdData) / sizeof(uint8_t));
102 mByteArrayProperties[kDeviceIdKey] = valueVector;
103
104 valueVector.clear();
105 valueVector.insert(valueVector.end(),
106 kMetricsData, kMetricsData + sizeof(kMetricsData) / sizeof(uint8_t));
107 mByteArrayProperties[kMetricsKey] = valueVector;
108 }
109
110 // The secure stop in ClearKey implementation is not installed securely.
111 // This function merely creates a test environment for testing secure stops APIs.
112 // The content in this secure stop is implementation dependent, the clearkey
113 // secureStop does not serve as a reference implementation.
installSecureStop(const hidl_vec<uint8_t> & sessionId)114 void DrmPlugin::installSecureStop(const hidl_vec<uint8_t>& sessionId) {
115 Mutex::Autolock lock(mSecureStopLock);
116
117 ClearkeySecureStop clearkeySecureStop;
118 clearkeySecureStop.id = uint32ToVector(++mNextSecureStopId);
119 clearkeySecureStop.data.assign(sessionId.begin(), sessionId.end());
120
121 mSecureStops.insert(std::pair<std::vector<uint8_t>, ClearkeySecureStop>(
122 clearkeySecureStop.id, clearkeySecureStop));
123 }
124
openSession(openSession_cb _hidl_cb)125 Return<void> DrmPlugin::openSession(openSession_cb _hidl_cb) {
126 sp<Session> session = mSessionLibrary->createSession();
127 processMockError(session);
128 std::vector<uint8_t> sessionId = session->sessionId();
129
130 Status status = setSecurityLevel(sessionId, SecurityLevel::SW_SECURE_CRYPTO);
131 _hidl_cb(status, toHidlVec(sessionId));
132 mOpenSessionOkCount++;
133 return Void();
134 }
135
openSession_1_1(SecurityLevel securityLevel,openSession_1_1_cb _hidl_cb)136 Return<void> DrmPlugin::openSession_1_1(SecurityLevel securityLevel,
137 openSession_1_1_cb _hidl_cb) {
138 sp<Session> session = mSessionLibrary->createSession();
139 processMockError(session);
140 std::vector<uint8_t> sessionId = session->sessionId();
141
142 Status status = setSecurityLevel(sessionId, securityLevel);
143 if (status == Status::OK) {
144 mOpenSessionOkCount++;
145 } else {
146 mSessionLibrary->destroySession(session);
147 sessionId.clear();
148 }
149 _hidl_cb(status, toHidlVec(sessionId));
150 return Void();
151 }
152
closeSession(const hidl_vec<uint8_t> & sessionId)153 Return<Status> DrmPlugin::closeSession(const hidl_vec<uint8_t>& sessionId) {
154 if (sessionId.size() == 0) {
155 return Status::BAD_VALUE;
156 }
157
158 sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
159 if (session.get()) {
160 mSessionLibrary->destroySession(session);
161 if (session->getMockError() != Status_V1_2::OK) {
162 sendSessionLostState(sessionId);
163 return Status::ERROR_DRM_INVALID_STATE;
164 }
165 mCloseSessionOkCount++;
166 return Status::OK;
167 }
168 mCloseSessionNotOpenedCount++;
169 return Status::ERROR_DRM_SESSION_NOT_OPENED;
170 }
171
getKeyRequestCommon(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & initData,const hidl_string & mimeType,KeyType keyType,const hidl_vec<KeyValue> & optionalParameters,std::vector<uint8_t> * request,KeyRequestType_V1_1 * keyRequestType,std::string * defaultUrl)172 Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope,
173 const hidl_vec<uint8_t>& initData,
174 const hidl_string& mimeType,
175 KeyType keyType,
176 const hidl_vec<KeyValue>& optionalParameters,
177 std::vector<uint8_t> *request,
178 KeyRequestType_V1_1 *keyRequestType,
179 std::string *defaultUrl) {
180 UNUSED(optionalParameters);
181
182 // GetKeyRequestOfflineKeyTypeNotSupported() in vts 1.0 and 1.1 expects
183 // KeyType::OFFLINE to return ERROR_DRM_CANNOT_HANDLE in clearkey plugin.
184 // Those tests pass in an empty initData, we use the empty initData to
185 // signal such specific use case.
186 if (keyType == KeyType::OFFLINE && 0 == initData.size()) {
187 return Status_V1_2::ERROR_DRM_CANNOT_HANDLE;
188 }
189
190 *defaultUrl = "https://default.url";
191 *keyRequestType = KeyRequestType_V1_1::UNKNOWN;
192 *request = std::vector<uint8_t>();
193
194 if (scope.size() == 0 ||
195 (keyType != KeyType::STREAMING &&
196 keyType != KeyType::OFFLINE &&
197 keyType != KeyType::RELEASE)) {
198 return Status_V1_2::BAD_VALUE;
199 }
200
201 const std::vector<uint8_t> scopeId = toVector(scope);
202 sp<Session> session;
203 if (keyType == KeyType::STREAMING || keyType == KeyType::OFFLINE) {
204 std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
205 session = mSessionLibrary->findSession(sessionId);
206 if (!session.get()) {
207 return Status_V1_2::ERROR_DRM_SESSION_NOT_OPENED;
208 } else if (session->getMockError() != Status_V1_2::OK) {
209 return session->getMockError();
210 }
211
212 *keyRequestType = KeyRequestType_V1_1::INITIAL;
213 }
214
215 Status_V1_2 status = static_cast<Status_V1_2>(
216 session->getKeyRequest(initData, mimeType, keyType, request));
217
218 if (keyType == KeyType::RELEASE) {
219 std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
220 std::string requestString(request->begin(), request->end());
221 if (requestString.find(kOfflineLicense) != std::string::npos) {
222 std::string emptyResponse;
223 std::string keySetIdString(keySetId.begin(), keySetId.end());
224 if (!mFileHandle.StoreLicense(keySetIdString,
225 DeviceFiles::kLicenseStateReleasing,
226 emptyResponse)) {
227 ALOGE("Problem releasing offline license");
228 return Status_V1_2::ERROR_DRM_UNKNOWN;
229 }
230 if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
231 sp<Session> session = mSessionLibrary->createSession();
232 mReleaseKeysMap[keySetIdString] = session->sessionId();
233 } else {
234 ALOGI("key is in use, ignore release request");
235 }
236 } else {
237 ALOGE("Offline license not found, nothing to release");
238 }
239 *keyRequestType = KeyRequestType_V1_1::RELEASE;
240 }
241 return status;
242 }
243
getKeyRequest(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & initData,const hidl_string & mimeType,KeyType keyType,const hidl_vec<KeyValue> & optionalParameters,getKeyRequest_cb _hidl_cb)244 Return<void> DrmPlugin::getKeyRequest(
245 const hidl_vec<uint8_t>& scope,
246 const hidl_vec<uint8_t>& initData,
247 const hidl_string& mimeType,
248 KeyType keyType,
249 const hidl_vec<KeyValue>& optionalParameters,
250 getKeyRequest_cb _hidl_cb) {
251 UNUSED(optionalParameters);
252
253 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
254 std::string defaultUrl("");
255 std::vector<uint8_t> request;
256 Status_V1_2 status = getKeyRequestCommon(
257 scope, initData, mimeType, keyType, optionalParameters,
258 &request, &keyRequestType, &defaultUrl);
259
260 _hidl_cb(toStatus_1_0(status), toHidlVec(request),
261 toKeyRequestType_V1_0(keyRequestType),
262 hidl_string(defaultUrl));
263 return Void();
264 }
265
getKeyRequest_1_1(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & initData,const hidl_string & mimeType,KeyType keyType,const hidl_vec<KeyValue> & optionalParameters,getKeyRequest_1_1_cb _hidl_cb)266 Return<void> DrmPlugin::getKeyRequest_1_1(
267 const hidl_vec<uint8_t>& scope,
268 const hidl_vec<uint8_t>& initData,
269 const hidl_string& mimeType,
270 KeyType keyType,
271 const hidl_vec<KeyValue>& optionalParameters,
272 getKeyRequest_1_1_cb _hidl_cb) {
273 UNUSED(optionalParameters);
274
275 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
276 std::string defaultUrl("");
277 std::vector<uint8_t> request;
278 Status_V1_2 status = getKeyRequestCommon(
279 scope, initData, mimeType, keyType, optionalParameters,
280 &request, &keyRequestType, &defaultUrl);
281
282 _hidl_cb(toStatus_1_0(status), toHidlVec(request),
283 keyRequestType, hidl_string(defaultUrl));
284 return Void();
285 }
286
getKeyRequest_1_2(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & initData,const hidl_string & mimeType,KeyType keyType,const hidl_vec<KeyValue> & optionalParameters,getKeyRequest_1_2_cb _hidl_cb)287 Return<void> DrmPlugin::getKeyRequest_1_2(
288 const hidl_vec<uint8_t>& scope,
289 const hidl_vec<uint8_t>& initData,
290 const hidl_string& mimeType,
291 KeyType keyType,
292 const hidl_vec<KeyValue>& optionalParameters,
293 getKeyRequest_1_2_cb _hidl_cb) {
294 UNUSED(optionalParameters);
295
296 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
297 std::string defaultUrl("");
298 std::vector<uint8_t> request;
299 Status_V1_2 status = getKeyRequestCommon(
300 scope, initData, mimeType, keyType, optionalParameters,
301 &request, &keyRequestType, &defaultUrl);
302
303 _hidl_cb(status, toHidlVec(request), keyRequestType, hidl_string(defaultUrl));
304 return Void();
305 }
306
setPlayPolicy()307 void DrmPlugin::setPlayPolicy() {
308 android::Mutex::Autolock lock(mPlayPolicyLock);
309 mPlayPolicy.clear();
310
311 KeyValue policy;
312 policy.key = kQueryKeyLicenseType;
313 policy.value = kStreaming;
314 mPlayPolicy.push_back(policy);
315
316 policy.key = kQueryKeyPlayAllowed;
317 policy.value = kTrue;
318 mPlayPolicy.push_back(policy);
319
320 policy.key = kQueryKeyRenewAllowed;
321 mPlayPolicy.push_back(policy);
322 }
323
makeKeySetId(std::string * keySetId)324 bool DrmPlugin::makeKeySetId(std::string* keySetId) {
325 if (!keySetId) {
326 ALOGE("keySetId destination not provided");
327 return false;
328 }
329 std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
330 ksid.resize(kKeySetIdLength);
331 std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
332
333 while (keySetId->empty()) {
334 for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
335 *itr = std::rand() % 0xff;
336 }
337 *keySetId = kKeySetIdPrefix + ByteArrayToHexString(
338 reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size());
339 if (mFileHandle.LicenseExists(*keySetId)) {
340 // collision, regenerate
341 ALOGV("Retry generating KeySetId");
342 keySetId->clear();
343 }
344 }
345 return true;
346 }
347
provideKeyResponse(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & response,provideKeyResponse_cb _hidl_cb)348 Return<void> DrmPlugin::provideKeyResponse(
349 const hidl_vec<uint8_t>& scope,
350 const hidl_vec<uint8_t>& response,
351 provideKeyResponse_cb _hidl_cb) {
352 if (scope.size() == 0 || response.size() == 0) {
353 // Returns empty keySetId
354 _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
355 return Void();
356 }
357
358 std::string responseString(
359 reinterpret_cast<const char*>(response.data()), response.size());
360 const std::vector<uint8_t> scopeId = toVector(scope);
361 std::vector<uint8_t> sessionId;
362 std::string keySetId;
363
364 Status status = Status::OK;
365 bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
366 if (scopeId.size() < kKeySetIdPrefix.size()) {
367 android_errorWriteLog(0x534e4554, "144507096");
368 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
369 return Void();
370 }
371 bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
372 if (isRelease) {
373 keySetId.assign(scopeId.begin(), scopeId.end());
374
375 auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
376 if (iter != mReleaseKeysMap.end()) {
377 sessionId.assign(iter->second.begin(), iter->second.end());
378 }
379 } else {
380 sessionId.assign(scopeId.begin(), scopeId.end());
381 // non offline license returns empty keySetId
382 keySetId.clear();
383 }
384
385 sp<Session> session = mSessionLibrary->findSession(sessionId);
386 if (!session.get()) {
387 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
388 return Void();
389 }
390 setPlayPolicy();
391
392 status = session->provideKeyResponse(response);
393 if (status == Status::OK) {
394 if (isOfflineLicense) {
395 if (isRelease) {
396 mFileHandle.DeleteLicense(keySetId);
397 mSessionLibrary->destroySession(session);
398 } else {
399 if (!makeKeySetId(&keySetId)) {
400 _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
401 return Void();
402 }
403
404 bool ok = mFileHandle.StoreLicense(
405 keySetId,
406 DeviceFiles::kLicenseStateActive,
407 std::string(response.begin(), response.end()));
408 if (!ok) {
409 ALOGE("Failed to store offline license");
410 }
411 }
412 }
413
414 // Test calling AMediaDrm listeners.
415 sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
416
417 sendExpirationUpdate(sessionId, 100);
418
419 std::vector<KeyStatus_V1_2> keysStatus;
420 KeyStatus_V1_2 keyStatus;
421
422 std::vector<uint8_t> keyId1 = { 0xA, 0xB, 0xC };
423 keyStatus.keyId = keyId1;
424 keyStatus.type = V1_2::KeyStatusType::USABLE;
425 keysStatus.push_back(keyStatus);
426
427 std::vector<uint8_t> keyId2 = { 0xD, 0xE, 0xF };
428 keyStatus.keyId = keyId2;
429 keyStatus.type = V1_2::KeyStatusType::EXPIRED;
430 keysStatus.push_back(keyStatus);
431
432 std::vector<uint8_t> keyId3 = { 0x0, 0x1, 0x2 };
433 keyStatus.keyId = keyId3;
434 keyStatus.type = V1_2::KeyStatusType::USABLEINFUTURE;
435 keysStatus.push_back(keyStatus);
436
437 sendKeysChange_1_2(sessionId, keysStatus, true);
438
439 installSecureStop(sessionId);
440 } else {
441 ALOGE("provideKeyResponse returns error=%d", status);
442 }
443
444 std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
445 _hidl_cb(status, toHidlVec(keySetIdVec));
446 return Void();
447 }
448
restoreKeys(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keySetId)449 Return<Status> DrmPlugin::restoreKeys(
450 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) {
451 if (sessionId.size() == 0 || keySetId.size() == 0) {
452 return Status::BAD_VALUE;
453 }
454
455 DeviceFiles::LicenseState licenseState;
456 std::string offlineLicense;
457 Status status = Status::OK;
458 if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
459 &licenseState, &offlineLicense)) {
460 ALOGE("Failed to restore offline license");
461 return Status::ERROR_DRM_NO_LICENSE;
462 }
463
464 if (DeviceFiles::kLicenseStateUnknown == licenseState ||
465 DeviceFiles::kLicenseStateReleasing == licenseState) {
466 ALOGE("Invalid license state=%d", licenseState);
467 return Status::ERROR_DRM_NO_LICENSE;
468 }
469
470 sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
471 if (!session.get()) {
472 return Status::ERROR_DRM_SESSION_NOT_OPENED;
473 }
474 status = session->provideKeyResponse(std::vector<uint8_t>(offlineLicense.begin(),
475 offlineLicense.end()));
476 if (status != Status::OK) {
477 ALOGE("Failed to restore keys");
478 }
479 return status;
480 }
481
getPropertyString(const hidl_string & propertyName,getPropertyString_cb _hidl_cb)482 Return<void> DrmPlugin::getPropertyString(
483 const hidl_string& propertyName, getPropertyString_cb _hidl_cb) {
484 std::string name(propertyName.c_str());
485 std::string value;
486
487 if (name == kVendorKey) {
488 value = mStringProperties[kVendorKey];
489 } else if (name == kVersionKey) {
490 value = mStringProperties[kVersionKey];
491 } else if (name == kPluginDescriptionKey) {
492 value = mStringProperties[kPluginDescriptionKey];
493 } else if (name == kAlgorithmsKey) {
494 value = mStringProperties[kAlgorithmsKey];
495 } else if (name == kListenerTestSupportKey) {
496 value = mStringProperties[kListenerTestSupportKey];
497 } else if (name == kDrmErrorTestKey) {
498 value = mStringProperties[kDrmErrorTestKey];
499 } else {
500 ALOGE("App requested unknown string property %s", name.c_str());
501 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
502 return Void();
503 }
504 _hidl_cb(Status::OK, value.c_str());
505 return Void();
506 }
507
getPropertyByteArray(const hidl_string & propertyName,getPropertyByteArray_cb _hidl_cb)508 Return<void> DrmPlugin::getPropertyByteArray(
509 const hidl_string& propertyName, getPropertyByteArray_cb _hidl_cb) {
510 std::map<std::string, std::vector<uint8_t> >::iterator itr =
511 mByteArrayProperties.find(std::string(propertyName.c_str()));
512 if (itr == mByteArrayProperties.end()) {
513 ALOGE("App requested unknown property: %s", propertyName.c_str());
514 _hidl_cb(Status::BAD_VALUE, std::vector<uint8_t>());
515 return Void();
516 }
517 _hidl_cb(Status::OK, itr->second);
518 return Void();
519
520 }
521
setPropertyString(const hidl_string & name,const hidl_string & value)522 Return<Status> DrmPlugin::setPropertyString(
523 const hidl_string& name, const hidl_string& value) {
524 std::string immutableKeys;
525 immutableKeys.append(kAlgorithmsKey + ",");
526 immutableKeys.append(kPluginDescriptionKey + ",");
527 immutableKeys.append(kVendorKey + ",");
528 immutableKeys.append(kVersionKey + ",");
529
530 std::string key = std::string(name.c_str());
531 if (immutableKeys.find(key) != std::string::npos) {
532 ALOGD("Cannot set immutable property: %s", key.c_str());
533 return Status::BAD_VALUE;
534 }
535
536 std::map<std::string, std::string>::iterator itr =
537 mStringProperties.find(key);
538 if (itr == mStringProperties.end()) {
539 ALOGE("Cannot set undefined property string, key=%s", key.c_str());
540 return Status::BAD_VALUE;
541 }
542
543 if (name == kDrmErrorTestKey) {
544 if (value == kResourceContentionValue) {
545 mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
546 } else if (value == kLostStateValue) {
547 mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
548 } else if (value == kFrameTooLargeValue) {
549 mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
550 } else if (value == kInvalidStateValue) {
551 mMockError = Status_V1_2::ERROR_DRM_INVALID_STATE;
552 } else {
553 mMockError = Status_V1_2::ERROR_DRM_UNKNOWN;
554 }
555 }
556
557 mStringProperties[key] = std::string(value.c_str());
558 return Status::OK;
559 }
560
setPropertyByteArray(const hidl_string & name,const hidl_vec<uint8_t> & value)561 Return<Status> DrmPlugin::setPropertyByteArray(
562 const hidl_string& name, const hidl_vec<uint8_t>& value) {
563 UNUSED(value);
564 if (name == kDeviceIdKey) {
565 ALOGD("Cannot set immutable property: %s", name.c_str());
566 return Status::BAD_VALUE;
567 } else if (name == kClientIdKey) {
568 mByteArrayProperties[kClientIdKey] = toVector(value);
569 return Status::OK;
570 }
571
572 // Setting of undefined properties is not supported
573 ALOGE("Failed to set property byte array, key=%s", name.c_str());
574 return Status::ERROR_DRM_CANNOT_HANDLE;
575 }
576
queryKeyStatus(const hidl_vec<uint8_t> & sessionId,queryKeyStatus_cb _hidl_cb)577 Return<void> DrmPlugin::queryKeyStatus(
578 const hidl_vec<uint8_t>& sessionId,
579 queryKeyStatus_cb _hidl_cb) {
580 if (sessionId.size() == 0) {
581 // Returns empty key status KeyValue pair
582 _hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>());
583 return Void();
584 }
585
586 std::vector<KeyValue> infoMapVec;
587 infoMapVec.clear();
588
589 mPlayPolicyLock.lock();
590 KeyValue keyValuePair;
591 for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
592 keyValuePair.key = mPlayPolicy[i].key;
593 keyValuePair.value = mPlayPolicy[i].value;
594 infoMapVec.push_back(keyValuePair);
595 }
596 mPlayPolicyLock.unlock();
597 _hidl_cb(Status::OK, toHidlVec(infoMapVec));
598 return Void();
599 }
600
getNumberOfSessions(getNumberOfSessions_cb _hidl_cb)601 Return<void> DrmPlugin::getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) {
602 uint32_t currentSessions = mSessionLibrary->numOpenSessions();
603 uint32_t maxSessions = 10;
604 _hidl_cb(Status::OK, currentSessions, maxSessions);
605 return Void();
606 }
607
getSecurityLevel(const hidl_vec<uint8_t> & sessionId,getSecurityLevel_cb _hidl_cb)608 Return<void> DrmPlugin::getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
609 getSecurityLevel_cb _hidl_cb) {
610 if (sessionId.size() == 0) {
611 _hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN);
612 return Void();
613 }
614
615 std::vector<uint8_t> sid = toVector(sessionId);
616 sp<Session> session = mSessionLibrary->findSession(sid);
617 if (!session.get()) {
618 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, SecurityLevel::UNKNOWN);
619 return Void();
620 }
621
622 Mutex::Autolock lock(mSecurityLevelLock);
623 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
624 mSecurityLevel.find(sid);
625 if (itr == mSecurityLevel.end()) {
626 ALOGE("Session id not found");
627 _hidl_cb(Status::ERROR_DRM_INVALID_STATE, SecurityLevel::UNKNOWN);
628 return Void();
629 }
630
631 _hidl_cb(Status::OK, itr->second);
632 return Void();
633 }
634
getLogMessages(getLogMessages_cb _hidl_cb)635 Return<void> DrmPlugin::getLogMessages(
636 getLogMessages_cb _hidl_cb) {
637 using std::chrono::duration_cast;
638 using std::chrono::milliseconds;
639 using std::chrono::system_clock;
640
641 auto timeMillis = duration_cast<milliseconds>(
642 system_clock::now().time_since_epoch()).count();
643
644 std::vector<LogMessage> logs = {
645 { timeMillis, LogPriority::ERROR, std::string("Not implemented") }};
646 _hidl_cb(drm::V1_4::Status::OK, toHidlVec(logs));
647 return Void();
648 }
649
requiresSecureDecoder(const hidl_string & mime,SecurityLevel level)650 Return<bool> DrmPlugin::requiresSecureDecoder(
651 const hidl_string& mime, SecurityLevel level) {
652 UNUSED(mime);
653 UNUSED(level);
654 return false;
655 }
656
requiresSecureDecoderDefault(const hidl_string & mime)657 Return<bool> DrmPlugin::requiresSecureDecoderDefault(const hidl_string& mime) {
658 UNUSED(mime);
659 // Clearkey only supports SW_SECURE_CRYPTO, so we always returns false
660 // regardless of mime type.
661 return false;
662 }
663
setPlaybackId(const hidl_vec<uint8_t> & sessionId,const hidl_string & playbackId)664 Return<Status> DrmPlugin::setPlaybackId(
665 const hidl_vec<uint8_t>& sessionId,
666 const hidl_string& playbackId) {
667 if (sessionId.size() == 0) {
668 ALOGE("Invalid empty session id");
669 return Status::BAD_VALUE;
670 }
671
672 std::vector<uint8_t> sid = toVector(sessionId);
673 mPlaybackId[sid] = playbackId;
674 return Status::OK;
675 }
676
setSecurityLevel(const hidl_vec<uint8_t> & sessionId,SecurityLevel level)677 Return<Status> DrmPlugin::setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
678 SecurityLevel level) {
679 if (sessionId.size() == 0) {
680 ALOGE("Invalid empty session id");
681 return Status::BAD_VALUE;
682 }
683
684 if (level > SecurityLevel::SW_SECURE_CRYPTO) {
685 ALOGE("Cannot set security level > max");
686 return Status::ERROR_DRM_CANNOT_HANDLE;
687 }
688
689 std::vector<uint8_t> sid = toVector(sessionId);
690 sp<Session> session = mSessionLibrary->findSession(sid);
691 if (!session.get()) {
692 return Status::ERROR_DRM_SESSION_NOT_OPENED;
693 }
694
695 Mutex::Autolock lock(mSecurityLevelLock);
696 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
697 mSecurityLevel.find(sid);
698 if (itr != mSecurityLevel.end()) {
699 mSecurityLevel[sid] = level;
700 } else {
701 if (!mSecurityLevel.insert(
702 std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level)).second) {
703 ALOGE("Failed to set security level");
704 return Status::ERROR_DRM_INVALID_STATE;
705 }
706 }
707 return Status::OK;
708 }
709
getMetrics(getMetrics_cb _hidl_cb)710 Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) {
711 // Set the open session count metric.
712 DrmMetricGroup::Attribute openSessionOkAttribute = {
713 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, ""
714 };
715 DrmMetricGroup::Value openSessionMetricValue = {
716 "count", DrmMetricGroup::ValueType::INT64_TYPE, mOpenSessionOkCount, 0.0, ""
717 };
718 DrmMetricGroup::Metric openSessionMetric = {
719 "open_session", { openSessionOkAttribute }, { openSessionMetricValue }
720 };
721
722 // Set the close session count metric.
723 DrmMetricGroup::Attribute closeSessionOkAttribute = {
724 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, ""
725 };
726 DrmMetricGroup::Value closeSessionMetricValue = {
727 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionOkCount, 0.0, ""
728 };
729 DrmMetricGroup::Metric closeSessionMetric = {
730 "close_session", { closeSessionOkAttribute }, { closeSessionMetricValue }
731 };
732
733 // Set the close session, not opened metric.
734 DrmMetricGroup::Attribute closeSessionNotOpenedAttribute = {
735 "status", DrmMetricGroup::ValueType::INT64_TYPE,
736 (int64_t) Status::ERROR_DRM_SESSION_NOT_OPENED, 0.0, ""
737 };
738 DrmMetricGroup::Value closeSessionNotOpenedMetricValue = {
739 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionNotOpenedCount, 0.0, ""
740 };
741 DrmMetricGroup::Metric closeSessionNotOpenedMetric = {
742 "close_session", { closeSessionNotOpenedAttribute }, { closeSessionNotOpenedMetricValue }
743 };
744
745 // Set the setPlaybackId metric.
746 std::vector<DrmMetricGroup::Attribute> sids;
747 std::vector<DrmMetricGroup::Value> playbackIds;
748 for (const auto&[key, value] : mPlaybackId) {
749 std::string sid(key.begin(), key.end());
750 DrmMetricGroup::Attribute sessionIdAttribute = {
751 "sid", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, sid };
752 sids.push_back(sessionIdAttribute);
753
754 DrmMetricGroup::Value playbackIdMetricValue = {
755 "playbackId", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, value };
756 playbackIds.push_back(playbackIdMetricValue);
757 }
758 DrmMetricGroup::Metric setPlaybackIdMetric = {
759 "set_playback_id", { sids }, { playbackIds }};
760
761 DrmMetricGroup metrics = {
762 { openSessionMetric, closeSessionMetric,
763 closeSessionNotOpenedMetric, setPlaybackIdMetric }};
764 _hidl_cb(Status::OK, hidl_vec<DrmMetricGroup>({metrics}));
765 return Void();
766 }
767
getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb)768 Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) {
769 std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
770 std::vector<KeySetId> keySetIds;
771 if (mMockError != Status_V1_2::OK) {
772 _hidl_cb(toStatus_1_0(mMockError), keySetIds);
773 return Void();
774 }
775 for (const auto& name : licenseNames) {
776 std::vector<uint8_t> keySetId(name.begin(), name.end());
777 keySetIds.push_back(keySetId);
778 }
779 _hidl_cb(Status::OK, keySetIds);
780 return Void();
781 }
782
783
removeOfflineLicense(const KeySetId & keySetId)784 Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
785 if (mMockError != Status_V1_2::OK) {
786 return toStatus_1_0(mMockError);
787 }
788 std::string licenseName(keySetId.begin(), keySetId.end());
789 if (mFileHandle.DeleteLicense(licenseName)) {
790 return Status::OK;
791 }
792 return Status::BAD_VALUE;
793 }
794
getOfflineLicenseState(const KeySetId & keySetId,getOfflineLicenseState_cb _hidl_cb)795 Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId,
796 getOfflineLicenseState_cb _hidl_cb) {
797 std::string licenseName(keySetId.begin(), keySetId.end());
798 DeviceFiles::LicenseState state;
799 std::string license;
800 OfflineLicenseState hLicenseState;
801 if (mMockError != Status_V1_2::OK) {
802 _hidl_cb(toStatus_1_0(mMockError), OfflineLicenseState::UNKNOWN);
803 } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
804 switch (state) {
805 case DeviceFiles::kLicenseStateActive:
806 hLicenseState = OfflineLicenseState::USABLE;
807 break;
808 case DeviceFiles::kLicenseStateReleasing:
809 hLicenseState = OfflineLicenseState::INACTIVE;
810 break;
811 case DeviceFiles::kLicenseStateUnknown:
812 hLicenseState = OfflineLicenseState::UNKNOWN;
813 break;
814 }
815 _hidl_cb(Status::OK, hLicenseState);
816 } else {
817 _hidl_cb(Status::BAD_VALUE, OfflineLicenseState::UNKNOWN);
818 }
819 return Void();
820 }
821
getSecureStops(getSecureStops_cb _hidl_cb)822 Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
823 mSecureStopLock.lock();
824 std::vector<SecureStop> stops;
825 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
826 ClearkeySecureStop clearkeyStop = itr->second;
827 std::vector<uint8_t> stopVec;
828 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
829 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
830
831 SecureStop stop;
832 stop.opaqueData = toHidlVec(stopVec);
833 stops.push_back(stop);
834 }
835 mSecureStopLock.unlock();
836
837 _hidl_cb(Status::OK, stops);
838 return Void();
839 }
840
getSecureStop(const hidl_vec<uint8_t> & secureStopId,getSecureStop_cb _hidl_cb)841 Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
842 getSecureStop_cb _hidl_cb) {
843 std::vector<uint8_t> stopVec;
844
845 mSecureStopLock.lock();
846 auto itr = mSecureStops.find(toVector(secureStopId));
847 if (itr != mSecureStops.end()) {
848 ClearkeySecureStop clearkeyStop = itr->second;
849 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
850 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
851 }
852 mSecureStopLock.unlock();
853
854 SecureStop stop;
855 if (!stopVec.empty()) {
856 stop.opaqueData = toHidlVec(stopVec);
857 _hidl_cb(Status::OK, stop);
858 } else {
859 _hidl_cb(Status::BAD_VALUE, stop);
860 }
861 return Void();
862 }
863
releaseSecureStop(const hidl_vec<uint8_t> & secureStopId)864 Return<Status> DrmPlugin::releaseSecureStop(const hidl_vec<uint8_t>& secureStopId) {
865 return removeSecureStop(secureStopId);
866 }
867
releaseAllSecureStops()868 Return<Status> DrmPlugin::releaseAllSecureStops() {
869 return removeAllSecureStops();
870 }
871
getSecureStopIds(getSecureStopIds_cb _hidl_cb)872 Return<void> DrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) {
873 mSecureStopLock.lock();
874 std::vector<SecureStopId> ids;
875 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
876 ids.push_back(itr->first);
877 }
878 mSecureStopLock.unlock();
879
880 _hidl_cb(Status::OK, toHidlVec(ids));
881 return Void();
882 }
883
releaseSecureStops(const SecureStopRelease & ssRelease)884 Return<Status> DrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) {
885 // OpaqueData starts with 4 byte decimal integer string
886 const size_t kFourBytesOffset = 4;
887 if (ssRelease.opaqueData.size() < kFourBytesOffset) {
888 ALOGE("Invalid secureStopRelease length");
889 return Status::BAD_VALUE;
890 }
891
892 Status status = Status::OK;
893 std::vector<uint8_t> input = toVector(ssRelease.opaqueData);
894
895 if (input.size() < kSecureStopIdSize + kFourBytesOffset) {
896 // The minimum size of SecureStopRelease has to contain
897 // a 4 bytes count and one secureStop id
898 ALOGE("Total size of secureStops is too short");
899 return Status::BAD_VALUE;
900 }
901
902 // The format of opaqueData is shared between the server
903 // and the drm service. The clearkey implementation consists of:
904 // count - number of secure stops
905 // list of fixed length secure stops
906 size_t countBufferSize = sizeof(uint32_t);
907 if (input.size() < countBufferSize) {
908 // SafetyNet logging
909 android_errorWriteLog(0x534e4554, "144766455");
910 return Status::BAD_VALUE;
911 }
912 uint32_t count = 0;
913 sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
914
915 // Avoid divide by 0 below.
916 if (count == 0) {
917 ALOGE("Invalid 0 secureStop count");
918 return Status::BAD_VALUE;
919 }
920
921 // Computes the fixed length secureStop size
922 size_t secureStopSize = (input.size() - kFourBytesOffset) / count;
923 if (secureStopSize < kSecureStopIdSize) {
924 // A valid secureStop contains the id plus data
925 ALOGE("Invalid secureStop size");
926 return Status::BAD_VALUE;
927 }
928 uint8_t* buffer = new uint8_t[secureStopSize];
929 size_t offset = kFourBytesOffset; // skip the count
930 for (size_t i = 0; i < count; ++i, offset += secureStopSize) {
931 memcpy(buffer, input.data() + offset, secureStopSize);
932
933 // A secureStop contains id+data, we only use the id for removal
934 std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize);
935 status = removeSecureStop(toHidlVec(id));
936 if (Status::OK != status) break;
937 }
938
939 delete[] buffer;
940 return status;
941 }
942
removeSecureStop(const hidl_vec<uint8_t> & secureStopId)943 Return<Status> DrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId) {
944 Mutex::Autolock lock(mSecureStopLock);
945
946 if (1 != mSecureStops.erase(toVector(secureStopId))) {
947 return Status::BAD_VALUE;
948 }
949 return Status::OK;
950 }
951
removeAllSecureStops()952 Return<Status> DrmPlugin::removeAllSecureStops() {
953 Mutex::Autolock lock(mSecureStopLock);
954
955 mSecureStops.clear();
956 mNextSecureStopId = kSecureStopIdStart;
957 return Status::OK;
958 }
959
960 } // namespace clearkey
961 } // namespace V1_4
962 } // namespace drm
963 } // namespace hardware
964 } // namespace android
965