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 = "";
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 Mutex::Autolock lock(mFileHandleLock);
225 if (!mFileHandle.StoreLicense(keySetIdString,
226 DeviceFiles::kLicenseStateReleasing,
227 emptyResponse)) {
228 ALOGE("Problem releasing offline license");
229 return Status_V1_2::ERROR_DRM_UNKNOWN;
230 }
231 if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
232 sp<Session> session = mSessionLibrary->createSession();
233 mReleaseKeysMap[keySetIdString] = session->sessionId();
234 } else {
235 ALOGI("key is in use, ignore release request");
236 }
237 } else {
238 ALOGE("Offline license not found, nothing to release");
239 }
240 *keyRequestType = KeyRequestType_V1_1::RELEASE;
241 }
242 return status;
243 }
244
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)245 Return<void> DrmPlugin::getKeyRequest(
246 const hidl_vec<uint8_t>& scope,
247 const hidl_vec<uint8_t>& initData,
248 const hidl_string& mimeType,
249 KeyType keyType,
250 const hidl_vec<KeyValue>& optionalParameters,
251 getKeyRequest_cb _hidl_cb) {
252 UNUSED(optionalParameters);
253
254 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
255 std::string defaultUrl("");
256 std::vector<uint8_t> request;
257 Status_V1_2 status = getKeyRequestCommon(
258 scope, initData, mimeType, keyType, optionalParameters,
259 &request, &keyRequestType, &defaultUrl);
260
261 _hidl_cb(toStatus_1_0(status), toHidlVec(request),
262 toKeyRequestType_V1_0(keyRequestType),
263 hidl_string(defaultUrl));
264 return Void();
265 }
266
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)267 Return<void> DrmPlugin::getKeyRequest_1_1(
268 const hidl_vec<uint8_t>& scope,
269 const hidl_vec<uint8_t>& initData,
270 const hidl_string& mimeType,
271 KeyType keyType,
272 const hidl_vec<KeyValue>& optionalParameters,
273 getKeyRequest_1_1_cb _hidl_cb) {
274 UNUSED(optionalParameters);
275
276 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
277 std::string defaultUrl("");
278 std::vector<uint8_t> request;
279 Status_V1_2 status = getKeyRequestCommon(
280 scope, initData, mimeType, keyType, optionalParameters,
281 &request, &keyRequestType, &defaultUrl);
282
283 _hidl_cb(toStatus_1_0(status), toHidlVec(request),
284 keyRequestType, hidl_string(defaultUrl));
285 return Void();
286 }
287
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)288 Return<void> DrmPlugin::getKeyRequest_1_2(
289 const hidl_vec<uint8_t>& scope,
290 const hidl_vec<uint8_t>& initData,
291 const hidl_string& mimeType,
292 KeyType keyType,
293 const hidl_vec<KeyValue>& optionalParameters,
294 getKeyRequest_1_2_cb _hidl_cb) {
295 UNUSED(optionalParameters);
296
297 KeyRequestType_V1_1 keyRequestType = KeyRequestType_V1_1::UNKNOWN;
298 std::string defaultUrl("");
299 std::vector<uint8_t> request;
300 Status_V1_2 status = getKeyRequestCommon(
301 scope, initData, mimeType, keyType, optionalParameters,
302 &request, &keyRequestType, &defaultUrl);
303
304 _hidl_cb(status, toHidlVec(request), keyRequestType, hidl_string(defaultUrl));
305 return Void();
306 }
307
setPlayPolicy()308 void DrmPlugin::setPlayPolicy() {
309 android::Mutex::Autolock lock(mPlayPolicyLock);
310 mPlayPolicy.clear();
311
312 KeyValue policy;
313 policy.key = kQueryKeyLicenseType;
314 policy.value = kStreaming;
315 mPlayPolicy.push_back(policy);
316
317 policy.key = kQueryKeyPlayAllowed;
318 policy.value = kTrue;
319 mPlayPolicy.push_back(policy);
320
321 policy.key = kQueryKeyRenewAllowed;
322 mPlayPolicy.push_back(policy);
323 }
324
makeKeySetId(std::string * keySetId)325 bool DrmPlugin::makeKeySetId(std::string* keySetId) {
326 if (!keySetId) {
327 ALOGE("keySetId destination not provided");
328 return false;
329 }
330 std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
331 ksid.resize(kKeySetIdLength);
332 std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
333
334 while (keySetId->empty()) {
335 for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
336 *itr = std::rand() % 0xff;
337 }
338 *keySetId = kKeySetIdPrefix + ByteArrayToHexString(
339 reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size());
340 Mutex::Autolock lock(mFileHandleLock);
341 if (mFileHandle.LicenseExists(*keySetId)) {
342 // collision, regenerate
343 ALOGV("Retry generating KeySetId");
344 keySetId->clear();
345 }
346 }
347 return true;
348 }
349
provideKeyResponse(const hidl_vec<uint8_t> & scope,const hidl_vec<uint8_t> & response,provideKeyResponse_cb _hidl_cb)350 Return<void> DrmPlugin::provideKeyResponse(
351 const hidl_vec<uint8_t>& scope,
352 const hidl_vec<uint8_t>& response,
353 provideKeyResponse_cb _hidl_cb) {
354 if (scope.size() == 0 || response.size() == 0) {
355 // Returns empty keySetId
356 _hidl_cb(Status::BAD_VALUE, hidl_vec<uint8_t>());
357 return Void();
358 }
359
360 std::string responseString(
361 reinterpret_cast<const char*>(response.data()), response.size());
362 const std::vector<uint8_t> scopeId = toVector(scope);
363 std::vector<uint8_t> sessionId;
364 std::string keySetId;
365
366 Status status = Status::OK;
367 bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
368 if (scopeId.size() < kKeySetIdPrefix.size()) {
369 android_errorWriteLog(0x534e4554, "144507096");
370 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, hidl_vec<uint8_t>());
371 return Void();
372 }
373 bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
374 if (isRelease) {
375 keySetId.assign(scopeId.begin(), scopeId.end());
376
377 auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
378 if (iter != mReleaseKeysMap.end()) {
379 sessionId.assign(iter->second.begin(), iter->second.end());
380 }
381 } else {
382 sessionId.assign(scopeId.begin(), scopeId.end());
383 // non offline license returns empty keySetId
384 keySetId.clear();
385 }
386
387 sp<Session> session = mSessionLibrary->findSession(sessionId);
388 if (!session.get()) {
389 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, hidl_vec<uint8_t>());
390 return Void();
391 }
392 setPlayPolicy();
393
394 status = session->provideKeyResponse(response);
395 if (status == Status::OK) {
396 if (isOfflineLicense) {
397 if (isRelease) {
398 Mutex::Autolock lock(mFileHandleLock);
399 mFileHandle.DeleteLicense(keySetId);
400 mSessionLibrary->destroySession(session);
401 } else {
402 if (!makeKeySetId(&keySetId)) {
403 _hidl_cb(Status::ERROR_DRM_UNKNOWN, hidl_vec<uint8_t>());
404 return Void();
405 }
406
407 Mutex::Autolock lock(mFileHandleLock);
408 bool ok = mFileHandle.StoreLicense(
409 keySetId,
410 DeviceFiles::kLicenseStateActive,
411 std::string(response.begin(), response.end()));
412 if (!ok) {
413 ALOGE("Failed to store offline license");
414 }
415 }
416 }
417
418 // Test calling AMediaDrm listeners.
419 sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
420
421 sendExpirationUpdate(sessionId, 100);
422
423 std::vector<KeyStatus_V1_2> keysStatus;
424 KeyStatus_V1_2 keyStatus;
425
426 std::vector<uint8_t> keyId1 = { 0xA, 0xB, 0xC };
427 keyStatus.keyId = keyId1;
428 keyStatus.type = V1_2::KeyStatusType::USABLE;
429 keysStatus.push_back(keyStatus);
430
431 std::vector<uint8_t> keyId2 = { 0xD, 0xE, 0xF };
432 keyStatus.keyId = keyId2;
433 keyStatus.type = V1_2::KeyStatusType::EXPIRED;
434 keysStatus.push_back(keyStatus);
435
436 std::vector<uint8_t> keyId3 = { 0x0, 0x1, 0x2 };
437 keyStatus.keyId = keyId3;
438 keyStatus.type = V1_2::KeyStatusType::USABLEINFUTURE;
439 keysStatus.push_back(keyStatus);
440
441 sendKeysChange_1_2(sessionId, keysStatus, true);
442
443 installSecureStop(sessionId);
444 } else {
445 ALOGE("provideKeyResponse returns error=%d", status);
446 }
447
448 std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
449 _hidl_cb(status, toHidlVec(keySetIdVec));
450 return Void();
451 }
452
restoreKeys(const hidl_vec<uint8_t> & sessionId,const hidl_vec<uint8_t> & keySetId)453 Return<Status> DrmPlugin::restoreKeys(
454 const hidl_vec<uint8_t>& sessionId, const hidl_vec<uint8_t>& keySetId) {
455 if (sessionId.size() == 0 || keySetId.size() == 0) {
456 return Status::BAD_VALUE;
457 }
458
459 DeviceFiles::LicenseState licenseState;
460 std::string offlineLicense;
461 Status status = Status::OK;
462 Mutex::Autolock lock(mFileHandleLock);
463 if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()),
464 &licenseState, &offlineLicense)) {
465 ALOGE("Failed to restore offline license");
466 return Status::ERROR_DRM_NO_LICENSE;
467 }
468
469 if (DeviceFiles::kLicenseStateUnknown == licenseState ||
470 DeviceFiles::kLicenseStateReleasing == licenseState) {
471 ALOGE("Invalid license state=%d", licenseState);
472 return Status::ERROR_DRM_NO_LICENSE;
473 }
474
475 sp<Session> session = mSessionLibrary->findSession(toVector(sessionId));
476 if (!session.get()) {
477 return Status::ERROR_DRM_SESSION_NOT_OPENED;
478 }
479 status = session->provideKeyResponse(std::vector<uint8_t>(offlineLicense.begin(),
480 offlineLicense.end()));
481 if (status != Status::OK) {
482 ALOGE("Failed to restore keys");
483 }
484 return status;
485 }
486
getPropertyString(const hidl_string & propertyName,getPropertyString_cb _hidl_cb)487 Return<void> DrmPlugin::getPropertyString(
488 const hidl_string& propertyName, getPropertyString_cb _hidl_cb) {
489 std::string name(propertyName.c_str());
490 std::string value;
491
492 if (name == kVendorKey) {
493 value = mStringProperties[kVendorKey];
494 } else if (name == kVersionKey) {
495 value = mStringProperties[kVersionKey];
496 } else if (name == kPluginDescriptionKey) {
497 value = mStringProperties[kPluginDescriptionKey];
498 } else if (name == kAlgorithmsKey) {
499 value = mStringProperties[kAlgorithmsKey];
500 } else if (name == kListenerTestSupportKey) {
501 value = mStringProperties[kListenerTestSupportKey];
502 } else if (name == kDrmErrorTestKey) {
503 value = mStringProperties[kDrmErrorTestKey];
504 } else {
505 ALOGE("App requested unknown string property %s", name.c_str());
506 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, "");
507 return Void();
508 }
509 _hidl_cb(Status::OK, value.c_str());
510 return Void();
511 }
512
getPropertyByteArray(const hidl_string & propertyName,getPropertyByteArray_cb _hidl_cb)513 Return<void> DrmPlugin::getPropertyByteArray(
514 const hidl_string& propertyName, getPropertyByteArray_cb _hidl_cb) {
515 std::map<std::string, std::vector<uint8_t> >::iterator itr =
516 mByteArrayProperties.find(std::string(propertyName.c_str()));
517 if (itr == mByteArrayProperties.end()) {
518 ALOGE("App requested unknown property: %s", propertyName.c_str());
519 _hidl_cb(Status::BAD_VALUE, std::vector<uint8_t>());
520 return Void();
521 }
522 _hidl_cb(Status::OK, itr->second);
523 return Void();
524
525 }
526
setPropertyString(const hidl_string & name,const hidl_string & value)527 Return<Status> DrmPlugin::setPropertyString(
528 const hidl_string& name, const hidl_string& value) {
529 std::string immutableKeys;
530 immutableKeys.append(kAlgorithmsKey + ",");
531 immutableKeys.append(kPluginDescriptionKey + ",");
532 immutableKeys.append(kVendorKey + ",");
533 immutableKeys.append(kVersionKey + ",");
534
535 std::string key = std::string(name.c_str());
536 if (immutableKeys.find(key) != std::string::npos) {
537 ALOGD("Cannot set immutable property: %s", key.c_str());
538 return Status::BAD_VALUE;
539 }
540
541 std::map<std::string, std::string>::iterator itr =
542 mStringProperties.find(key);
543 if (itr == mStringProperties.end()) {
544 ALOGE("Cannot set undefined property string, key=%s", key.c_str());
545 return Status::BAD_VALUE;
546 }
547
548 if (name == kDrmErrorTestKey) {
549 if (value == kResourceContentionValue) {
550 mMockError = Status_V1_2::ERROR_DRM_RESOURCE_CONTENTION;
551 } else if (value == kLostStateValue) {
552 mMockError = Status_V1_2::ERROR_DRM_SESSION_LOST_STATE;
553 } else if (value == kFrameTooLargeValue) {
554 mMockError = Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE;
555 } else if (value == kInvalidStateValue) {
556 mMockError = Status_V1_2::ERROR_DRM_INVALID_STATE;
557 } else {
558 mMockError = Status_V1_2::ERROR_DRM_UNKNOWN;
559 }
560 }
561
562 mStringProperties[key] = std::string(value.c_str());
563 return Status::OK;
564 }
565
setPropertyByteArray(const hidl_string & name,const hidl_vec<uint8_t> & value)566 Return<Status> DrmPlugin::setPropertyByteArray(
567 const hidl_string& name, const hidl_vec<uint8_t>& value) {
568 UNUSED(value);
569 if (name == kDeviceIdKey) {
570 ALOGD("Cannot set immutable property: %s", name.c_str());
571 return Status::BAD_VALUE;
572 } else if (name == kClientIdKey) {
573 mByteArrayProperties[kClientIdKey] = toVector(value);
574 return Status::OK;
575 }
576
577 // Setting of undefined properties is not supported
578 ALOGE("Failed to set property byte array, key=%s", name.c_str());
579 return Status::ERROR_DRM_CANNOT_HANDLE;
580 }
581
queryKeyStatus(const hidl_vec<uint8_t> & sessionId,queryKeyStatus_cb _hidl_cb)582 Return<void> DrmPlugin::queryKeyStatus(
583 const hidl_vec<uint8_t>& sessionId,
584 queryKeyStatus_cb _hidl_cb) {
585 if (sessionId.size() == 0) {
586 // Returns empty key status KeyValue pair
587 _hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>());
588 return Void();
589 }
590
591 std::vector<KeyValue> infoMapVec;
592 infoMapVec.clear();
593
594 mPlayPolicyLock.lock();
595 KeyValue keyValuePair;
596 for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
597 keyValuePair.key = mPlayPolicy[i].key;
598 keyValuePair.value = mPlayPolicy[i].value;
599 infoMapVec.push_back(keyValuePair);
600 }
601 mPlayPolicyLock.unlock();
602 _hidl_cb(Status::OK, toHidlVec(infoMapVec));
603 return Void();
604 }
605
getNumberOfSessions(getNumberOfSessions_cb _hidl_cb)606 Return<void> DrmPlugin::getNumberOfSessions(getNumberOfSessions_cb _hidl_cb) {
607 uint32_t currentSessions = mSessionLibrary->numOpenSessions();
608 uint32_t maxSessions = 10;
609 _hidl_cb(Status::OK, currentSessions, maxSessions);
610 return Void();
611 }
612
getSecurityLevel(const hidl_vec<uint8_t> & sessionId,getSecurityLevel_cb _hidl_cb)613 Return<void> DrmPlugin::getSecurityLevel(const hidl_vec<uint8_t>& sessionId,
614 getSecurityLevel_cb _hidl_cb) {
615 if (sessionId.size() == 0) {
616 _hidl_cb(Status::BAD_VALUE, SecurityLevel::UNKNOWN);
617 return Void();
618 }
619
620 std::vector<uint8_t> sid = toVector(sessionId);
621 sp<Session> session = mSessionLibrary->findSession(sid);
622 if (!session.get()) {
623 _hidl_cb(Status::ERROR_DRM_SESSION_NOT_OPENED, SecurityLevel::UNKNOWN);
624 return Void();
625 }
626
627 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
628 mSecurityLevel.find(sid);
629 if (itr == mSecurityLevel.end()) {
630 ALOGE("Session id not found");
631 _hidl_cb(Status::ERROR_DRM_INVALID_STATE, SecurityLevel::UNKNOWN);
632 return Void();
633 }
634
635 _hidl_cb(Status::OK, itr->second);
636 return Void();
637 }
638
getLogMessages(getLogMessages_cb _hidl_cb)639 Return<void> DrmPlugin::getLogMessages(
640 getLogMessages_cb _hidl_cb) {
641 using std::chrono::duration_cast;
642 using std::chrono::milliseconds;
643 using std::chrono::system_clock;
644
645 auto timeMillis = duration_cast<milliseconds>(
646 system_clock::now().time_since_epoch()).count();
647
648 std::vector<LogMessage> logs = {
649 { timeMillis, LogPriority::ERROR, std::string("Not implemented") }};
650 _hidl_cb(drm::V1_4::Status::OK, toHidlVec(logs));
651 return Void();
652 }
653
requiresSecureDecoder(const hidl_string & mime,SecurityLevel level)654 Return<bool> DrmPlugin::requiresSecureDecoder(
655 const hidl_string& mime, SecurityLevel level) {
656 UNUSED(mime);
657 UNUSED(level);
658 return false;
659 }
660
requiresSecureDecoderDefault(const hidl_string & mime)661 Return<bool> DrmPlugin::requiresSecureDecoderDefault(const hidl_string& mime) {
662 UNUSED(mime);
663 // Clearkey only supports SW_SECURE_CRYPTO, so we always returns false
664 // regardless of mime type.
665 return false;
666 }
667
setPlaybackId(const hidl_vec<uint8_t> & sessionId,const hidl_string & playbackId)668 Return<Status> DrmPlugin::setPlaybackId(
669 const hidl_vec<uint8_t>& sessionId,
670 const hidl_string& playbackId) {
671 if (sessionId.size() == 0) {
672 ALOGE("Invalid empty session id");
673 return Status::BAD_VALUE;
674 }
675
676 std::vector<uint8_t> sid = toVector(sessionId);
677 mPlaybackId[sid] = playbackId;
678 return Status::OK;
679 }
680
setSecurityLevel(const hidl_vec<uint8_t> & sessionId,SecurityLevel level)681 Return<Status> DrmPlugin::setSecurityLevel(const hidl_vec<uint8_t>& sessionId,
682 SecurityLevel level) {
683 if (sessionId.size() == 0) {
684 ALOGE("Invalid empty session id");
685 return Status::BAD_VALUE;
686 }
687
688 if (level > SecurityLevel::SW_SECURE_CRYPTO) {
689 ALOGE("Cannot set security level > max");
690 return Status::ERROR_DRM_CANNOT_HANDLE;
691 }
692
693 std::vector<uint8_t> sid = toVector(sessionId);
694 sp<Session> session = mSessionLibrary->findSession(sid);
695 if (!session.get()) {
696 return Status::ERROR_DRM_SESSION_NOT_OPENED;
697 }
698
699 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr =
700 mSecurityLevel.find(sid);
701 if (itr != mSecurityLevel.end()) {
702 mSecurityLevel[sid] = level;
703 } else {
704 if (!mSecurityLevel.insert(
705 std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level)).second) {
706 ALOGE("Failed to set security level");
707 return Status::ERROR_DRM_INVALID_STATE;
708 }
709 }
710 return Status::OK;
711 }
712
getMetrics(getMetrics_cb _hidl_cb)713 Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) {
714 // Set the open session count metric.
715 DrmMetricGroup::Attribute openSessionOkAttribute = {
716 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, ""
717 };
718 DrmMetricGroup::Value openSessionMetricValue = {
719 "count", DrmMetricGroup::ValueType::INT64_TYPE, mOpenSessionOkCount, 0.0, ""
720 };
721 DrmMetricGroup::Metric openSessionMetric = {
722 "open_session", { openSessionOkAttribute }, { openSessionMetricValue }
723 };
724
725 // Set the close session count metric.
726 DrmMetricGroup::Attribute closeSessionOkAttribute = {
727 "status", DrmMetricGroup::ValueType::INT64_TYPE, (int64_t) Status::OK, 0.0, ""
728 };
729 DrmMetricGroup::Value closeSessionMetricValue = {
730 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionOkCount, 0.0, ""
731 };
732 DrmMetricGroup::Metric closeSessionMetric = {
733 "close_session", { closeSessionOkAttribute }, { closeSessionMetricValue }
734 };
735
736 // Set the close session, not opened metric.
737 DrmMetricGroup::Attribute closeSessionNotOpenedAttribute = {
738 "status", DrmMetricGroup::ValueType::INT64_TYPE,
739 (int64_t) Status::ERROR_DRM_SESSION_NOT_OPENED, 0.0, ""
740 };
741 DrmMetricGroup::Value closeSessionNotOpenedMetricValue = {
742 "count", DrmMetricGroup::ValueType::INT64_TYPE, mCloseSessionNotOpenedCount, 0.0, ""
743 };
744 DrmMetricGroup::Metric closeSessionNotOpenedMetric = {
745 "close_session", { closeSessionNotOpenedAttribute }, { closeSessionNotOpenedMetricValue }
746 };
747
748 // Set the setPlaybackId metric.
749 std::vector<DrmMetricGroup::Attribute> sids;
750 std::vector<DrmMetricGroup::Value> playbackIds;
751 for (const auto&[key, value] : mPlaybackId) {
752 std::string sid(key.begin(), key.end());
753 DrmMetricGroup::Attribute sessionIdAttribute = {
754 "sid", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, sid };
755 sids.push_back(sessionIdAttribute);
756
757 DrmMetricGroup::Value playbackIdMetricValue = {
758 "playbackId", DrmMetricGroup::ValueType::STRING_TYPE, 0, 0, value };
759 playbackIds.push_back(playbackIdMetricValue);
760 }
761 DrmMetricGroup::Metric setPlaybackIdMetric = {
762 "set_playback_id", { sids }, { playbackIds }};
763
764 DrmMetricGroup metrics = {
765 { openSessionMetric, closeSessionMetric,
766 closeSessionNotOpenedMetric, setPlaybackIdMetric }};
767 _hidl_cb(Status::OK, hidl_vec<DrmMetricGroup>({metrics}));
768 return Void();
769 }
770
getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb)771 Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) {
772 Mutex::Autolock lock(mFileHandleLock);
773
774 std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
775 std::vector<KeySetId> keySetIds;
776 if (mMockError != Status_V1_2::OK) {
777 _hidl_cb(toStatus_1_0(mMockError), keySetIds);
778 return Void();
779 }
780 for (const auto& name : licenseNames) {
781 std::vector<uint8_t> keySetId(name.begin(), name.end());
782 keySetIds.push_back(keySetId);
783 }
784 _hidl_cb(Status::OK, keySetIds);
785 return Void();
786 }
787
788
removeOfflineLicense(const KeySetId & keySetId)789 Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) {
790 if (mMockError != Status_V1_2::OK) {
791 return toStatus_1_0(mMockError);
792 }
793 std::string licenseName(keySetId.begin(), keySetId.end());
794 Mutex::Autolock lock(mFileHandleLock);
795 if (mFileHandle.DeleteLicense(licenseName)) {
796 return Status::OK;
797 }
798 return Status::BAD_VALUE;
799 }
800
getOfflineLicenseState(const KeySetId & keySetId,getOfflineLicenseState_cb _hidl_cb)801 Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId,
802 getOfflineLicenseState_cb _hidl_cb) {
803 Mutex::Autolock lock(mFileHandleLock);
804
805 std::string licenseName(keySetId.begin(), keySetId.end());
806 DeviceFiles::LicenseState state;
807 std::string license;
808 OfflineLicenseState hLicenseState;
809 if (mMockError != Status_V1_2::OK) {
810 _hidl_cb(toStatus_1_0(mMockError), OfflineLicenseState::UNKNOWN);
811 } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
812 switch (state) {
813 case DeviceFiles::kLicenseStateActive:
814 hLicenseState = OfflineLicenseState::USABLE;
815 break;
816 case DeviceFiles::kLicenseStateReleasing:
817 hLicenseState = OfflineLicenseState::INACTIVE;
818 break;
819 case DeviceFiles::kLicenseStateUnknown:
820 hLicenseState = OfflineLicenseState::UNKNOWN;
821 break;
822 }
823 _hidl_cb(Status::OK, hLicenseState);
824 } else {
825 _hidl_cb(Status::BAD_VALUE, OfflineLicenseState::UNKNOWN);
826 }
827 return Void();
828 }
829
getSecureStops(getSecureStops_cb _hidl_cb)830 Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) {
831 mSecureStopLock.lock();
832 std::vector<SecureStop> stops;
833 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
834 ClearkeySecureStop clearkeyStop = itr->second;
835 std::vector<uint8_t> stopVec;
836 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
837 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
838
839 SecureStop stop;
840 stop.opaqueData = toHidlVec(stopVec);
841 stops.push_back(stop);
842 }
843 mSecureStopLock.unlock();
844
845 _hidl_cb(Status::OK, stops);
846 return Void();
847 }
848
getSecureStop(const hidl_vec<uint8_t> & secureStopId,getSecureStop_cb _hidl_cb)849 Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId,
850 getSecureStop_cb _hidl_cb) {
851 std::vector<uint8_t> stopVec;
852
853 mSecureStopLock.lock();
854 auto itr = mSecureStops.find(toVector(secureStopId));
855 if (itr != mSecureStops.end()) {
856 ClearkeySecureStop clearkeyStop = itr->second;
857 stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
858 stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
859 }
860 mSecureStopLock.unlock();
861
862 SecureStop stop;
863 if (!stopVec.empty()) {
864 stop.opaqueData = toHidlVec(stopVec);
865 _hidl_cb(Status::OK, stop);
866 } else {
867 _hidl_cb(Status::BAD_VALUE, stop);
868 }
869 return Void();
870 }
871
releaseSecureStop(const hidl_vec<uint8_t> & secureStopId)872 Return<Status> DrmPlugin::releaseSecureStop(const hidl_vec<uint8_t>& secureStopId) {
873 return removeSecureStop(secureStopId);
874 }
875
releaseAllSecureStops()876 Return<Status> DrmPlugin::releaseAllSecureStops() {
877 return removeAllSecureStops();
878 }
879
getSecureStopIds(getSecureStopIds_cb _hidl_cb)880 Return<void> DrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) {
881 mSecureStopLock.lock();
882 std::vector<SecureStopId> ids;
883 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
884 ids.push_back(itr->first);
885 }
886 mSecureStopLock.unlock();
887
888 _hidl_cb(Status::OK, toHidlVec(ids));
889 return Void();
890 }
891
releaseSecureStops(const SecureStopRelease & ssRelease)892 Return<Status> DrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) {
893 // OpaqueData starts with 4 byte decimal integer string
894 const size_t kFourBytesOffset = 4;
895 if (ssRelease.opaqueData.size() < kFourBytesOffset) {
896 ALOGE("Invalid secureStopRelease length");
897 return Status::BAD_VALUE;
898 }
899
900 Status status = Status::OK;
901 std::vector<uint8_t> input = toVector(ssRelease.opaqueData);
902
903 if (input.size() < kSecureStopIdSize + kFourBytesOffset) {
904 // The minimum size of SecureStopRelease has to contain
905 // a 4 bytes count and one secureStop id
906 ALOGE("Total size of secureStops is too short");
907 return Status::BAD_VALUE;
908 }
909
910 // The format of opaqueData is shared between the server
911 // and the drm service. The clearkey implementation consists of:
912 // count - number of secure stops
913 // list of fixed length secure stops
914 size_t countBufferSize = sizeof(uint32_t);
915 if (input.size() < countBufferSize) {
916 // SafetyNet logging
917 android_errorWriteLog(0x534e4554, "144766455");
918 return Status::BAD_VALUE;
919 }
920 uint32_t count = 0;
921 sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
922
923 // Avoid divide by 0 below.
924 if (count == 0) {
925 ALOGE("Invalid 0 secureStop count");
926 return Status::BAD_VALUE;
927 }
928
929 // Computes the fixed length secureStop size
930 size_t secureStopSize = (input.size() - kFourBytesOffset) / count;
931 if (secureStopSize < kSecureStopIdSize) {
932 // A valid secureStop contains the id plus data
933 ALOGE("Invalid secureStop size");
934 return Status::BAD_VALUE;
935 }
936 uint8_t* buffer = new uint8_t[secureStopSize];
937 size_t offset = kFourBytesOffset; // skip the count
938 for (size_t i = 0; i < count; ++i, offset += secureStopSize) {
939 memcpy(buffer, input.data() + offset, secureStopSize);
940
941 // A secureStop contains id+data, we only use the id for removal
942 std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize);
943 status = removeSecureStop(toHidlVec(id));
944 if (Status::OK != status) break;
945 }
946
947 delete[] buffer;
948 return status;
949 }
950
removeSecureStop(const hidl_vec<uint8_t> & secureStopId)951 Return<Status> DrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId) {
952 Mutex::Autolock lock(mSecureStopLock);
953
954 if (1 != mSecureStops.erase(toVector(secureStopId))) {
955 return Status::BAD_VALUE;
956 }
957 return Status::OK;
958 }
959
removeAllSecureStops()960 Return<Status> DrmPlugin::removeAllSecureStops() {
961 Mutex::Autolock lock(mSecureStopLock);
962
963 mSecureStops.clear();
964 mNextSecureStopId = kSecureStopIdStart;
965 return Status::OK;
966 }
967
968 } // namespace clearkey
969 } // namespace V1_4
970 } // namespace drm
971 } // namespace hardware
972 } // namespace android
973