ICrypto.cpp revision 705868c0f2a6e85a39addefe4db9f2130627c219
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>
23ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/ADebug.h>
24ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
25ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android {
26ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberenum {
281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION,
291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    IS_CRYPTO_SUPPORTED,
301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    CREATE_PLUGIN,
311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DESTROY_PLUGIN,
321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    REQUIRES_SECURE_COMPONENT,
331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    DECRYPT,
34ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
35ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
36ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstruct BpCrypto : public BpInterface<ICrypto> {
37ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    BpCrypto(const sp<IBinder> &impl)
38ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        : BpInterface<ICrypto>(impl) {
39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t initCheck() const {
42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(INIT_CHECK, data, &reply);
45ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
46ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
47ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
48ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) const {
50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
51ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
521bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply);
54ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
56ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
57ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t createPlugin(
591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) {
60ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
61ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
621bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(uuid, 16);
631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(opaqueSize);
64705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
65705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        if (opaqueSize > 0) {
66705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            data.write(opaqueData, opaqueSize);
67705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber        }
68705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(CREATE_PLUGIN, data, &reply);
70ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
71ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
72ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
73ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t destroyPlugin() {
75ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
76ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DESTROY_PLUGIN, data, &reply);
78ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
79ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
80ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
81ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool requiresSecureDecoderComponent(
831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime) const {
84ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
85ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeCString(mime);
871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
88ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
90ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
91ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t decrypt(
931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure,
941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t key[16],
951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t iv[16],
961bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode,
971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const void *srcPtr,
981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr) {
100ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
101ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
1021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(secure);
1031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(mode);
1044b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1054b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        static const uint8_t kDummy[16] = { 0 };
1064b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1074b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (key == NULL) {
1084b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            key = kDummy;
1094b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1104b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1114b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        if (iv == NULL) {
1124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            iv = kDummy;
1134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber
1151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(key, 16);
1161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(iv, 16);
1171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        size_t totalSize = 0;
1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
1201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfEncryptedData;
1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfClearData;
122ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
123ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(totalSize);
1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(srcPtr, totalSize);
1261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(numSubSamples);
1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (secure) {
1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.writeIntPtr((intptr_t)dstPtr);
1321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
133ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DECRYPT, data, &reply);
135ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        status_t result = reply.readInt32();
137ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (result != OK) {
1391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return result;
140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (!secure) {
1431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply.read(dstPtr, totalSize);
1441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
145ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return OK;
147ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
148ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
149ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate:
150ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
151ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
152ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
153ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
154ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
155ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber////////////////////////////////////////////////////////////////////////////////
156ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact(
158ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
159ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    switch (code) {
1601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case INIT_CHECK:
161ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(initCheck());
164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
167ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case IS_CRYPTO_SUPPORTED:
169ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
170ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(isCryptoSchemeSupported(uuid));
174ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
175ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
176ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case CREATE_PLUGIN:
179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t opaqueSize = data.readInt32();
186705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            void *opaqueData = NULL;
187705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber
188705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueSize > 0) {
189705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = malloc(opaqueSize);
190705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                data.read(opaqueData, opaqueSize);
191705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
195705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            if (opaqueData != NULL) {
196705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                free(opaqueData);
197705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber                opaqueData = NULL;
198705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber            }
199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
200ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
201ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
202ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DESTROY_PLUGIN:
204ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
205ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
2061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(destroyPlugin());
207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
208ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
210ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case REQUIRES_SECURE_COMPONENT:
212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
213ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
214ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime = data.readCString();
2161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(requiresSecureDecoderComponent(mime));
217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return OK;
2191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DECRYPT:
2221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        {
2231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure = data.readInt32() != 0;
2261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t key[16];
2291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(key, sizeof(key));
230ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t iv[16];
2321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(iv, sizeof(iv));
233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t totalSize = data.readInt32();
2351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *srcData = malloc(totalSize);
2361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(srcData, totalSize);
237ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            int32_t numSubSamples = data.readInt32();
239ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::SubSample *subSamples =
2411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new CryptoPlugin::SubSample[numSubSamples];
242ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(
2441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples,
2451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    sizeof(CryptoPlugin::SubSample) * numSubSamples);
246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr;
2481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (secure) {
2491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = (void *)data.readIntPtr();
2501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
2511bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = malloc(totalSize);
252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            status_t err = decrypt(
2551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    secure,
2561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    key,
2571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    iv,
2581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    mode,
2591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    srcData,
2601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples, numSubSamples,
2611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    dstPtr);
262ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(err);
264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!secure) {
2661bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                if (err == OK) {
2671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    reply->write(dstPtr, totalSize);
2681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
269ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                free(dstPtr);
2711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = NULL;
272ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
273ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            delete[] subSamples;
2751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            subSamples = NULL;
276ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
277ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            free(srcData);
278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            srcData = NULL;
279ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
280ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
281ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
283ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        default:
284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return BBinder::onTransact(code, data, reply, flags);
285ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
286ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
287ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
288ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}  // namespace android
289ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
290