ICrypto.cpp revision 5b8987e7de9d04b09153f329c680d2316cdb44ec
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 "ICrypto"
19ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <utils/Log.h>
20ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
21ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <binder/Parcel.h>
22ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h>
235b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/MediaErrors.h>
24ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/ADebug.h>
255b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h>
26ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android {
28ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
29ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberenum {
301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    IS_CRYPTO_SUPPORTED,
321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    CREATE_PLUGIN,
331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DESTROY_PLUGIN,
341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    REQUIRES_SECURE_COMPONENT,
351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DECRYPT,
36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
38ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstruct BpCrypto : public BpInterface<ICrypto> {
39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    BpCrypto(const sp<IBinder> &impl)
40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        : BpInterface<ICrypto>(impl) {
41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t initCheck() const {
44ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
45ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(INIT_CHECK, data, &reply);
47ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
48ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
49ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const {
52ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
53ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
56ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
58ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
59ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t createPlugin(
611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) {
62ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
63ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(opaqueSize);
66705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
67705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        if (opaqueSize > 0) {
68705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            data.write(opaqueData, opaqueSize);
69705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        }
70705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(CREATE_PLUGIN, data, &reply);
72ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
73ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
74ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
75ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t destroyPlugin() {
77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
78ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DESTROY_PLUGIN, data, &reply);
80ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
81ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
82ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
83ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool requiresSecureDecoderComponent(
851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime) const {
86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeCString(mime);
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
90ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
92ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
93ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t decrypt(
951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure,
961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t key[16],
971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t iv[16],
981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode,
991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const void *srcPtr,
1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
1015b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            void *dstPtr,
1025b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            AString *errorDetailMsg) {
103ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(secure);
1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(mode);
1074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        static const uint8_t kDummy[16] = { 0 };
1094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (key == NULL) {
1114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = kDummy;
1124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (iv == NULL) {
1154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = kDummy;
1164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(key, 16);
1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(iv, 16);
1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        size_t totalSize = 0;
1221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfEncryptedData;
1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfClearData;
125ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(totalSize);
1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(srcPtr, totalSize);
1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(numSubSamples);
1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
1321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (secure) {
1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.writeIntPtr((intptr_t)dstPtr);
1351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
136ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DECRYPT, data, &reply);
138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        status_t result = reply.readInt32();
140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1415b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        if (result >= ERROR_DRM_VENDOR_MIN && result <= ERROR_DRM_VENDOR_MAX) {
1425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            errorDetailMsg->setTo(reply.readCString());
1435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        }
1445b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
1451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (result != OK) {
1461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return result;
147ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
148ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (!secure) {
1501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply.read(dstPtr, totalSize);
1511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
152ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return OK;
154ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
155ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
156ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate:
157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
158ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
159ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
160ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
161ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber////////////////////////////////////////////////////////////////////////////////
163ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact(
165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    switch (code) {
1671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case INIT_CHECK:
168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(initCheck());
171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
172ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
173ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
174ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case IS_CRYPTO_SUPPORTED:
176ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(isCryptoSchemeSupported(uuid));
181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
184ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case CREATE_PLUGIN:
186ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
187ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
188ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t opaqueSize = data.readInt32();
193705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            void *opaqueData = NULL;
194705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
195705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueSize > 0) {
196705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = malloc(opaqueSize);
197705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                data.read(opaqueData, opaqueSize);
198705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
202705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueData != NULL) {
203705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                free(opaqueData);
204705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = NULL;
205705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
206ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
208ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DESTROY_PLUGIN:
211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(destroyPlugin());
214ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case REQUIRES_SECURE_COMPONENT:
219ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime = data.readCString();
2231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(requiresSecureDecoderComponent(mime));
224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return OK;
2261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DECRYPT:
2291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        {
2301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure = data.readInt32() != 0;
2331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
234ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t key[16];
2361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(key, sizeof(key));
237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t iv[16];
2391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(iv, sizeof(iv));
240ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t totalSize = data.readInt32();
2421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *srcData = malloc(totalSize);
2431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(srcData, totalSize);
244ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            int32_t numSubSamples = data.readInt32();
246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::SubSample *subSamples =
2481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new CryptoPlugin::SubSample[numSubSamples];
249ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(
2511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples,
2521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    sizeof(CryptoPlugin::SubSample) * numSubSamples);
253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr;
2551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (secure) {
2561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = (void *)data.readIntPtr();
2571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
2581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = malloc(totalSize);
259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
260ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2615b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            AString errorDetailMsg;
2625b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            status_t err = decrypt(
2641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    secure,
2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    key,
2661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    iv,
2671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    mode,
2681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    srcData,
2691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples, numSubSamples,
2705b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                    dstPtr,
2715b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                    &errorDetailMsg);
272ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(err);
274ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            if (err >= ERROR_DRM_VENDOR_MIN
2765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                    && err <= ERROR_DRM_VENDOR_MAX) {
2775b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                reply->writeCString(errorDetailMsg.c_str());
2785b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            }
2795b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!secure) {
2811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                if (err == OK) {
2821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    reply->write(dstPtr, totalSize);
2831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                free(dstPtr);
2861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = NULL;
287ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
288ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            delete[] subSamples;
2901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            subSamples = NULL;
291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            free(srcData);
293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            srcData = NULL;
294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
295ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        default:
299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return BBinder::onTransact(code, data, reply, flags);
300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
301ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
302ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}  // namespace android
304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
305