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