1 /*
2 * Copyright (C) 2012 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 "Crypto"
19 #include <utils/Log.h>
20
21 #include "Crypto.h"
22
23 #include <media/hardware/CryptoAPI.h>
24 #include <media/stagefright/foundation/ADebug.h>
25 #include <media/stagefright/foundation/AString.h>
26 #include <media/stagefright/foundation/hexdump.h>
27 #include <media/stagefright/MediaErrors.h>
28
29 #include <dlfcn.h>
30
31 namespace android {
32
Crypto()33 Crypto::Crypto()
34 : mInitCheck(NO_INIT),
35 mLibHandle(NULL),
36 mFactory(NULL),
37 mPlugin(NULL) {
38 mInitCheck = init();
39 }
40
~Crypto()41 Crypto::~Crypto() {
42 delete mPlugin;
43 mPlugin = NULL;
44
45 delete mFactory;
46 mFactory = NULL;
47
48 if (mLibHandle != NULL) {
49 dlclose(mLibHandle);
50 mLibHandle = NULL;
51 }
52 }
53
initCheck() const54 status_t Crypto::initCheck() const {
55 return mInitCheck;
56 }
57
init()58 status_t Crypto::init() {
59 mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW);
60
61 if (mLibHandle == NULL) {
62 ALOGE("Unable to locate libdrmdecrypt.so");
63
64 return ERROR_UNSUPPORTED;
65 }
66
67 typedef CryptoFactory *(*CreateCryptoFactoryFunc)();
68 CreateCryptoFactoryFunc createCryptoFactory =
69 (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory");
70
71 if (createCryptoFactory == NULL
72 || ((mFactory = createCryptoFactory()) == NULL)) {
73 if (createCryptoFactory == NULL) {
74 ALOGE("Unable to find symbol 'createCryptoFactory'.");
75 } else {
76 ALOGE("createCryptoFactory() failed.");
77 }
78
79 dlclose(mLibHandle);
80 mLibHandle = NULL;
81
82 return ERROR_UNSUPPORTED;
83 }
84
85 return OK;
86 }
87
isCryptoSchemeSupported(const uint8_t uuid[16]) const88 bool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const {
89 Mutex::Autolock autoLock(mLock);
90
91 if (mInitCheck != OK) {
92 return false;
93 }
94
95 return mFactory->isCryptoSchemeSupported(uuid);
96 }
97
createPlugin(const uint8_t uuid[16],const void * data,size_t size)98 status_t Crypto::createPlugin(
99 const uint8_t uuid[16], const void *data, size_t size) {
100 Mutex::Autolock autoLock(mLock);
101
102 if (mInitCheck != OK) {
103 return mInitCheck;
104 }
105
106 if (mPlugin != NULL) {
107 return -EINVAL;
108 }
109
110 return mFactory->createPlugin(uuid, data, size, &mPlugin);
111 }
112
destroyPlugin()113 status_t Crypto::destroyPlugin() {
114 Mutex::Autolock autoLock(mLock);
115
116 if (mInitCheck != OK) {
117 return mInitCheck;
118 }
119
120 if (mPlugin == NULL) {
121 return -EINVAL;
122 }
123
124 delete mPlugin;
125 mPlugin = NULL;
126
127 return OK;
128 }
129
requiresSecureDecoderComponent(const char * mime) const130 bool Crypto::requiresSecureDecoderComponent(const char *mime) const {
131 Mutex::Autolock autoLock(mLock);
132
133 if (mInitCheck != OK) {
134 return mInitCheck;
135 }
136
137 if (mPlugin == NULL) {
138 return -EINVAL;
139 }
140
141 return mPlugin->requiresSecureDecoderComponent(mime);
142 }
143
decrypt(bool secure,const uint8_t key[16],const uint8_t iv[16],CryptoPlugin::Mode mode,const void * srcPtr,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,void * dstPtr,AString * errorDetailMsg)144 status_t Crypto::decrypt(
145 bool secure,
146 const uint8_t key[16],
147 const uint8_t iv[16],
148 CryptoPlugin::Mode mode,
149 const void *srcPtr,
150 const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
151 void *dstPtr,
152 AString *errorDetailMsg) {
153 Mutex::Autolock autoLock(mLock);
154
155 if (mInitCheck != OK) {
156 return mInitCheck;
157 }
158
159 if (mPlugin == NULL) {
160 return -EINVAL;
161 }
162
163 return mPlugin->decrypt(
164 secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr,
165 errorDetailMsg);
166 }
167
168 } // namespace android
169