Crypto.cpp revision 1bd139a2a68690e80398b70b27ca59550fea0e65
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> 251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <media/stagefright/foundation/hexdump.h> 26ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/MediaErrors.h> 27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber#include <dlfcn.h> 291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android { 31ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 321bd139a2a68690e80398b70b27ca59550fea0e65Andreas HuberCrypto::Crypto() 331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber : mInitCheck(NO_INIT), 341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle(NULL), 351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin(NULL) { 361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mInitCheck = init(); 37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 38ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberCrypto::~Crypto() { 401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mPlugin; 411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin = NULL; 421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mFactory; 441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mFactory = NULL; 451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mLibHandle != NULL) { 471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dlclose(mLibHandle); 481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = NULL; 491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 51ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::initCheck() const { 531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 54ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 55ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::init() { 571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = dlopen("libdrmdecrypt.so", RTLD_NOW); 581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mLibHandle == NULL) { 601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return ERROR_UNSUPPORTED; 611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber typedef CryptoFactory *(*CreateCryptoFactoryFunc)(); 641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CreateCryptoFactoryFunc createCryptoFactory = 651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber (CreateCryptoFactoryFunc)dlsym(mLibHandle, "createCryptoFactory"); 661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (createCryptoFactory == NULL 681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber || ((mFactory = createCryptoFactory()) == NULL)) { 691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dlclose(mLibHandle); 701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mLibHandle = NULL; 711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return ERROR_UNSUPPORTED; 731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 76ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberbool Crypto::isCryptoSchemeSupported(const uint8_t uuid[16]) const { 791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return false; 831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mFactory->isCryptoSchemeSupported(uuid); 86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::createPlugin( 891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t uuid[16], const void *data, size_t size) { 901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin != NULL) { 971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mFactory->createPlugin(uuid, data, size, &mPlugin); 101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 102ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::destroyPlugin() { 1041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete mPlugin; 1151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber mPlugin = NULL; 1161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 1181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber} 1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberbool Crypto::requiresSecureDecoderComponent(const char *mime) const { 1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mPlugin->requiresSecureDecoderComponent(mime); 132ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 133ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberstatus_t Crypto::decrypt( 1351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber bool secure, 1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t key[16], 1371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t iv[16], 1381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::Mode mode, 1391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const void *srcPtr, 1401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 1411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber void *dstPtr) { 1421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber Mutex::Autolock autoLock(mLock); 1431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mInitCheck != OK) { 1451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mInitCheck; 1461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (mPlugin == NULL) { 1491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return -EINVAL; 1501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 1511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return mPlugin->decrypt( 1531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr); 154ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 155ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 156ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} // namespace android 157