blob: d4f6fab3d273bc70a3e70335392e15a7dab90a6e [file] [log] [blame]
Jeff Tinkercc82dc62013-02-08 10:18:35 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "Drm"
19#include <utils/Log.h>
20
21#include <dirent.h>
22#include <dlfcn.h>
23
24#include "Drm.h"
25
Ronghua Wu5c3da202015-02-22 08:45:28 -080026#include "DrmSessionClientInterface.h"
27#include "DrmSessionManager.h"
Jeff Tinkercc82dc62013-02-08 10:18:35 -080028#include <media/drm/DrmAPI.h>
29#include <media/stagefright/foundation/ADebug.h>
30#include <media/stagefright/foundation/AString.h>
31#include <media/stagefright/foundation/hexdump.h>
32#include <media/stagefright/MediaErrors.h>
Jeff Tinker81e0bd42014-04-02 16:41:38 -070033#include <binder/IServiceManager.h>
34#include <binder/IPCThreadState.h>
Jeff Tinkercc82dc62013-02-08 10:18:35 -080035
36namespace android {
37
Ronghua Wu5c3da202015-02-22 08:45:28 -080038static inline int getCallingPid() {
39 return IPCThreadState::self()->getCallingPid();
40}
41
Jeff Tinker81e0bd42014-04-02 16:41:38 -070042static bool checkPermission(const char* permissionString) {
43#ifndef HAVE_ANDROID_OS
44 return true;
45#endif
46 if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
47 bool ok = checkCallingPermission(String16(permissionString));
48 if (!ok) ALOGE("Request requires %s", permissionString);
49 return ok;
50}
51
Jeff Tinkercc82dc62013-02-08 10:18:35 -080052KeyedVector<Vector<uint8_t>, String8> Drm::mUUIDToLibraryPathMap;
53KeyedVector<String8, wp<SharedLibrary> > Drm::mLibraryPathToOpenLibraryMap;
54Mutex Drm::mMapLock;
55
56static bool operator<(const Vector<uint8_t> &lhs, const Vector<uint8_t> &rhs) {
57 if (lhs.size() < rhs.size()) {
58 return true;
59 } else if (lhs.size() > rhs.size()) {
60 return false;
61 }
62
63 return memcmp((void *)lhs.array(), (void *)rhs.array(), rhs.size()) < 0;
64}
65
Ronghua Wu5c3da202015-02-22 08:45:28 -080066struct DrmSessionClient : public DrmSessionClientInterface {
67 DrmSessionClient(Drm* drm) : mDrm(drm) {}
68
69 virtual bool reclaimSession(const Vector<uint8_t>& sessionId) {
70 sp<Drm> drm = mDrm.promote();
71 if (drm == NULL) {
72 return true;
73 }
74 status_t err = drm->closeSession(sessionId);
75 if (err != OK) {
76 return false;
77 }
78 drm->sendEvent(DrmPlugin::kDrmPluginEventSessionReclaimed, 0, &sessionId, NULL);
79 return true;
80 }
81
82protected:
83 virtual ~DrmSessionClient() {}
84
85private:
86 wp<Drm> mDrm;
87
88 DISALLOW_EVIL_CONSTRUCTORS(DrmSessionClient);
89};
90
Jeff Tinkercc82dc62013-02-08 10:18:35 -080091Drm::Drm()
92 : mInitCheck(NO_INIT),
Ronghua Wu5c3da202015-02-22 08:45:28 -080093 mDrmSessionClient(new DrmSessionClient(this)),
Jeff Tinker0cb126a2013-04-02 13:08:05 -070094 mListener(NULL),
Jeff Tinkercc82dc62013-02-08 10:18:35 -080095 mFactory(NULL),
96 mPlugin(NULL) {
97}
98
99Drm::~Drm() {
Ronghua Wu5c3da202015-02-22 08:45:28 -0800100 DrmSessionManager::Instance()->removeDrm(mDrmSessionClient);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800101 delete mPlugin;
102 mPlugin = NULL;
103 closeFactory();
104}
105
106void Drm::closeFactory() {
107 delete mFactory;
108 mFactory = NULL;
109 mLibrary.clear();
110}
111
112status_t Drm::initCheck() const {
113 return mInitCheck;
114}
115
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700116status_t Drm::setListener(const sp<IDrmClient>& listener)
117{
118 Mutex::Autolock lock(mEventLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700119 if (mListener != NULL){
Marco Nelissenf8880202014-11-14 07:58:25 -0800120 IInterface::asBinder(mListener)->unlinkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700121 }
122 if (listener != NULL) {
Marco Nelissenf8880202014-11-14 07:58:25 -0800123 IInterface::asBinder(listener)->linkToDeath(this);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700124 }
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700125 mListener = listener;
126 return NO_ERROR;
127}
128
129void Drm::sendEvent(DrmPlugin::EventType eventType, int extra,
130 Vector<uint8_t> const *sessionId,
131 Vector<uint8_t> const *data)
132{
133 mEventLock.lock();
134 sp<IDrmClient> listener = mListener;
135 mEventLock.unlock();
136
137 if (listener != NULL) {
138 Parcel obj;
139 if (sessionId && sessionId->size()) {
140 obj.writeInt32(sessionId->size());
141 obj.write(sessionId->array(), sessionId->size());
142 } else {
143 obj.writeInt32(0);
144 }
145
146 if (data && data->size()) {
147 obj.writeInt32(data->size());
148 obj.write(data->array(), data->size());
149 } else {
150 obj.writeInt32(0);
151 }
152
153 Mutex::Autolock lock(mNotifyLock);
154 listener->notify(eventType, extra, &obj);
155 }
156}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800157
158/*
159 * Search the plugins directory for a plugin that supports the scheme
160 * specified by uuid
161 *
162 * If found:
163 * mLibrary holds a strong pointer to the dlopen'd library
164 * mFactory is set to the library's factory method
165 * mInitCheck is set to OK
166 *
167 * If not found:
168 * mLibrary is cleared and mFactory are set to NULL
169 * mInitCheck is set to an error (!OK)
170 */
171void Drm::findFactoryForScheme(const uint8_t uuid[16]) {
172
173 closeFactory();
174
175 // lock static maps
176 Mutex::Autolock autoLock(mMapLock);
177
178 // first check cache
179 Vector<uint8_t> uuidVector;
180 uuidVector.appendArray(uuid, sizeof(uuid));
181 ssize_t index = mUUIDToLibraryPathMap.indexOfKey(uuidVector);
182 if (index >= 0) {
183 if (loadLibraryForScheme(mUUIDToLibraryPathMap[index], uuid)) {
184 mInitCheck = OK;
185 return;
186 } else {
187 ALOGE("Failed to load from cached library path!");
188 mInitCheck = ERROR_UNSUPPORTED;
189 return;
190 }
191 }
192
193 // no luck, have to search
194 String8 dirPath("/vendor/lib/mediadrm");
195 DIR* pDir = opendir(dirPath.string());
196
197 if (pDir == NULL) {
198 mInitCheck = ERROR_UNSUPPORTED;
199 ALOGE("Failed to open plugin directory %s", dirPath.string());
200 return;
201 }
202
203
204 struct dirent* pEntry;
205 while ((pEntry = readdir(pDir))) {
206
207 String8 pluginPath = dirPath + "/" + pEntry->d_name;
208
209 if (pluginPath.getPathExtension() == ".so") {
210
211 if (loadLibraryForScheme(pluginPath, uuid)) {
212 mUUIDToLibraryPathMap.add(uuidVector, pluginPath);
213 mInitCheck = OK;
214 closedir(pDir);
215 return;
216 }
217 }
218 }
219
220 closedir(pDir);
221
222 ALOGE("Failed to find drm plugin");
223 mInitCheck = ERROR_UNSUPPORTED;
224}
225
226bool Drm::loadLibraryForScheme(const String8 &path, const uint8_t uuid[16]) {
227
228 // get strong pointer to open shared library
229 ssize_t index = mLibraryPathToOpenLibraryMap.indexOfKey(path);
230 if (index >= 0) {
231 mLibrary = mLibraryPathToOpenLibraryMap[index].promote();
232 } else {
233 index = mLibraryPathToOpenLibraryMap.add(path, NULL);
234 }
235
236 if (!mLibrary.get()) {
237 mLibrary = new SharedLibrary(path);
238 if (!*mLibrary) {
239 return false;
240 }
241
242 mLibraryPathToOpenLibraryMap.replaceValueAt(index, mLibrary);
243 }
244
245 typedef DrmFactory *(*CreateDrmFactoryFunc)();
246
247 CreateDrmFactoryFunc createDrmFactory =
248 (CreateDrmFactoryFunc)mLibrary->lookup("createDrmFactory");
249
250 if (createDrmFactory == NULL ||
251 (mFactory = createDrmFactory()) == NULL ||
252 !mFactory->isCryptoSchemeSupported(uuid)) {
253 closeFactory();
254 return false;
255 }
256 return true;
257}
258
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700259bool Drm::isCryptoSchemeSupported(const uint8_t uuid[16], const String8 &mimeType) {
260
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800261 Mutex::Autolock autoLock(mLock);
262
Jeff Tinker9cf69e02013-08-21 11:59:23 -0700263 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
264 findFactoryForScheme(uuid);
265 if (mInitCheck != OK) {
266 return false;
267 }
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800268 }
269
Jeff Tinkeree7e77d2013-08-28 16:40:41 -0700270 if (mimeType != "") {
271 return mFactory->isContentTypeSupported(mimeType);
272 }
273
274 return true;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800275}
276
277status_t Drm::createPlugin(const uint8_t uuid[16]) {
278 Mutex::Autolock autoLock(mLock);
279
280 if (mPlugin != NULL) {
281 return -EINVAL;
282 }
283
284 if (!mFactory || !mFactory->isCryptoSchemeSupported(uuid)) {
285 findFactoryForScheme(uuid);
286 }
287
288 if (mInitCheck != OK) {
289 return mInitCheck;
290 }
291
Jeff Tinker0cb126a2013-04-02 13:08:05 -0700292 status_t result = mFactory->createDrmPlugin(uuid, &mPlugin);
293 mPlugin->setListener(this);
294 return result;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800295}
296
297status_t Drm::destroyPlugin() {
298 Mutex::Autolock autoLock(mLock);
299
300 if (mInitCheck != OK) {
301 return mInitCheck;
302 }
303
304 if (mPlugin == NULL) {
305 return -EINVAL;
306 }
307
308 delete mPlugin;
309 mPlugin = NULL;
310
311 return OK;
312}
313
314status_t Drm::openSession(Vector<uint8_t> &sessionId) {
315 Mutex::Autolock autoLock(mLock);
316
317 if (mInitCheck != OK) {
318 return mInitCheck;
319 }
320
321 if (mPlugin == NULL) {
322 return -EINVAL;
323 }
324
Ronghua Wu5c3da202015-02-22 08:45:28 -0800325 status_t err = mPlugin->openSession(sessionId);
326 if (err == ERROR_DRM_RESOURCE_BUSY) {
327 bool retry = false;
328 retry = DrmSessionManager::Instance()->reclaimSession(getCallingPid());
329 if (retry) {
330 err = mPlugin->openSession(sessionId);
331 }
332 }
333 if (err == OK) {
334 DrmSessionManager::Instance()->addSession(getCallingPid(), mDrmSessionClient, sessionId);
335 }
336 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800337}
338
339status_t Drm::closeSession(Vector<uint8_t> const &sessionId) {
340 Mutex::Autolock autoLock(mLock);
341
342 if (mInitCheck != OK) {
343 return mInitCheck;
344 }
345
346 if (mPlugin == NULL) {
347 return -EINVAL;
348 }
349
Ronghua Wu5c3da202015-02-22 08:45:28 -0800350 status_t err = mPlugin->closeSession(sessionId);
351 if (err == OK) {
352 DrmSessionManager::Instance()->removeSession(sessionId);
353 }
354 return err;
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800355}
356
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700357status_t Drm::getKeyRequest(Vector<uint8_t> const &sessionId,
358 Vector<uint8_t> const &initData,
359 String8 const &mimeType, DrmPlugin::KeyType keyType,
360 KeyedVector<String8, String8> const &optionalParameters,
361 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800362 Mutex::Autolock autoLock(mLock);
363
364 if (mInitCheck != OK) {
365 return mInitCheck;
366 }
367
368 if (mPlugin == NULL) {
369 return -EINVAL;
370 }
371
Ronghua Wu5c3da202015-02-22 08:45:28 -0800372 DrmSessionManager::Instance()->useSession(sessionId);
373
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700374 return mPlugin->getKeyRequest(sessionId, initData, mimeType, keyType,
375 optionalParameters, request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800376}
377
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700378status_t Drm::provideKeyResponse(Vector<uint8_t> const &sessionId,
379 Vector<uint8_t> const &response,
380 Vector<uint8_t> &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800381 Mutex::Autolock autoLock(mLock);
382
383 if (mInitCheck != OK) {
384 return mInitCheck;
385 }
386
387 if (mPlugin == NULL) {
388 return -EINVAL;
389 }
390
Ronghua Wu5c3da202015-02-22 08:45:28 -0800391 DrmSessionManager::Instance()->useSession(sessionId);
392
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700393 return mPlugin->provideKeyResponse(sessionId, response, keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800394}
395
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700396status_t Drm::removeKeys(Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800397 Mutex::Autolock autoLock(mLock);
398
399 if (mInitCheck != OK) {
400 return mInitCheck;
401 }
402
403 if (mPlugin == NULL) {
404 return -EINVAL;
405 }
406
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700407 return mPlugin->removeKeys(keySetId);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800408}
409
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700410status_t Drm::restoreKeys(Vector<uint8_t> const &sessionId,
411 Vector<uint8_t> const &keySetId) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800412 Mutex::Autolock autoLock(mLock);
413
414 if (mInitCheck != OK) {
415 return mInitCheck;
416 }
417
418 if (mPlugin == NULL) {
419 return -EINVAL;
420 }
421
Ronghua Wu5c3da202015-02-22 08:45:28 -0800422 DrmSessionManager::Instance()->useSession(sessionId);
423
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700424 return mPlugin->restoreKeys(sessionId, keySetId);
425}
426
427status_t Drm::queryKeyStatus(Vector<uint8_t> const &sessionId,
428 KeyedVector<String8, String8> &infoMap) const {
429 Mutex::Autolock autoLock(mLock);
430
431 if (mInitCheck != OK) {
432 return mInitCheck;
433 }
434
435 if (mPlugin == NULL) {
436 return -EINVAL;
437 }
438
Ronghua Wu5c3da202015-02-22 08:45:28 -0800439 DrmSessionManager::Instance()->useSession(sessionId);
440
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700441 return mPlugin->queryKeyStatus(sessionId, infoMap);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800442}
443
Jeff Tinker68d9d712014-03-04 13:21:31 -0800444status_t Drm::getProvisionRequest(String8 const &certType, String8 const &certAuthority,
445 Vector<uint8_t> &request, String8 &defaultUrl) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800446 Mutex::Autolock autoLock(mLock);
447
448 if (mInitCheck != OK) {
449 return mInitCheck;
450 }
451
452 if (mPlugin == NULL) {
453 return -EINVAL;
454 }
455
Jeff Tinker68d9d712014-03-04 13:21:31 -0800456 return mPlugin->getProvisionRequest(certType, certAuthority,
457 request, defaultUrl);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800458}
459
Jeff Tinker68d9d712014-03-04 13:21:31 -0800460status_t Drm::provideProvisionResponse(Vector<uint8_t> const &response,
461 Vector<uint8_t> &certificate,
462 Vector<uint8_t> &wrappedKey) {
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800463 Mutex::Autolock autoLock(mLock);
464
465 if (mInitCheck != OK) {
466 return mInitCheck;
467 }
468
469 if (mPlugin == NULL) {
470 return -EINVAL;
471 }
472
Jeff Tinker68d9d712014-03-04 13:21:31 -0800473 return mPlugin->provideProvisionResponse(response, certificate, wrappedKey);
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800474}
475
Jeff Tinker68b15552014-04-30 10:19:03 -0700476status_t Drm::unprovisionDevice() {
477 Mutex::Autolock autoLock(mLock);
478
479 if (mInitCheck != OK) {
480 return mInitCheck;
481 }
482
483 if (mPlugin == NULL) {
484 return -EINVAL;
485 }
486
487 if (!checkPermission("android.permission.REMOVE_DRM_CERTIFICATES")) {
488 return -EPERM;
489 }
490
491 return mPlugin->unprovisionDevice();
492}
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800493
494status_t Drm::getSecureStops(List<Vector<uint8_t> > &secureStops) {
495 Mutex::Autolock autoLock(mLock);
496
497 if (mInitCheck != OK) {
498 return mInitCheck;
499 }
500
501 if (mPlugin == NULL) {
502 return -EINVAL;
503 }
504
505 return mPlugin->getSecureStops(secureStops);
506}
507
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700508status_t Drm::getSecureStop(Vector<uint8_t> const &ssid, Vector<uint8_t> &secureStop) {
509 Mutex::Autolock autoLock(mLock);
510
511 if (mInitCheck != OK) {
512 return mInitCheck;
513 }
514
515 if (mPlugin == NULL) {
516 return -EINVAL;
517 }
518
519 return mPlugin->getSecureStop(ssid, secureStop);
520}
521
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800522status_t Drm::releaseSecureStops(Vector<uint8_t> const &ssRelease) {
523 Mutex::Autolock autoLock(mLock);
524
525 if (mInitCheck != OK) {
526 return mInitCheck;
527 }
528
529 if (mPlugin == NULL) {
530 return -EINVAL;
531 }
532
533 return mPlugin->releaseSecureStops(ssRelease);
534}
535
Jeff Tinker3c1285e2014-10-31 00:55:16 -0700536status_t Drm::releaseAllSecureStops() {
537 Mutex::Autolock autoLock(mLock);
538
539 if (mInitCheck != OK) {
540 return mInitCheck;
541 }
542
543 if (mPlugin == NULL) {
544 return -EINVAL;
545 }
546
547 return mPlugin->releaseAllSecureStops();
548}
549
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800550status_t Drm::getPropertyString(String8 const &name, String8 &value ) const {
551 Mutex::Autolock autoLock(mLock);
552
553 if (mInitCheck != OK) {
554 return mInitCheck;
555 }
556
557 if (mPlugin == NULL) {
558 return -EINVAL;
559 }
560
561 return mPlugin->getPropertyString(name, value);
562}
563
564status_t Drm::getPropertyByteArray(String8 const &name, Vector<uint8_t> &value ) const {
565 Mutex::Autolock autoLock(mLock);
566
567 if (mInitCheck != OK) {
568 return mInitCheck;
569 }
570
571 if (mPlugin == NULL) {
572 return -EINVAL;
573 }
574
575 return mPlugin->getPropertyByteArray(name, value);
576}
577
578status_t Drm::setPropertyString(String8 const &name, String8 const &value ) const {
579 Mutex::Autolock autoLock(mLock);
580
581 if (mInitCheck != OK) {
582 return mInitCheck;
583 }
584
585 if (mPlugin == NULL) {
586 return -EINVAL;
587 }
588
589 return mPlugin->setPropertyString(name, value);
590}
591
592status_t Drm::setPropertyByteArray(String8 const &name,
593 Vector<uint8_t> const &value ) const {
594 Mutex::Autolock autoLock(mLock);
595
596 if (mInitCheck != OK) {
597 return mInitCheck;
598 }
599
600 if (mPlugin == NULL) {
601 return -EINVAL;
602 }
603
604 return mPlugin->setPropertyByteArray(name, value);
605}
606
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700607
608status_t Drm::setCipherAlgorithm(Vector<uint8_t> const &sessionId,
609 String8 const &algorithm) {
610 Mutex::Autolock autoLock(mLock);
611
612 if (mInitCheck != OK) {
613 return mInitCheck;
614 }
615
616 if (mPlugin == NULL) {
617 return -EINVAL;
618 }
619
Ronghua Wu5c3da202015-02-22 08:45:28 -0800620 DrmSessionManager::Instance()->useSession(sessionId);
621
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700622 return mPlugin->setCipherAlgorithm(sessionId, algorithm);
623}
624
625status_t Drm::setMacAlgorithm(Vector<uint8_t> const &sessionId,
626 String8 const &algorithm) {
627 Mutex::Autolock autoLock(mLock);
628
629 if (mInitCheck != OK) {
630 return mInitCheck;
631 }
632
633 if (mPlugin == NULL) {
634 return -EINVAL;
635 }
636
Ronghua Wu5c3da202015-02-22 08:45:28 -0800637 DrmSessionManager::Instance()->useSession(sessionId);
638
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700639 return mPlugin->setMacAlgorithm(sessionId, algorithm);
640}
641
642status_t Drm::encrypt(Vector<uint8_t> const &sessionId,
643 Vector<uint8_t> const &keyId,
644 Vector<uint8_t> const &input,
645 Vector<uint8_t> const &iv,
646 Vector<uint8_t> &output) {
647 Mutex::Autolock autoLock(mLock);
648
649 if (mInitCheck != OK) {
650 return mInitCheck;
651 }
652
653 if (mPlugin == NULL) {
654 return -EINVAL;
655 }
656
Ronghua Wu5c3da202015-02-22 08:45:28 -0800657 DrmSessionManager::Instance()->useSession(sessionId);
658
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700659 return mPlugin->encrypt(sessionId, keyId, input, iv, output);
660}
661
662status_t Drm::decrypt(Vector<uint8_t> const &sessionId,
663 Vector<uint8_t> const &keyId,
664 Vector<uint8_t> const &input,
665 Vector<uint8_t> const &iv,
666 Vector<uint8_t> &output) {
667 Mutex::Autolock autoLock(mLock);
668
669 if (mInitCheck != OK) {
670 return mInitCheck;
671 }
672
673 if (mPlugin == NULL) {
674 return -EINVAL;
675 }
676
Ronghua Wu5c3da202015-02-22 08:45:28 -0800677 DrmSessionManager::Instance()->useSession(sessionId);
678
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700679 return mPlugin->decrypt(sessionId, keyId, input, iv, output);
680}
681
682status_t Drm::sign(Vector<uint8_t> const &sessionId,
683 Vector<uint8_t> const &keyId,
684 Vector<uint8_t> const &message,
685 Vector<uint8_t> &signature) {
686 Mutex::Autolock autoLock(mLock);
687
688 if (mInitCheck != OK) {
689 return mInitCheck;
690 }
691
692 if (mPlugin == NULL) {
693 return -EINVAL;
694 }
695
Ronghua Wu5c3da202015-02-22 08:45:28 -0800696 DrmSessionManager::Instance()->useSession(sessionId);
697
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700698 return mPlugin->sign(sessionId, keyId, message, signature);
699}
700
701status_t Drm::verify(Vector<uint8_t> const &sessionId,
702 Vector<uint8_t> const &keyId,
703 Vector<uint8_t> const &message,
704 Vector<uint8_t> const &signature,
705 bool &match) {
706 Mutex::Autolock autoLock(mLock);
707
708 if (mInitCheck != OK) {
709 return mInitCheck;
710 }
711
712 if (mPlugin == NULL) {
713 return -EINVAL;
714 }
715
Ronghua Wu5c3da202015-02-22 08:45:28 -0800716 DrmSessionManager::Instance()->useSession(sessionId);
717
Jeff Tinker8856c8b2013-03-30 16:19:44 -0700718 return mPlugin->verify(sessionId, keyId, message, signature, match);
719}
720
Jeff Tinker68d9d712014-03-04 13:21:31 -0800721status_t Drm::signRSA(Vector<uint8_t> const &sessionId,
722 String8 const &algorithm,
723 Vector<uint8_t> const &message,
724 Vector<uint8_t> const &wrappedKey,
725 Vector<uint8_t> &signature) {
726 Mutex::Autolock autoLock(mLock);
727
728 if (mInitCheck != OK) {
729 return mInitCheck;
730 }
731
732 if (mPlugin == NULL) {
733 return -EINVAL;
734 }
735
Jeff Tinker81e0bd42014-04-02 16:41:38 -0700736 if (!checkPermission("android.permission.ACCESS_DRM_CERTIFICATES")) {
737 return -EPERM;
738 }
739
Ronghua Wu5c3da202015-02-22 08:45:28 -0800740 DrmSessionManager::Instance()->useSession(sessionId);
741
Jeff Tinker68d9d712014-03-04 13:21:31 -0800742 return mPlugin->signRSA(sessionId, algorithm, message, wrappedKey, signature);
743}
744
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700745void Drm::binderDied(const wp<IBinder> &the_late_who)
746{
Jeff Tinker4dbc8cc2014-11-16 11:52:03 -0800747 mEventLock.lock();
748 mListener.clear();
749 mEventLock.unlock();
750
751 Mutex::Autolock autoLock(mLock);
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700752 delete mPlugin;
753 mPlugin = NULL;
754 closeFactory();
Jeff Tinker3d3f67f2013-07-03 15:38:58 -0700755}
756
Jeff Tinkercc82dc62013-02-08 10:18:35 -0800757} // namespace android