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