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