ICrypto.cpp revision 2514d080c8a54ff603a45d7e336de668fe7329db
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,
362514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    NOTIFY_RESOLUTION,
37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
38ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstruct BpCrypto : public BpInterface<ICrypto> {
40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    BpCrypto(const sp<IBinder> &impl)
41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        : BpInterface<ICrypto>(impl) {
42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t initCheck() const {
45ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
46ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(INIT_CHECK, data, &reply);
48ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
49ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
51ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
52bafb682ec7f51486e751fea954169deb91846063Jeff Tinker    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) {
53ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
54ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
57ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
59ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
60ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t createPlugin(
621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) {
63ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
64ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(opaqueSize);
67705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
68705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        if (opaqueSize > 0) {
69705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            data.write(opaqueData, opaqueSize);
70705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        }
71705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(CREATE_PLUGIN, data, &reply);
73ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
74ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
75ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
76ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t destroyPlugin() {
78ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
79ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DESTROY_PLUGIN, data, &reply);
81ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
82ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
83ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
84ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool requiresSecureDecoderComponent(
861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime) const {
87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
88ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeCString(mime);
901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
91ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
93ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
94ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
95fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong    virtual ssize_t decrypt(
961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure,
971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t key[16],
981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t iv[16],
991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode,
1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const void *srcPtr,
1011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
1025b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            void *dstPtr,
1035b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            AString *errorDetailMsg) {
104ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
105ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(secure);
1071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(mode);
1084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        static const uint8_t kDummy[16] = { 0 };
1104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (key == NULL) {
1124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = kDummy;
1134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (iv == NULL) {
1164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = kDummy;
1174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(key, 16);
1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(iv, 16);
1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        size_t totalSize = 0;
1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfEncryptedData;
1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfClearData;
126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
127ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(totalSize);
1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(srcPtr, totalSize);
1301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(numSubSamples);
1321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
1331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (secure) {
135bcca9e072c1f288a53ce6862936f57dc36488f96Jeff Tinker            data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
137ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DECRYPT, data, &reply);
139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
140fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        ssize_t result = reply.readInt32();
141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1425b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        if (result >= ERROR_DRM_VENDOR_MIN && result <= ERROR_DRM_VENDOR_MAX) {
1435b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            errorDetailMsg->setTo(reply.readCString());
1445b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        }
1455b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
146fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        if (!secure && result >= 0) {
147fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            reply.read(dstPtr, result);
148ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
149ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
150fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong        return result;
151ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
152ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1532514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    virtual void notifyResolution(
1542514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        uint32_t width, uint32_t height) {
1552514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        Parcel data, reply;
1562514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1572514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInt32(width);
1582514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        data.writeInt32(height);
1592514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        remote()->transact(NOTIFY_RESOLUTION, data, &reply);
1602514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker    }
1612514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate:
163ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
168ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber////////////////////////////////////////////////////////////////////////////////
169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
170ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact(
171ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
172ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    switch (code) {
1731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case INIT_CHECK:
174ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
175ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(initCheck());
177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
178ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case IS_CRYPTO_SUPPORTED:
182ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(isCryptoSchemeSupported(uuid));
187ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
188ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
189ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
190ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case CREATE_PLUGIN:
192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t opaqueSize = data.readInt32();
199705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            void *opaqueData = NULL;
200705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
201705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueSize > 0) {
202705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = malloc(opaqueSize);
203705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                data.read(opaqueData, opaqueSize);
204705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
208705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueData != NULL) {
209705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                free(opaqueData);
210705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = NULL;
211705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
213ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
214ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DESTROY_PLUGIN:
217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
218ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(destroyPlugin());
220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
222ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
223ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case REQUIRES_SECURE_COMPONENT:
225ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
226ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime = data.readCString();
2291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(requiresSecureDecoderComponent(mime));
230ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return OK;
2321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DECRYPT:
2351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        {
2361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure = data.readInt32() != 0;
2391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
240ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t key[16];
2421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(key, sizeof(key));
243ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t iv[16];
2451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(iv, sizeof(iv));
246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t totalSize = data.readInt32();
2481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *srcData = malloc(totalSize);
2491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(srcData, totalSize);
250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            int32_t numSubSamples = data.readInt32();
252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::SubSample *subSamples =
2541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new CryptoPlugin::SubSample[numSubSamples];
255ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(
2571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples,
2581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    sizeof(CryptoPlugin::SubSample) * numSubSamples);
259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr;
2611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (secure) {
262bcca9e072c1f288a53ce6862936f57dc36488f96Jeff Tinker                dstPtr = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
2631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
2641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = malloc(totalSize);
265ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
266ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            AString errorDetailMsg;
268fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            ssize_t result = decrypt(
2691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    secure,
2701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    key,
2711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    iv,
2721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    mode,
2731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    srcData,
2741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples, numSubSamples,
2755b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                    dstPtr,
2765b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                    &errorDetailMsg);
277ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
278fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            reply->writeInt32(result);
279ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
280fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong            if (result >= ERROR_DRM_VENDOR_MIN
281fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong                && result <= ERROR_DRM_VENDOR_MAX) {
2825b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber                reply->writeCString(errorDetailMsg.c_str());
2835b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber            }
2845b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber
2851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!secure) {
286fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong                if (result >= 0) {
287fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong                    CHECK_LE(result, static_cast<ssize_t>(totalSize));
288fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong                    reply->write(dstPtr, result);
2891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
2901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                free(dstPtr);
2911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = NULL;
292ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
293ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            delete[] subSamples;
2951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            subSamples = NULL;
296ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
297ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            free(srcData);
298ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            srcData = NULL;
299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
300ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
301ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
302ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3032514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        case NOTIFY_RESOLUTION:
3042514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        {
3052514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            CHECK_INTERFACE(ICrypto, data, reply);
3062514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
3072514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            int32_t width = data.readInt32();
3082514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            int32_t height = data.readInt32();
3092514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            notifyResolution(width, height);
3102514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
3112514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker            return OK;
3122514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker        }
3132514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker
314ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        default:
315ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return BBinder::onTransact(code, data, reply, flags);
316ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
317ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
318ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
319ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}  // namespace android
320