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