1ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber/* 2ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Copyright (C) 2012 The Android Open Source Project 3ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * 4ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 5ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * you may not use this file except in compliance with the License. 6ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * You may obtain a copy of the License at 7ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * 8ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 9ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * 10ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * Unless required by applicable law or agreed to in writing, software 11ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 12ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * See the License for the specific language governing permissions and 14ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber * limitations under the License. 15ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber */ 16ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 17ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber//#define LOG_NDEBUG 0 18ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#define LOG_TAG "Crypto" 19ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <utils/Log.h> 20ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 21ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include "Crypto.h" 22ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/hardware/CryptoAPI.h> 241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/foundation/ADebug.h> 255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/foundation/hexdump.h> 27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/MediaErrors.h> 28ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <dlfcn.h> 301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 31ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android { 32ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 331bd139a2a68690e80398b70b27ca59550fea0e65Andreas HuberCrypto::Crypto() 341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber : mInitCheck(NO_INIT), 351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle(NULL), 361608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber mFactory(NULL), 371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin(NULL) { 381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mInitCheck = init(); 39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberCrypto::~Crypto() { 421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mPlugin; 431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin = NULL; 441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mFactory; 461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFactory = NULL; 471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mLibHandle != NULL) { 491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dlclose(mLibHandle); 501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = NULL; 511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 52ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 53ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::initCheck() const { 551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 56ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 57ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::init() { 591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW); 601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mLibHandle == NULL) { 621608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber ALOGE("Unable to locate libdrmdecrypt.so"); 631608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return ERROR_UNSUPPORTED; 651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); 681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CreateCryptoFactoryFunc createCryptoFactory = 691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory"); 701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (createCryptoFactory == NULL 721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber || ((mFactory = createCryptoFactory()) == NULL)) { 731608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber if (createCryptoFactory == NULL) { 741608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber ALOGE("Unable to find symbol 'createCryptoFactory'."); 751608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } else { 761608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber ALOGE("createCryptoFactory() failed."); 771608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber } 781608735ef488ecd8c3c012a3b0d4b1d4ef3d93c7Andreas Huber 791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dlclose(mLibHandle); 801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = NULL; 811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return ERROR_UNSUPPORTED; 831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberbool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const { 891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return false; 931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mFactory->isCryptoSchemeSupported(uuid); 96ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 97ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::createPlugin( 991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t uuid[16], const void *data, size_t size) { 1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin != NULL) { 1071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mFactory->createPlugin(uuid, data, size, &mPlugin); 111ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 112ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::destroyPlugin() { 1141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mPlugin; 1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin = NULL; 1261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber} 1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberbool Crypto::requiresSecureDecoderComponent(const char *mime) const { 1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mPlugin->requiresSecureDecoderComponent(mime); 142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 143ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 144fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wongssize_t Crypto::decrypt( 1451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber bool secure, 1461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t key[16], 1471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t iv[16], 1481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::Mode mode, 1491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const void *srcPtr, 1501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 1515b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber void *dstPtr, 1525b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 1531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mPlugin->decrypt( 1645b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr, 1655b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg); 166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} // namespace android 169