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 31namespace android { 32 33Crypto::Crypto() 34 : mInitCheck(NO_INIT), 35 mLibHandle(NULL), 36 mFactory(NULL), 37 mPlugin(NULL) { 38 mInitCheck = init(); 39} 40 41Crypto::~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 54status_t Crypto::initCheck() const { 55 return mInitCheck; 56} 57 58status_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 88bool 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 98status_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 113status_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 130bool 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 144ssize_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