ICrypto.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 "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);
641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(opaqueData, opaqueSize);
651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(CREATE_PLUGIN, data, &reply);
66ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
67ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
68ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
69ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t destroyPlugin() {
71ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
72ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DESTROY_PLUGIN, data, &reply);
74ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
75ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        return reply.readInt32();
76ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
781bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual bool requiresSecureDecoderComponent(
791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime) const {
80ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
81ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeCString(mime);
831bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply);
84ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return reply.readInt32() != 0;
86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
87ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber    virtual status_t decrypt(
891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure,
901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t key[16],
911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const uint8_t iv[16],
921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode,
931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const void *srcPtr,
941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr) {
96ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        Parcel data, reply;
97ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(secure);
991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(mode);
1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(key, 16);
1011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(iv, 16);
1021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        size_t totalSize = 0;
1041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        for (size_t i = 0; i < numSubSamples; ++i) {
1051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfEncryptedData;
1061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            totalSize += subSamples[i].mNumBytesOfClearData;
107ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
108ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(totalSize);
1101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(srcPtr, totalSize);
1111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.writeInt32(numSubSamples);
1131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
1141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (secure) {
1161bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.writeIntPtr((intptr_t)dstPtr);
1171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
118ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        remote()->transact(DECRYPT, data, &reply);
120ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        status_t result = reply.readInt32();
122ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (result != OK) {
1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return result;
125ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
126ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        if (!secure) {
1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply.read(dstPtr, totalSize);
1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
130ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        return OK;
132ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
133ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
134ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate:
135ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(BpCrypto);
136ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber};
137ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
138ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto");
139ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
140ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber////////////////////////////////////////////////////////////////////////////////
141ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact(
143ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
144ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    switch (code) {
1451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case INIT_CHECK:
146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
147ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(initCheck());
149ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
150ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
151ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
152ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case IS_CRYPTO_SUPPORTED:
154ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
155ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(isCryptoSchemeSupported(uuid));
159ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
160ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
161ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
162ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case CREATE_PLUGIN:
164ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
165ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
166ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t uuid[16];
1681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(uuid, sizeof(uuid));
1691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber
1701bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t opaqueSize = data.readInt32();
1711bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *opaqueData = malloc(opaqueSize);
1721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(opaqueData, opaqueSize);
173ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
175ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            free(opaqueData);
1771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            opaqueData = NULL;
178ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
179ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
180ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DESTROY_PLUGIN:
183ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
184ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
1851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(destroyPlugin());
186ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
187ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
188ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
189ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case REQUIRES_SECURE_COMPONENT:
191ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        {
192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            const char *mime = data.readCString();
1951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(requiresSecureDecoderComponent(mime));
196ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
1971bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            return OK;
1981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        }
199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        case DECRYPT:
2011bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber        {
2021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CHECK_INTERFACE(ICrypto, data, reply);
203ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            bool secure = data.readInt32() != 0;
2051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
206ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t key[16];
2081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(key, sizeof(key));
209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            uint8_t iv[16];
2111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(iv, sizeof(iv));
212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            size_t totalSize = data.readInt32();
2141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *srcData = malloc(totalSize);
2151bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(srcData, totalSize);
216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            int32_t numSubSamples = data.readInt32();
218ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2191bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            CryptoPlugin::SubSample *subSamples =
2201bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                new CryptoPlugin::SubSample[numSubSamples];
221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            data.read(
2231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples,
2241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    sizeof(CryptoPlugin::SubSample) * numSubSamples);
225ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            void *dstPtr;
2271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (secure) {
2281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = (void *)data.readIntPtr();
2291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            } else {
2301bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = malloc(totalSize);
231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
232ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            status_t err = decrypt(
2341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    secure,
2351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    key,
2361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    iv,
2371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    mode,
2381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    srcData,
2391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    subSamples, numSubSamples,
2401bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    dstPtr);
241ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2421bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            reply->writeInt32(err);
243ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            if (!secure) {
2451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                if (err == OK) {
2461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                    reply->write(dstPtr, totalSize);
2471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                }
248ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                free(dstPtr);
2501bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber                dstPtr = NULL;
251ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            }
252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
2531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            delete[] subSamples;
2541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber            subSamples = NULL;
255ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
256ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            free(srcData);
257ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            srcData = NULL;
258ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return OK;
260ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        }
261ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
262ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber        default:
263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber            return BBinder::onTransact(code, data, reply, flags);
264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
265ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}
266ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
267ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}  // namespace android
268ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
269