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