1 /*
2 * Copyright (C) 2021 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 #define LOG_TAG "clearkey-DrmPlugin"
17
18 #include <aidl/android/hardware/drm/DrmMetric.h>
19 #include <android-base/parseint.h>
20 #include <utils/Log.h>
21
22 #include <inttypes.h>
23 #include <stdio.h>
24 #include <chrono>
25 #include <set>
26
27 #include "AidlUtils.h"
28 #include "ClearKeyDrmProperties.h"
29 #include "DrmPlugin.h"
30 #include "Session.h"
31 #include "Utils.h"
32 #include "AidlClearKeryProperties.h"
33
34 namespace {
35 const std::string kKeySetIdPrefix("ckid");
36 const int kKeySetIdLength = 16;
37 const int kSecureStopIdStart = 100;
38 const std::string kOfflineLicense("\"type\":\"persistent-license\"");
39 const std::string kStreaming("Streaming");
40 const std::string kTrue("True");
41
42 const std::string kQueryKeyLicenseType("LicenseType");
43 // Value: "Streaming" or "Offline"
44 const std::string kQueryKeyPlayAllowed("PlayAllowed");
45 // Value: "True" or "False"
46 const std::string kQueryKeyRenewAllowed("RenewAllowed");
47 // Value: "True" or "False"
48
49 const int kSecureStopIdSize = 10;
50
uint32ToVector(uint32_t value)51 std::vector<uint8_t> uint32ToVector(uint32_t value) {
52 // 10 bytes to display max value 4294967295 + one byte null terminator
53 char buffer[kSecureStopIdSize];
54 memset(buffer, 0, kSecureStopIdSize);
55 snprintf(buffer, kSecureStopIdSize, "%" PRIu32, value);
56 return std::vector<uint8_t>(buffer, buffer + sizeof(buffer));
57 }
58
59 }; // unnamed namespace
60
61 namespace aidl {
62 namespace android {
63 namespace hardware {
64 namespace drm {
65 namespace clearkey {
66
67 using ::android::Mutex;
68
DrmPlugin(SessionLibrary * sessionLibrary)69 DrmPlugin::DrmPlugin(SessionLibrary* sessionLibrary)
70 : mSessionLibrary(sessionLibrary),
71 mOpenSessionOkCount(0),
72 mCloseSessionOkCount(0),
73 mCloseSessionNotOpenedCount(0),
74 mNextSecureStopId(kSecureStopIdStart),
75 mMockError(Status::OK) {
76 mPlayPolicy.clear();
77 initProperties();
78 mSecureStops.clear();
79 mReleaseKeysMap.clear();
80 std::srand(std::time(nullptr));
81 }
82
initProperties()83 void DrmPlugin::initProperties() {
84 mStringProperties.clear();
85 mStringProperties[kVendorKey] = kAidlVendorValue;
86 mStringProperties[kVersionKey] = kVersionValue;
87 mStringProperties[kPluginDescriptionKey] = kAidlPluginDescriptionValue;
88 mStringProperties[kAlgorithmsKey] = kAidlAlgorithmsValue;
89 mStringProperties[kListenerTestSupportKey] = kAidlListenerTestSupportValue;
90 mStringProperties[kDrmErrorTestKey] = kAidlDrmErrorTestValue;
91 mStringProperties[kAidlVersionKey] = kAidlVersionValue;
92 mStringProperties[kOemErrorKey] = "0";
93 mStringProperties[kErrorContextKey] = "0";
94
95 std::vector<uint8_t> valueVector;
96 valueVector.clear();
97 valueVector.insert(valueVector.end(), kTestDeviceIdData,
98 kTestDeviceIdData + sizeof(kTestDeviceIdData) / sizeof(uint8_t));
99 mByteArrayProperties[kDeviceIdKey] = valueVector;
100
101 valueVector.clear();
102 valueVector.insert(valueVector.end(), kMetricsData,
103 kMetricsData + sizeof(kMetricsData) / sizeof(uint8_t));
104 mByteArrayProperties[kMetricsKey] = valueVector;
105 }
106
getIntProperty(const std::string & prop,int32_t defaultVal) const107 int32_t DrmPlugin::getIntProperty(const std::string& prop, int32_t defaultVal) const {
108 if (!mStringProperties.count(prop)) {
109 return defaultVal;
110 }
111 int32_t out = defaultVal;
112 if (!::android::base::ParseInt(mStringProperties.at(prop), &out)) {
113 return defaultVal;
114 }
115 return out;
116 }
117
getOemError() const118 int32_t DrmPlugin::getOemError() const {
119 return getIntProperty(kOemErrorKey);
120 }
121
getErrorContext() const122 int32_t DrmPlugin::getErrorContext() const {
123 return getIntProperty(kErrorContextKey);
124 }
125
126 //
127 // The secure stop in ClearKey implementation is not installed securely.
128 // This function merely creates a test environment for testing secure stops APIs.
129 // The content in this secure stop is implementation dependent, the clearkey
130 // secureStop does not serve as a reference implementation.
installSecureStop(const std::vector<uint8_t> & sessionId)131 void DrmPlugin::installSecureStop(const std::vector<uint8_t>& sessionId) {
132 ::android::Mutex::Autolock lock(mSecureStopLock);
133
134 ClearkeySecureStop clearkeySecureStop;
135 clearkeySecureStop.id = uint32ToVector(++mNextSecureStopId);
136 clearkeySecureStop.data.assign(sessionId.begin(), sessionId.end());
137
138 mSecureStops.insert(std::pair<std::vector<uint8_t>, ClearkeySecureStop>(clearkeySecureStop.id,
139 clearkeySecureStop));
140 }
141
closeSession(const std::vector<uint8_t> & in_sessionId)142 ::ndk::ScopedAStatus DrmPlugin::closeSession(const std::vector<uint8_t>& in_sessionId) {
143 if (in_sessionId.size() == 0) {
144 return toNdkScopedAStatus(Status::BAD_VALUE);
145 }
146
147 ::android::sp<Session> session = mSessionLibrary->findSession(in_sessionId);
148 if (session.get()) {
149 mSessionLibrary->destroySession(session);
150 if (session->getMockError() != clearkeydrm::OK) {
151 sendSessionLostState(in_sessionId);
152 return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE,
153 nullptr,
154 getOemError(),
155 getErrorContext());
156 }
157 mCloseSessionOkCount++;
158 return toNdkScopedAStatus(Status::OK);
159 }
160 mCloseSessionNotOpenedCount++;
161 return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
162 }
163
decrypt(const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_keyId,const std::vector<uint8_t> & in_input,const std::vector<uint8_t> & in_iv,std::vector<uint8_t> * _aidl_return)164 ::ndk::ScopedAStatus DrmPlugin::decrypt(const std::vector<uint8_t>& in_sessionId,
165 const std::vector<uint8_t>& in_keyId,
166 const std::vector<uint8_t>& in_input,
167 const std::vector<uint8_t>& in_iv,
168 std::vector<uint8_t>* _aidl_return) {
169 *_aidl_return = {};
170 if (in_sessionId.size() == 0 || in_keyId.size() == 0 || in_input.size() == 0 ||
171 in_iv.size() == 0) {
172 return toNdkScopedAStatus(Status::BAD_VALUE);
173 }
174 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
175 }
176
encrypt(const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_keyId,const std::vector<uint8_t> & in_input,const std::vector<uint8_t> & in_iv,std::vector<uint8_t> * _aidl_return)177 ::ndk::ScopedAStatus DrmPlugin::encrypt(const std::vector<uint8_t>& in_sessionId,
178 const std::vector<uint8_t>& in_keyId,
179 const std::vector<uint8_t>& in_input,
180 const std::vector<uint8_t>& in_iv,
181 std::vector<uint8_t>* _aidl_return) {
182 *_aidl_return = {};
183 if (in_sessionId.size() == 0 || in_keyId.size() == 0 || in_input.size() == 0 ||
184 in_iv.size() == 0) {
185 return toNdkScopedAStatus(Status::BAD_VALUE);
186 }
187 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
188 }
189
getHdcpLevels(::aidl::android::hardware::drm::HdcpLevels * _aidl_return)190 ::ndk::ScopedAStatus DrmPlugin::getHdcpLevels(
191 ::aidl::android::hardware::drm::HdcpLevels* _aidl_return) {
192 _aidl_return->connectedLevel = HdcpLevel::HDCP_NONE;
193 _aidl_return->maxLevel = HdcpLevel::HDCP_NO_OUTPUT;
194 return toNdkScopedAStatus(Status::OK);
195 }
196
getKeyRequest(const std::vector<uint8_t> & in_scope,const std::vector<uint8_t> & in_initData,const std::string & in_mimeType,::aidl::android::hardware::drm::KeyType in_keyType,const std::vector<::aidl::android::hardware::drm::KeyValue> & in_optionalParameters,::aidl::android::hardware::drm::KeyRequest * _aidl_return)197 ::ndk::ScopedAStatus DrmPlugin::getKeyRequest(
198 const std::vector<uint8_t>& in_scope, const std::vector<uint8_t>& in_initData,
199 const std::string& in_mimeType, ::aidl::android::hardware::drm::KeyType in_keyType,
200 const std::vector<::aidl::android::hardware::drm::KeyValue>& in_optionalParameters,
201 ::aidl::android::hardware::drm::KeyRequest* _aidl_return) {
202 UNUSED(in_optionalParameters);
203
204 KeyRequestType keyRequestType = KeyRequestType::UNKNOWN;
205 std::string defaultUrl("");
206
207 _aidl_return->request = {};
208 _aidl_return->requestType = keyRequestType;
209 _aidl_return->defaultUrl = defaultUrl;
210
211 if (in_scope.size() == 0 ||
212 (in_keyType != KeyType::STREAMING && in_keyType != KeyType::OFFLINE &&
213 in_keyType != KeyType::RELEASE)) {
214 return toNdkScopedAStatus(Status::BAD_VALUE);
215 }
216
217 const std::vector<uint8_t> scopeId = in_scope;
218 ::android::sp<Session> session;
219 std::set<KeyType> init_types{KeyType::STREAMING, KeyType::OFFLINE};
220 if (init_types.count(in_keyType)) {
221 std::vector<uint8_t> sessionId(scopeId.begin(), scopeId.end());
222 session = mSessionLibrary->findSession(sessionId);
223 if (!session.get()) {
224 return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
225 } else if (session->getMockError() != clearkeydrm::OK) {
226 auto err = static_cast<Status>(session->getMockError());
227 return toNdkScopedAStatus(err, nullptr, getOemError(), getErrorContext());
228 }
229 keyRequestType = KeyRequestType::INITIAL;
230 }
231
232 std::vector<uint8_t> request = {};
233 auto keyType = static_cast<CdmKeyType>(in_keyType);
234 auto status = session->getKeyRequest(in_initData, in_mimeType, keyType, &request);
235
236 if (in_keyType == KeyType::RELEASE) {
237 std::vector<uint8_t> keySetId(scopeId.begin(), scopeId.end());
238 std::string requestString(request.begin(), request.end());
239 if (requestString.find(kOfflineLicense) != std::string::npos) {
240 std::string emptyResponse;
241 std::string keySetIdString(keySetId.begin(), keySetId.end());
242 if (!mFileHandle.StoreLicense(keySetIdString, DeviceFiles::kLicenseStateReleasing,
243 emptyResponse)) {
244 ALOGE("Problem releasing offline license");
245 return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
246 }
247 if (mReleaseKeysMap.find(keySetIdString) == mReleaseKeysMap.end()) {
248 ::android::sp<Session> session = mSessionLibrary->createSession();
249 mReleaseKeysMap[keySetIdString] = session->sessionId();
250 } else {
251 ALOGI("key is in use, ignore release request");
252 }
253 } else {
254 ALOGE("Offline license not found, nothing to release");
255 }
256 keyRequestType = KeyRequestType::RELEASE;
257 }
258 _aidl_return->request = request;
259 _aidl_return->requestType = keyRequestType;
260 _aidl_return->defaultUrl = defaultUrl;
261 return toNdkScopedAStatus(status);
262 }
263
getLogMessages(std::vector<::aidl::android::hardware::drm::LogMessage> * _aidl_return)264 ::ndk::ScopedAStatus DrmPlugin::getLogMessages(
265 std::vector<::aidl::android::hardware::drm::LogMessage>* _aidl_return) {
266 using std::chrono::duration_cast;
267 using std::chrono::milliseconds;
268 using std::chrono::system_clock;
269
270 auto timeMillis = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
271
272 std::vector<::aidl::android::hardware::drm::LogMessage> logs = {
273 {timeMillis, ::aidl::android::hardware::drm::LogPriority::ERROR,
274 std::string("Not implemented")}};
275 *_aidl_return = logs;
276 return toNdkScopedAStatus(Status::OK);
277 }
278
getMetrics(std::vector<::aidl::android::hardware::drm::DrmMetricGroup> * _aidl_return)279 ::ndk::ScopedAStatus DrmPlugin::getMetrics(
280 std::vector<::aidl::android::hardware::drm::DrmMetricGroup>* _aidl_return) {
281 // Set the open session count metric.
282 DrmMetricNamedValue openSessionOkAttribute = {"status", static_cast<int64_t>(Status::OK)};
283 DrmMetricNamedValue openSessionMetricValue = {"count", mOpenSessionOkCount};
284 DrmMetric openSessionMetric = {
285 "open_session", {openSessionOkAttribute}, {openSessionMetricValue}};
286
287 // Set the close session count metric.
288 DrmMetricNamedValue closeSessionOkAttribute = {"status", static_cast<int64_t>(Status::OK)};
289 DrmMetricNamedValue closeSessionMetricValue = {"count", mCloseSessionOkCount};
290 DrmMetric closeSessionMetric = {
291 "close_session", {closeSessionOkAttribute}, {closeSessionMetricValue}};
292
293 // Set the close session, not opened metric.
294 DrmMetricNamedValue closeSessionNotOpenedAttribute = {"status",
295 static_cast<int64_t>(Status::ERROR_DRM_SESSION_NOT_OPENED)};
296 DrmMetricNamedValue closeSessionNotOpenedMetricValue = {"count", mCloseSessionNotOpenedCount};
297 DrmMetric closeSessionNotOpenedMetric = {
298 "close_session", {closeSessionNotOpenedAttribute}, {closeSessionNotOpenedMetricValue}};
299
300 // Set the setPlaybackId metric.
301 std::vector<DrmMetricNamedValue> sids = {};
302 std::vector<DrmMetricNamedValue> playbackIds = {};
303 for (const auto& [key, value] : mPlaybackId) {
304 std::string sid(key.begin(), key.end());
305 DrmMetricNamedValue sessionIdAttribute = {"sid", sid};
306 sids.push_back(sessionIdAttribute);
307
308 DrmMetricNamedValue playbackIdMetricValue = {"playbackId", value};
309 playbackIds.push_back(playbackIdMetricValue);
310 }
311 DrmMetric setPlaybackIdMetric = {"set_playback_id", sids, playbackIds};
312
313 DrmMetricGroup metrics = {{openSessionMetric, closeSessionMetric, closeSessionNotOpenedMetric,
314 setPlaybackIdMetric}};
315
316 *_aidl_return = {metrics};
317 return toNdkScopedAStatus(Status::OK);
318 }
319
getNumberOfSessions(::aidl::android::hardware::drm::NumberOfSessions * _aidl_return)320 ::ndk::ScopedAStatus DrmPlugin::getNumberOfSessions(
321 ::aidl::android::hardware::drm::NumberOfSessions* _aidl_return) {
322 _aidl_return->currentSessions = mSessionLibrary->numOpenSessions();
323 _aidl_return->maxSessions = 10;
324 return toNdkScopedAStatus(Status::OK);
325 }
326
getOfflineLicenseKeySetIds(std::vector<::aidl::android::hardware::drm::KeySetId> * _aidl_return)327 ::ndk::ScopedAStatus DrmPlugin::getOfflineLicenseKeySetIds(
328 std::vector<::aidl::android::hardware::drm::KeySetId>* _aidl_return) {
329 std::vector<std::string> licenseNames = mFileHandle.ListLicenses();
330 std::vector<KeySetId> keySetIds = {};
331 if (mMockError != Status::OK) {
332 *_aidl_return = keySetIds;
333 return toNdkScopedAStatus(toMockStatus(mMockError));
334 }
335 for (const auto& name : licenseNames) {
336 std::vector<uint8_t> keySetId(name.begin(), name.end());
337 KeySetId id = {};
338 id.keySetId = keySetId;
339 keySetIds.push_back(id);
340 }
341 *_aidl_return = keySetIds;
342 return toNdkScopedAStatus(Status::OK);
343 }
344
getOfflineLicenseState(const::aidl::android::hardware::drm::KeySetId & in_keySetId,::aidl::android::hardware::drm::OfflineLicenseState * _aidl_return)345 ::ndk::ScopedAStatus DrmPlugin::getOfflineLicenseState(
346 const ::aidl::android::hardware::drm::KeySetId& in_keySetId,
347 ::aidl::android::hardware::drm::OfflineLicenseState* _aidl_return) {
348 std::string licenseName(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end());
349 DeviceFiles::LicenseState state;
350 std::string license;
351 OfflineLicenseState licenseState = OfflineLicenseState::UNKNOWN;
352 Status status = Status::OK;
353 if (mMockError != Status::OK) {
354 *_aidl_return = licenseState;
355 return toNdkScopedAStatus(toMockStatus(mMockError));
356 } else if (mFileHandle.RetrieveLicense(licenseName, &state, &license)) {
357 switch (state) {
358 case DeviceFiles::kLicenseStateActive:
359 licenseState = OfflineLicenseState::USABLE;
360 break;
361 case DeviceFiles::kLicenseStateReleasing:
362 licenseState = OfflineLicenseState::INACTIVE;
363 break;
364 case DeviceFiles::kLicenseStateUnknown:
365 licenseState = OfflineLicenseState::UNKNOWN;
366 break;
367 }
368 } else {
369 status = Status::BAD_VALUE;
370 }
371 *_aidl_return = licenseState;
372 return toNdkScopedAStatus(status);
373 }
374
getPropertyByteArray(const std::string & in_propertyName,std::vector<uint8_t> * _aidl_return)375 ::ndk::ScopedAStatus DrmPlugin::getPropertyByteArray(const std::string& in_propertyName,
376 std::vector<uint8_t>* _aidl_return) {
377 std::map<std::string, std::vector<uint8_t>>::iterator itr =
378 mByteArrayProperties.find(std::string(in_propertyName.c_str()));
379 Status status = Status::OK;
380 if (itr != mByteArrayProperties.end()) {
381 *_aidl_return = itr->second;
382 } else {
383 ALOGE("App requested unknown property: %s", in_propertyName.c_str());
384 status = Status::BAD_VALUE;
385 *_aidl_return = {};
386 }
387 return toNdkScopedAStatus(status);
388 }
389
getPropertyString(const std::string & in_propertyName,std::string * _aidl_return)390 ::ndk::ScopedAStatus DrmPlugin::getPropertyString(const std::string& in_propertyName,
391 std::string* _aidl_return) {
392 std::string name(in_propertyName.c_str());
393 std::string value;
394 Status status = Status::OK;
395
396 if (name == kVendorKey) {
397 value = mStringProperties[kVendorKey];
398 } else if (name == kVersionKey) {
399 value = mStringProperties[kVersionKey];
400 } else if (name == kPluginDescriptionKey) {
401 value = mStringProperties[kPluginDescriptionKey];
402 } else if (name == kAlgorithmsKey) {
403 value = mStringProperties[kAlgorithmsKey];
404 } else if (name == kListenerTestSupportKey) {
405 value = mStringProperties[kListenerTestSupportKey];
406 } else if (name == kDrmErrorTestKey) {
407 value = mStringProperties[kDrmErrorTestKey];
408 } else if (name == kAidlVersionKey) {
409 value = mStringProperties[kAidlVersionKey];
410 } else if (name == kOemErrorKey) {
411 value = mStringProperties[kOemErrorKey];
412 } else if (name == kErrorContextKey) {
413 value = mStringProperties[kErrorContextKey];
414 } else {
415 ALOGE("App requested unknown string property %s", name.c_str());
416 status = Status::ERROR_DRM_CANNOT_HANDLE;
417 }
418 *_aidl_return = value;
419 return toNdkScopedAStatus(status);
420 }
421
getProvisionRequest(const std::string & in_certificateType,const std::string & in_certificateAuthority,::aidl::android::hardware::drm::ProvisionRequest * _aidl_return)422 ::ndk::ScopedAStatus DrmPlugin::getProvisionRequest(
423 const std::string& in_certificateType, const std::string& in_certificateAuthority,
424 ::aidl::android::hardware::drm::ProvisionRequest* _aidl_return) {
425 UNUSED(in_certificateType);
426 UNUSED(in_certificateAuthority);
427 _aidl_return->request = {};
428 _aidl_return->defaultUrl = {};
429 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
430 }
431
getSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId,::aidl::android::hardware::drm::SecureStop * _aidl_return)432 ::ndk::ScopedAStatus DrmPlugin::getSecureStop(
433 const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId,
434 ::aidl::android::hardware::drm::SecureStop* _aidl_return) {
435 std::vector<uint8_t> stop = {};
436
437 mSecureStopLock.lock();
438 auto itr = mSecureStops.find(in_secureStopId.secureStopId);
439 if (itr != mSecureStops.end()) {
440 ClearkeySecureStop clearkeyStop = itr->second;
441 stop.insert(stop.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
442 stop.insert(stop.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
443 }
444 mSecureStopLock.unlock();
445
446 SecureStop secureStop = {};
447 Status status = Status::OK;
448 if (!stop.empty()) {
449 secureStop.opaqueData = stop;
450 } else {
451 status = Status::BAD_VALUE;
452 }
453 *_aidl_return = secureStop;
454 return toNdkScopedAStatus(status);
455 }
456
getSecureStopIds(std::vector<::aidl::android::hardware::drm::SecureStopId> * _aidl_return)457 ::ndk::ScopedAStatus DrmPlugin::getSecureStopIds(
458 std::vector<::aidl::android::hardware::drm::SecureStopId>* _aidl_return) {
459 mSecureStopLock.lock();
460 std::vector<::aidl::android::hardware::drm::SecureStopId> ids;
461 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
462 SecureStopId id;
463 id.secureStopId = itr->first;
464 ids.push_back(id);
465 }
466 mSecureStopLock.unlock();
467
468 *_aidl_return = ids;
469 return toNdkScopedAStatus(Status::OK);
470 }
471
getSecureStops(std::vector<::aidl::android::hardware::drm::SecureStop> * _aidl_return)472 ::ndk::ScopedAStatus DrmPlugin::getSecureStops(
473 std::vector<::aidl::android::hardware::drm::SecureStop>* _aidl_return) {
474 mSecureStopLock.lock();
475 std::vector<::aidl::android::hardware::drm::SecureStop> stops;
476 for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) {
477 ClearkeySecureStop clearkeyStop = itr->second;
478 std::vector<uint8_t> stop{};
479 stop.insert(stop.end(), clearkeyStop.id.begin(), clearkeyStop.id.end());
480 stop.insert(stop.end(), clearkeyStop.data.begin(), clearkeyStop.data.end());
481
482 SecureStop secureStop;
483 secureStop.opaqueData = stop;
484 stops.push_back(secureStop);
485 }
486 mSecureStopLock.unlock();
487
488 *_aidl_return = stops;
489 return toNdkScopedAStatus(Status::OK);
490 }
491
getSecurityLevel(const std::vector<uint8_t> & in_sessionId,::aidl::android::hardware::drm::SecurityLevel * _aidl_return)492 ::ndk::ScopedAStatus DrmPlugin::getSecurityLevel(
493 const std::vector<uint8_t>& in_sessionId,
494 ::aidl::android::hardware::drm::SecurityLevel* _aidl_return) {
495 if (in_sessionId.size() == 0) {
496 *_aidl_return = ::aidl::android::hardware::drm::SecurityLevel::UNKNOWN;
497 return toNdkScopedAStatus(Status::BAD_VALUE);
498 }
499
500 std::vector<uint8_t> sid = in_sessionId;
501 ::android::sp<Session> session = mSessionLibrary->findSession(sid);
502 if (!session.get()) {
503 *_aidl_return = SecurityLevel::UNKNOWN;
504 return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
505 }
506
507 Mutex::Autolock lock(mSecurityLevelLock);
508 std::map<std::vector<uint8_t>, ::aidl::android::hardware::drm::SecurityLevel>::iterator itr =
509 mSecurityLevel.find(sid);
510 if (itr == mSecurityLevel.end()) {
511 ALOGE("Session id not found");
512 *_aidl_return = SecurityLevel::UNKNOWN;
513 return toNdkScopedAStatus(Status::ERROR_DRM_INVALID_STATE);
514 }
515
516 *_aidl_return = SecurityLevel::SW_SECURE_CRYPTO;
517 return toNdkScopedAStatus(Status::OK);
518 }
519
openSession(::aidl::android::hardware::drm::SecurityLevel in_securityLevel,std::vector<uint8_t> * _aidl_return)520 ::ndk::ScopedAStatus DrmPlugin::openSession(
521 ::aidl::android::hardware::drm::SecurityLevel in_securityLevel,
522 std::vector<uint8_t>* _aidl_return) {
523 ::android::sp<Session> session = mSessionLibrary->createSession();
524 processMockError(session);
525 std::vector<uint8_t> sessionId = session->sessionId();
526
527 Status status = setSecurityLevel(sessionId, in_securityLevel);
528 if (status == Status::OK) {
529 mOpenSessionOkCount++;
530 } else {
531 mSessionLibrary->destroySession(session);
532 sessionId.clear();
533 }
534 *_aidl_return = sessionId;
535 return toNdkScopedAStatus(status);
536 }
537
provideKeyResponse(const std::vector<uint8_t> & in_scope,const std::vector<uint8_t> & in_response,::aidl::android::hardware::drm::KeySetId * _aidl_return)538 ::ndk::ScopedAStatus DrmPlugin::provideKeyResponse(
539 const std::vector<uint8_t>& in_scope, const std::vector<uint8_t>& in_response,
540 ::aidl::android::hardware::drm::KeySetId* _aidl_return) {
541 if (in_scope.size() == 0 || in_response.size() == 0) {
542 // Returns empty keySetId
543 *_aidl_return = {};
544 return toNdkScopedAStatus(Status::BAD_VALUE);
545 }
546
547 std::string responseString(reinterpret_cast<const char*>(in_response.data()),
548 in_response.size());
549 const std::vector<uint8_t> scopeId = in_scope;
550 std::vector<uint8_t> sessionId = {};
551 std::string keySetId;
552
553 bool isOfflineLicense = responseString.find(kOfflineLicense) != std::string::npos;
554 if (scopeId.size() < kKeySetIdPrefix.size()) {
555 android_errorWriteLog(0x534e4554, "144507096");
556 *_aidl_return = {};
557 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
558 }
559 bool isRelease = (memcmp(scopeId.data(), kKeySetIdPrefix.data(), kKeySetIdPrefix.size()) == 0);
560 if (isRelease) {
561 keySetId.assign(scopeId.begin(), scopeId.end());
562
563 auto iter = mReleaseKeysMap.find(std::string(keySetId.begin(), keySetId.end()));
564 if (iter != mReleaseKeysMap.end()) {
565 sessionId.assign(iter->second.begin(), iter->second.end());
566 }
567 } else {
568 sessionId.assign(scopeId.begin(), scopeId.end());
569 // non offline license returns empty keySetId
570 keySetId.clear();
571 }
572
573 ::android::sp<Session> session = mSessionLibrary->findSession(sessionId);
574 if (!session.get()) {
575 *_aidl_return = {};
576 return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
577 }
578 setPlayPolicy();
579
580 auto res = session->provideKeyResponse(in_response);
581 if (res == clearkeydrm::OK) {
582 if (isOfflineLicense) {
583 if (isRelease) {
584 mFileHandle.DeleteLicense(keySetId);
585 mSessionLibrary->destroySession(session);
586 } else {
587 if (!makeKeySetId(&keySetId)) {
588 *_aidl_return = {};
589 return toNdkScopedAStatus(Status::ERROR_DRM_UNKNOWN);
590 }
591
592 bool ok = mFileHandle.StoreLicense(
593 keySetId, DeviceFiles::kLicenseStateActive,
594 std::string(in_response.begin(), in_response.end()));
595 if (!ok) {
596 ALOGE("Failed to store offline license");
597 }
598 }
599 }
600
601 // Test calling AMediaDrm listeners.
602 sendEvent(EventType::VENDOR_DEFINED, sessionId, sessionId);
603
604 sendExpirationUpdate(sessionId, 100);
605
606 std::vector<KeyStatus> keysStatus = {};
607 KeyStatus keyStatus;
608
609 std::vector<uint8_t> keyId1 = {0xA, 0xB, 0xC};
610 keyStatus.keyId = keyId1;
611 keyStatus.type = KeyStatusType::USABLE;
612 keysStatus.push_back(keyStatus);
613
614 std::vector<uint8_t> keyId2 = {0xD, 0xE, 0xF};
615 keyStatus.keyId = keyId2;
616 keyStatus.type = KeyStatusType::EXPIRED;
617 keysStatus.push_back(keyStatus);
618
619 std::vector<uint8_t> keyId3 = {0x0, 0x1, 0x2};
620 keyStatus.keyId = keyId3;
621 keyStatus.type = KeyStatusType::USABLE_IN_FUTURE;
622 keysStatus.push_back(keyStatus);
623
624 sendKeysChange(sessionId, keysStatus, true);
625
626 installSecureStop(sessionId);
627 } else {
628 ALOGE("provideKeyResponse returns error=%d", res);
629 }
630
631 std::vector<uint8_t> keySetIdVec(keySetId.begin(), keySetId.end());
632 _aidl_return->keySetId = keySetIdVec;
633 return toNdkScopedAStatus(res);
634 }
635
provideProvisionResponse(const std::vector<uint8_t> & in_response,::aidl::android::hardware::drm::ProvideProvisionResponseResult * _aidl_return)636 ::ndk::ScopedAStatus DrmPlugin::provideProvisionResponse(
637 const std::vector<uint8_t>& in_response,
638 ::aidl::android::hardware::drm::ProvideProvisionResponseResult* _aidl_return) {
639 Status status = Status::ERROR_DRM_CANNOT_HANDLE;
640 _aidl_return->certificate = {};
641 _aidl_return->wrappedKey = {};
642 if (in_response.size() == 0) {
643 status = Status::BAD_VALUE;
644 }
645 return toNdkScopedAStatus(status);
646 }
647
queryKeyStatus(const std::vector<uint8_t> & in_sessionId,std::vector<::aidl::android::hardware::drm::KeyValue> * _aidl_return)648 ::ndk::ScopedAStatus DrmPlugin::queryKeyStatus(
649 const std::vector<uint8_t>& in_sessionId,
650 std::vector<::aidl::android::hardware::drm::KeyValue>* _aidl_return) {
651 if (in_sessionId.size() == 0) {
652 // Returns empty key status KeyValue pair
653 *_aidl_return = {};
654 return toNdkScopedAStatus(Status::BAD_VALUE);
655 }
656
657 std::vector<KeyValue> infoMap = {};
658 mPlayPolicyLock.lock();
659 KeyValue keyValuePair;
660 for (size_t i = 0; i < mPlayPolicy.size(); ++i) {
661 keyValuePair.key = mPlayPolicy[i].key;
662 keyValuePair.value = mPlayPolicy[i].value;
663 infoMap.push_back(keyValuePair);
664 }
665 mPlayPolicyLock.unlock();
666 *_aidl_return = infoMap;
667 return toNdkScopedAStatus(Status::OK);
668 }
669
releaseAllSecureStops()670 ::ndk::ScopedAStatus DrmPlugin::releaseAllSecureStops() {
671 Status status = Status::OK;
672 const auto res = removeAllSecureStops();
673 if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
674 status = static_cast<Status>(res.getServiceSpecificError());
675 }
676 return toNdkScopedAStatus(status);
677 }
678
releaseSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId)679 ::ndk::ScopedAStatus DrmPlugin::releaseSecureStop(
680 const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId) {
681 Status status = Status::OK;
682 const auto res = removeSecureStop(in_secureStopId);
683 if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
684 status = static_cast<Status>(res.getServiceSpecificError());
685 }
686 return toNdkScopedAStatus(status);
687 }
688
releaseSecureStops(const::aidl::android::hardware::drm::OpaqueData & in_ssRelease)689 ::ndk::ScopedAStatus DrmPlugin::releaseSecureStops(
690 const ::aidl::android::hardware::drm::OpaqueData& in_ssRelease) {
691 // OpaqueData starts with 4 byte decimal integer string
692 const size_t kFourBytesOffset = 4;
693 if (in_ssRelease.opaqueData.size() < kFourBytesOffset) {
694 ALOGE("Invalid secureStopRelease length");
695 return toNdkScopedAStatus(Status::BAD_VALUE);
696 }
697
698 Status status = Status::OK;
699 std::vector<uint8_t> input = in_ssRelease.opaqueData;
700
701 if (input.size() < kSecureStopIdSize + kFourBytesOffset) {
702 // The minimum size of secure stop has to contain
703 // a 4 bytes count and one secureStop id
704 ALOGE("Total size of secureStops is too short");
705 return toNdkScopedAStatus(Status::BAD_VALUE);
706 }
707
708 // The format of opaqueData is shared between the server
709 // and the drm service. The clearkey implementation consists of:
710 // count - number of secure stops
711 // list of fixed length secure stops
712 size_t countBufferSize = sizeof(uint32_t);
713 if (input.size() < countBufferSize) {
714 // SafetyNet logging
715 android_errorWriteLog(0x534e4554, "144766455");
716 return toNdkScopedAStatus(Status::BAD_VALUE);
717 }
718 uint32_t count = 0;
719 sscanf(reinterpret_cast<char*>(input.data()), "%04" PRIu32, &count);
720
721 // Avoid divide by 0 below.
722 if (count == 0) {
723 ALOGE("Invalid 0 secureStop count");
724 return toNdkScopedAStatus(Status::BAD_VALUE);
725 }
726
727 // Computes the fixed length secureStop size
728 size_t secureStopSize = (input.size() - kFourBytesOffset) / count;
729 if (secureStopSize < kSecureStopIdSize) {
730 // A valid secureStop contains the id plus data
731 ALOGE("Invalid secureStop size");
732 return toNdkScopedAStatus(Status::BAD_VALUE);
733 }
734 uint8_t* buffer = new uint8_t[secureStopSize];
735 size_t offset = kFourBytesOffset; // skip the count
736 for (size_t i = 0; i < count; ++i, offset += secureStopSize) {
737 memcpy(buffer, input.data() + offset, secureStopSize);
738
739 // A secureStop contains id+data, we only use the id for removal
740 std::vector<uint8_t> id(buffer, buffer + kSecureStopIdSize);
741 ::aidl::android::hardware::drm::SecureStopId secureStopId{id};
742 const auto res = removeSecureStop(secureStopId);
743 if (!res.isOk() && res.getExceptionCode() == EX_SERVICE_SPECIFIC) {
744 status = static_cast<Status>(res.getServiceSpecificError());
745 }
746 if (Status::OK != status) break;
747 }
748
749 delete[] buffer;
750 return toNdkScopedAStatus(status);
751 }
752
removeAllSecureStops()753 ::ndk::ScopedAStatus DrmPlugin::removeAllSecureStops() {
754 Mutex::Autolock lock(mSecureStopLock);
755
756 mSecureStops.clear();
757 mNextSecureStopId = kSecureStopIdStart;
758 return toNdkScopedAStatus(Status::OK);
759 }
760
removeKeys(const std::vector<uint8_t> & in_sessionId)761 ::ndk::ScopedAStatus DrmPlugin::removeKeys(const std::vector<uint8_t>& in_sessionId) {
762 Status status = Status::ERROR_DRM_CANNOT_HANDLE;
763 if (in_sessionId.size() == 0) {
764 status = Status::BAD_VALUE;
765 }
766 return toNdkScopedAStatus(status);
767 }
768
removeOfflineLicense(const::aidl::android::hardware::drm::KeySetId & in_keySetId)769 ::ndk::ScopedAStatus DrmPlugin::removeOfflineLicense(
770 const ::aidl::android::hardware::drm::KeySetId& in_keySetId) {
771 if (mMockError != Status::OK) {
772 return toNdkScopedAStatus(toMockStatus(mMockError));
773 }
774 Status status = Status::BAD_VALUE;
775 std::string licenseName(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end());
776 if (mFileHandle.DeleteLicense(licenseName)) {
777 status = Status::OK;
778 }
779 return toNdkScopedAStatus(status);
780 }
781
removeSecureStop(const::aidl::android::hardware::drm::SecureStopId & in_secureStopId)782 ::ndk::ScopedAStatus DrmPlugin::removeSecureStop(
783 const ::aidl::android::hardware::drm::SecureStopId& in_secureStopId) {
784 Mutex::Autolock lock(mSecureStopLock);
785
786 Status status = Status::OK;
787 if (1 != mSecureStops.erase(in_secureStopId.secureStopId)) {
788 status = Status::BAD_VALUE;
789 }
790 return toNdkScopedAStatus(status);
791 }
792
requiresSecureDecoder(const std::string & in_mime,::aidl::android::hardware::drm::SecurityLevel in_level,bool * _aidl_return)793 ::ndk::ScopedAStatus DrmPlugin::requiresSecureDecoder(
794 const std::string& in_mime, ::aidl::android::hardware::drm::SecurityLevel in_level,
795 bool* _aidl_return) {
796 UNUSED(in_mime);
797 UNUSED(in_level);
798 *_aidl_return = false;
799 return ::ndk::ScopedAStatus::ok();
800 }
801
restoreKeys(const std::vector<uint8_t> & in_sessionId,const::aidl::android::hardware::drm::KeySetId & in_keySetId)802 ::ndk::ScopedAStatus DrmPlugin::restoreKeys(
803 const std::vector<uint8_t>& in_sessionId,
804 const ::aidl::android::hardware::drm::KeySetId& in_keySetId) {
805 if (in_sessionId.size() == 0 || in_keySetId.keySetId.size() == 0) {
806 return toNdkScopedAStatus(Status::BAD_VALUE);
807 }
808
809 DeviceFiles::LicenseState licenseState;
810 std::string offlineLicense;
811 if (!mFileHandle.RetrieveLicense(
812 std::string(in_keySetId.keySetId.begin(), in_keySetId.keySetId.end()),
813 &licenseState, &offlineLicense)) {
814 ALOGE("Failed to restore offline license");
815 return toNdkScopedAStatus(Status::ERROR_DRM_NO_LICENSE);
816 }
817
818 if (DeviceFiles::kLicenseStateUnknown == licenseState ||
819 DeviceFiles::kLicenseStateReleasing == licenseState) {
820 ALOGE("Invalid license state=%d", licenseState);
821 return toNdkScopedAStatus(Status::ERROR_DRM_NO_LICENSE);
822 }
823
824 ::android::sp<Session> session = mSessionLibrary->findSession(in_sessionId);
825 if (!session.get()) {
826 return toNdkScopedAStatus(Status::ERROR_DRM_SESSION_NOT_OPENED);
827 }
828 auto res = session->provideKeyResponse(
829 std::vector<uint8_t>(offlineLicense.begin(), offlineLicense.end()));
830 if (res != clearkeydrm::OK) {
831 ALOGE("Failed to restore keys");
832 }
833 return toNdkScopedAStatus(res);
834 }
835
sendEvent(::aidl::android::hardware::drm::EventType in_eventType,const std::vector<uint8_t> & in_sessionId,const std::vector<uint8_t> & in_data)836 void DrmPlugin::sendEvent(::aidl::android::hardware::drm::EventType in_eventType,
837 const std::vector<uint8_t>& in_sessionId,
838 const std::vector<uint8_t>& in_data) {
839 if (mListener != nullptr) {
840 mListener->onEvent(in_eventType, in_sessionId, in_data);
841 } else {
842 ALOGE("Null event listener, event not sent");
843 }
844 return;
845 }
846
sendExpirationUpdate(const std::vector<uint8_t> & in_sessionId,int64_t in_expiryTimeInMS)847 void DrmPlugin::sendExpirationUpdate(const std::vector<uint8_t>& in_sessionId,
848 int64_t in_expiryTimeInMS) {
849 if (mListener != nullptr) {
850 mListener->onExpirationUpdate(in_sessionId, in_expiryTimeInMS);
851 } else {
852 ALOGE("Null event listener, event not sent");
853 }
854 return;
855 }
856
sendKeysChange(const std::vector<uint8_t> & in_sessionId,const std::vector<::aidl::android::hardware::drm::KeyStatus> & in_keyStatusList,bool in_hasNewUsableKey)857 void DrmPlugin::sendKeysChange(
858 const std::vector<uint8_t>& in_sessionId,
859 const std::vector<::aidl::android::hardware::drm::KeyStatus>& in_keyStatusList,
860 bool in_hasNewUsableKey) {
861 if (mListener != nullptr) {
862 mListener->onKeysChange(in_sessionId, in_keyStatusList, in_hasNewUsableKey);
863 } else {
864 ALOGE("Null event listener, event not sent");
865 }
866 return;
867 }
868
sendSessionLostState(const std::vector<uint8_t> & in_sessionId)869 void DrmPlugin::sendSessionLostState(const std::vector<uint8_t>& in_sessionId) {
870 if (mListener != nullptr) {
871 mListener->onSessionLostState(in_sessionId);
872 }
873 return;
874 }
875
setCipherAlgorithm(const std::vector<uint8_t> &,const std::string &)876 ::ndk::ScopedAStatus DrmPlugin::setCipherAlgorithm(const std::vector<uint8_t>& /*in_sessionId*/,
877 const std::string& /*in_algorithm*/) {
878 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
879 }
880
setListener(const std::shared_ptr<::aidl::android::hardware::drm::IDrmPluginListener> & in_listener)881 ::ndk::ScopedAStatus DrmPlugin::setListener(
882 const std::shared_ptr<
883 ::aidl::android::hardware::drm::IDrmPluginListener>& in_listener) {
884 mListener = in_listener;
885 return toNdkScopedAStatus(Status::OK);
886 }
887
setMacAlgorithm(const std::vector<uint8_t> &,const std::string &)888 ::ndk::ScopedAStatus DrmPlugin::setMacAlgorithm(const std::vector<uint8_t>& /*in_sessionId*/,
889 const std::string& /*in_algorithm*/) {
890 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
891 }
892
setPlaybackId(const std::vector<uint8_t> & in_sessionId,const std::string & in_playbackId)893 ::ndk::ScopedAStatus DrmPlugin::setPlaybackId(const std::vector<uint8_t>& in_sessionId,
894 const std::string& in_playbackId) {
895 if (in_sessionId.size() == 0) {
896 ALOGE("Invalid empty session id");
897 return toNdkScopedAStatus(Status::BAD_VALUE);
898 }
899
900 std::vector<uint8_t> sid = in_sessionId;
901 mPlaybackId[sid] = in_playbackId;
902 return toNdkScopedAStatus(Status::OK);
903 }
904
setPropertyByteArray(const std::string & in_propertyName,const std::vector<uint8_t> & in_value)905 ::ndk::ScopedAStatus DrmPlugin::setPropertyByteArray(const std::string& in_propertyName,
906 const std::vector<uint8_t>& in_value) {
907 if (in_propertyName == kDeviceIdKey) {
908 ALOGD("Cannot set immutable property: %s", in_propertyName.c_str());
909 return toNdkScopedAStatus(Status::BAD_VALUE);
910 } else if (in_propertyName == kClientIdKey) {
911 mByteArrayProperties[kClientIdKey] = in_value;
912 return toNdkScopedAStatus(Status::OK);
913 }
914
915 // Setting of undefined properties is not supported
916 ALOGE("Failed to set property byte array, key=%s", in_propertyName.c_str());
917 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
918 }
919
setPropertyString(const std::string & in_propertyName,const std::string & in_value)920 ::ndk::ScopedAStatus DrmPlugin::setPropertyString(const std::string& in_propertyName,
921 const std::string& in_value) {
922 std::string immutableKeys;
923 immutableKeys.append(kAlgorithmsKey + ",");
924 immutableKeys.append(kPluginDescriptionKey + ",");
925 immutableKeys.append(kVendorKey + ",");
926 immutableKeys.append(kVersionKey + ",");
927
928 std::string key = std::string(in_propertyName.c_str());
929 if (immutableKeys.find(key) != std::string::npos) {
930 ALOGD("Cannot set immutable property: %s", key.c_str());
931 return toNdkScopedAStatus(Status::BAD_VALUE);
932 }
933
934 std::map<std::string, std::string>::iterator itr = mStringProperties.find(key);
935 if (itr == mStringProperties.end()) {
936 ALOGE("Cannot set undefined property string, key=%s", key.c_str());
937 return toNdkScopedAStatus(Status::BAD_VALUE);
938 }
939
940 if (in_propertyName == kDrmErrorTestKey) {
941 if (in_value == kResourceContentionValue) {
942 mMockError = Status::ERROR_DRM_RESOURCE_CONTENTION;
943 } else if (in_value == kLostStateValue) {
944 mMockError = Status::ERROR_DRM_SESSION_LOST_STATE;
945 } else if (in_value == kFrameTooLargeValue) {
946 mMockError = Status::ERROR_DRM_FRAME_TOO_LARGE;
947 } else if (in_value == kInvalidStateValue) {
948 mMockError = Status::ERROR_DRM_INVALID_STATE;
949 } else {
950 mMockError = Status::ERROR_DRM_UNKNOWN;
951 }
952 }
953
954 if (in_propertyName == kOemErrorKey || in_propertyName == kErrorContextKey) {
955 int32_t err = 0;
956 if (!::android::base::ParseInt(in_value, &err)) {
957 return toNdkScopedAStatus(Status::BAD_VALUE);
958 }
959 }
960
961 mStringProperties[key] = std::string(in_value.c_str());
962 return toNdkScopedAStatus(Status::OK);
963 }
964
sign(const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,std::vector<uint8_t> * _aidl_return)965 ::ndk::ScopedAStatus DrmPlugin::sign(const std::vector<uint8_t>& /*in_sessionId*/,
966 const std::vector<uint8_t>& /*in_keyId*/,
967 const std::vector<uint8_t>& /*in_message*/,
968 std::vector<uint8_t>* _aidl_return) {
969 *_aidl_return = {};
970 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
971 }
972
signRSA(const std::vector<uint8_t> &,const std::string &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,std::vector<uint8_t> * _aidl_return)973 ::ndk::ScopedAStatus DrmPlugin::signRSA(const std::vector<uint8_t>& /*in_sessionId*/,
974 const std::string& /*in_algorithm*/,
975 const std::vector<uint8_t>& /*in_message*/,
976 const std::vector<uint8_t>& /*in_wrappedkey*/,
977 std::vector<uint8_t>* _aidl_return) {
978 *_aidl_return = {};
979 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
980 }
981
verify(const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,const std::vector<uint8_t> &,bool * _aidl_return)982 ::ndk::ScopedAStatus DrmPlugin::verify(const std::vector<uint8_t>& /*in_sessionId*/,
983 const std::vector<uint8_t>& /*in_keyId*/,
984 const std::vector<uint8_t>& /*in_message*/,
985 const std::vector<uint8_t>& /*in_signature*/,
986 bool* _aidl_return) {
987 *_aidl_return = false;
988 return toNdkScopedAStatus(Status::ERROR_DRM_CANNOT_HANDLE);
989 }
990
991 // Private methods below.
setPlayPolicy()992 void DrmPlugin::setPlayPolicy() {
993 ::android::Mutex::Autolock lock(mPlayPolicyLock);
994 mPlayPolicy.clear();
995
996 KeyValue policy;
997 policy.key = kQueryKeyLicenseType;
998 policy.value = kStreaming;
999 mPlayPolicy.push_back(policy);
1000
1001 policy.key = kQueryKeyPlayAllowed;
1002 policy.value = kTrue;
1003 mPlayPolicy.push_back(policy);
1004
1005 policy.key = kQueryKeyRenewAllowed;
1006 mPlayPolicy.push_back(policy);
1007 }
1008
makeKeySetId(std::string * keySetId)1009 bool DrmPlugin::makeKeySetId(std::string* keySetId) {
1010 if (!keySetId) {
1011 ALOGE("keySetId destination not provided");
1012 return false;
1013 }
1014 std::vector<uint8_t> ksid(kKeySetIdPrefix.begin(), kKeySetIdPrefix.end());
1015 ksid.resize(kKeySetIdLength);
1016 std::vector<uint8_t> randomData((kKeySetIdLength - kKeySetIdPrefix.size()) / 2, 0);
1017
1018 while (keySetId->empty()) {
1019 for (auto itr = randomData.begin(); itr != randomData.end(); ++itr) {
1020 *itr = std::rand() % 0xff;
1021 }
1022 auto id = reinterpret_cast<const uint8_t*>(randomData.data());
1023 *keySetId = kKeySetIdPrefix + ::android::ByteArrayToHexString(id, randomData.size());
1024 if (mFileHandle.LicenseExists(*keySetId)) {
1025 // collision, regenerate
1026 ALOGV("Retry generating KeySetId");
1027 keySetId->clear();
1028 }
1029 }
1030 return true;
1031 }
1032
setSecurityLevel(const std::vector<uint8_t> & sessionId,SecurityLevel level)1033 Status DrmPlugin::setSecurityLevel(const std::vector<uint8_t>& sessionId, SecurityLevel level) {
1034 if (sessionId.size() == 0) {
1035 ALOGE("Invalid empty session id");
1036 return Status::BAD_VALUE;
1037 }
1038
1039 if (level != SecurityLevel::DEFAULT && level != SecurityLevel::SW_SECURE_CRYPTO) {
1040 ALOGE("Cannot set security level > max");
1041 return Status::ERROR_DRM_CANNOT_HANDLE;
1042 }
1043
1044 std::vector<uint8_t> sid = sessionId;
1045 ::android::sp<Session> session = mSessionLibrary->findSession(sid);
1046 if (!session.get()) {
1047 return Status::ERROR_DRM_SESSION_NOT_OPENED;
1048 }
1049
1050 Mutex::Autolock lock(mSecurityLevelLock);
1051 std::map<std::vector<uint8_t>, SecurityLevel>::iterator itr = mSecurityLevel.find(sid);
1052 if (itr != mSecurityLevel.end()) {
1053 mSecurityLevel[sid] = level;
1054 } else {
1055 if (!mSecurityLevel.insert(std::pair<std::vector<uint8_t>, SecurityLevel>(sid, level))
1056 .second) {
1057 ALOGE("Failed to set security level");
1058 return Status::ERROR_DRM_INVALID_STATE;
1059 }
1060 }
1061 return Status::OK;
1062 }
1063
1064 } // namespace clearkey
1065 } // namespace drm
1066 } // namespace hardware
1067 } // namespace android
1068 } // namespace aidl
1069