• 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 = "";
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