blob: d35d5b1ef92721a8c2e557780bb112e1d189cf48 [file] [log] [blame]
Andreas Hubered3e3e02012-03-26 11:13:27 -07001/*
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
Andreas Huber1bd139a2012-04-03 14:19:20 -070023#include <media/hardware/CryptoAPI.h>
24#include <media/stagefright/foundation/ADebug.h>
Andreas Huber5b8987e2012-04-19 12:52:20 -070025#include <media/stagefright/foundation/AString.h>
Andreas Huber1bd139a2012-04-03 14:19:20 -070026#include <media/stagefright/foundation/hexdump.h>
Andreas Hubered3e3e02012-03-26 11:13:27 -070027#include <media/stagefright/MediaErrors.h>
28
Andreas Huber1bd139a2012-04-03 14:19:20 -070029#include <dlfcn.h>
30
Andreas Hubered3e3e02012-03-26 11:13:27 -070031namespace android {
32
Andreas Huber1bd139a2012-04-03 14:19:20 -070033Crypto::Crypto()
34 : mInitCheck(NO_INIT),
35 mLibHandle(NULL),
Andreas Huber16087352012-04-13 14:54:36 -070036 mFactory(NULL),
Andreas Huber1bd139a2012-04-03 14:19:20 -070037 mPlugin(NULL) {
38 mInitCheck = init();
Andreas Hubered3e3e02012-03-26 11:13:27 -070039}
40
41Crypto::~Crypto() {
Andreas Huber1bd139a2012-04-03 14:19:20 -070042 delete mPlugin;
43 mPlugin = NULL;
44
45 delete mFactory;
46 mFactory = NULL;
47
48 if (mLibHandle != NULL) {
49 dlclose(mLibHandle);
50 mLibHandle = NULL;
51 }
Andreas Hubered3e3e02012-03-26 11:13:27 -070052}
53
Andreas Huber1bd139a2012-04-03 14:19:20 -070054status_t Crypto::initCheck() const {
55 return mInitCheck;
Andreas Hubered3e3e02012-03-26 11:13:27 -070056}
57
Andreas Huber1bd139a2012-04-03 14:19:20 -070058status_t Crypto::init() {
59 mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW);
60
61 if (mLibHandle == NULL) {
Andreas Huber16087352012-04-13 14:54:36 -070062 ALOGE("Unable to locate libdrmdecrypt.so");
63
Andreas Huber1bd139a2012-04-03 14:19:20 -070064 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)) {
Andreas Huber16087352012-04-13 14:54:36 -070073 if (createCryptoFactory == NULL) {
74 ALOGE("Unable to find symbol 'createCryptoFactory'.");
75 } else {
76 ALOGE("createCryptoFactory() failed.");
77 }
78
Andreas Huber1bd139a2012-04-03 14:19:20 -070079 dlclose(mLibHandle);
80 mLibHandle = NULL;
81
82 return ERROR_UNSUPPORTED;
83 }
84
85 return OK;
Andreas Hubered3e3e02012-03-26 11:13:27 -070086}
87
Andreas Huber1bd139a2012-04-03 14:19:20 -070088bool 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);
Andreas Hubered3e3e02012-03-26 11:13:27 -070096}
97
Andreas Huber1bd139a2012-04-03 14:19:20 -070098status_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);
Andreas Hubered3e3e02012-03-26 11:13:27 -0700111}
112
Andreas Huber1bd139a2012-04-03 14:19:20 -0700113status_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;
Andreas Hubered3e3e02012-03-26 11:13:27 -0700128}
129
Andreas Huber1bd139a2012-04-03 14:19:20 -0700130bool 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
144status_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,
Andreas Huber5b8987e2012-04-19 12:52:20 -0700151 void *dstPtr,
152 AString *errorDetailMsg) {
Andreas Huber1bd139a2012-04-03 14:19:20 -0700153 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(
Andreas Huber5b8987e2012-04-19 12:52:20 -0700164 secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr,
165 errorDetailMsg);
Andreas Hubered3e3e02012-03-26 11:13:27 -0700166}
167
168} // namespace android