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