• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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