ICrypto.cpp revision 18cb1eca504817b5b144a023ae2792d90e74c9a5
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> 22c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker#include <binder/IMemory.h> 23ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/ICrypto.h> 245b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/MediaErrors.h> 25ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber#include <media/stagefright/foundation/ADebug.h> 265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber#include <media/stagefright/foundation/AString.h> 27ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 28ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Hubernamespace android { 29ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 30ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberenum { 311bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber INIT_CHECK = IBinder::FIRST_CALL_TRANSACTION, 321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber IS_CRYPTO_SUPPORTED, 331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CREATE_PLUGIN, 341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber DESTROY_PLUGIN, 351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber REQUIRES_SECURE_COMPONENT, 361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber DECRYPT, 372514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker NOTIFY_RESOLUTION, 381849570240443d1f75775c205fa658f7070849c6Jeff Tinker SET_MEDIADRM_SESSION, 39ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}; 40ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 41ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstruct BpCrypto : public BpInterface<ICrypto> { 42ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber BpCrypto(const sp<IBinder> &impl) 43ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber : BpInterface<ICrypto>(impl) { 44ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 45ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 461bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber virtual status_t initCheck() const { 47ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 48ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 491bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(INIT_CHECK, data, &reply); 50ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 51ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return reply.readInt32(); 52ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 53ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 54bafb682ec7f51486e751fea954169deb91846063Jeff Tinker virtual bool isCryptoSchemeSupported(const uint8_t uuid[16]) { 55ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 56ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.write(uuid, 16); 581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(IS_CRYPTO_SUPPORTED, data, &reply); 59ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return reply.readInt32() != 0; 61ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 62ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber virtual status_t createPlugin( 641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t uuid[16], const void *opaqueData, size_t opaqueSize) { 65ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 66ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 671bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.write(uuid, 16); 681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeInt32(opaqueSize); 69705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber 70705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber if (opaqueSize > 0) { 71705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber data.write(opaqueData, opaqueSize); 72705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber } 73705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber 741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(CREATE_PLUGIN, data, &reply); 75ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 76ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return reply.readInt32(); 77ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 78ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber virtual status_t destroyPlugin() { 80ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 81ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 821bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(DESTROY_PLUGIN, data, &reply); 83ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 84ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return reply.readInt32(); 85ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 86ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber virtual bool requiresSecureDecoderComponent( 881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const char *mime) const { 89ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 90ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeCString(mime); 921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(REQUIRES_SECURE_COMPONENT, data, &reply); 93ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 941bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return reply.readInt32() != 0; 95ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 96ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 97fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong virtual ssize_t decrypt( 981bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber bool secure, 991bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t key[16], 1001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const uint8_t iv[16], 10118cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, 102c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker const sp<IMemory> &sharedBuffer, size_t offset, 1031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 1045b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber void *dstPtr, 1055b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString *errorDetailMsg) { 106ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber Parcel data, reply; 107ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 1081bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeInt32(secure); 1091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeInt32(mode); 11018cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker data.writeInt32(pattern.mEncryptBlocks); 11118cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker data.writeInt32(pattern.mSkipBlocks); 1124b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 1134b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber static const uint8_t kDummy[16] = { 0 }; 1144b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 1154b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (key == NULL) { 1164b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber key = kDummy; 1174b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 1184b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 1194b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber if (iv == NULL) { 1204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber iv = kDummy; 1214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber } 1224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber 1231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.write(key, 16); 1241bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.write(iv, 16); 1251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber size_t totalSize = 0; 1271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber for (size_t i = 0; i < numSubSamples; ++i) { 1281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber totalSize += subSamples[i].mNumBytesOfEncryptedData; 1291bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber totalSize += subSamples[i].mNumBytesOfClearData; 130ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 131ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeInt32(totalSize); 133c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker data.writeStrongBinder(IInterface::asBinder(sharedBuffer)); 134c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker data.writeInt32(offset); 1351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.writeInt32(numSubSamples); 1371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples); 1381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 1391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (secure) { 140bcca9e072c1f288a53ce6862936f57dc36488f96Jeff Tinker data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr))); 1411bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 142ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(DECRYPT, data, &reply); 144ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 145fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = reply.readInt32(); 146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 147ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker if (isCryptoError(result)) { 1485b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->setTo(reply.readCString()); 1495b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 1505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 151fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (!secure && result >= 0) { 152fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply.read(dstPtr, result); 153ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 154ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 155fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 156ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1582514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker virtual void notifyResolution( 1592514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker uint32_t width, uint32_t height) { 1602514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker Parcel data, reply; 1612514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 1622514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInt32(width); 1632514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInt32(height); 1642514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker remote()->transact(NOTIFY_RESOLUTION, data, &reply); 1652514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 1662514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 1671849570240443d1f75775c205fa658f7070849c6Jeff Tinker virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) { 1681849570240443d1f75775c205fa658f7070849c6Jeff Tinker Parcel data, reply; 1691849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 1701849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1711849570240443d1f75775c205fa658f7070849c6Jeff Tinker writeVector(data, sessionId); 1721849570240443d1f75775c205fa658f7070849c6Jeff Tinker remote()->transact(SET_MEDIADRM_SESSION, data, &reply); 1731849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1741849570240443d1f75775c205fa658f7070849c6Jeff Tinker return reply.readInt32(); 1751849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1761849570240443d1f75775c205fa658f7070849c6Jeff Tinker 177ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate: 1781849570240443d1f75775c205fa658f7070849c6Jeff Tinker void readVector(Parcel &reply, Vector<uint8_t> &vector) const { 1791849570240443d1f75775c205fa658f7070849c6Jeff Tinker uint32_t size = reply.readInt32(); 1801849570240443d1f75775c205fa658f7070849c6Jeff Tinker vector.insertAt((size_t)0, size); 1811849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply.read(vector.editArray(), size); 1821849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1831849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1841849570240443d1f75775c205fa658f7070849c6Jeff Tinker void writeVector(Parcel &data, Vector<uint8_t> const &vector) const { 1851849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.writeInt32(vector.size()); 1861849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.write(vector.array(), vector.size()); 1871849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1881849570240443d1f75775c205fa658f7070849c6Jeff Tinker 189ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(BpCrypto); 190ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}; 191ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 192ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto"); 193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber//////////////////////////////////////////////////////////////////////////////// 195ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1961849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::readVector(const Parcel &data, Vector<uint8_t> &vector) const { 1971849570240443d1f75775c205fa658f7070849c6Jeff Tinker uint32_t size = data.readInt32(); 1981849570240443d1f75775c205fa658f7070849c6Jeff Tinker vector.insertAt((size_t)0, size); 1991849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.read(vector.editArray(), size); 2001849570240443d1f75775c205fa658f7070849c6Jeff Tinker} 2011849570240443d1f75775c205fa658f7070849c6Jeff Tinker 2021849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const { 2031849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->writeInt32(vector.size()); 2041849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->write(vector.array(), vector.size()); 2051849570240443d1f75775c205fa658f7070849c6Jeff Tinker} 2061849570240443d1f75775c205fa658f7070849c6Jeff Tinker 207ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact( 208ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 209ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber switch (code) { 2101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case INIT_CHECK: 211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(initCheck()); 214ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 217ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2181bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case IS_CRYPTO_SUPPORTED: 219ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t uuid[16]; 2221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(uuid, sizeof(uuid)); 2231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(isCryptoSchemeSupported(uuid)); 224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 225ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 226ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 227ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2281bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case CREATE_PLUGIN: 229ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 230ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t uuid[16]; 2331bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(uuid, sizeof(uuid)); 2341bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2351bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber size_t opaqueSize = data.readInt32(); 236705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber void *opaqueData = NULL; 237705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber 238705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber if (opaqueSize > 0) { 239705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber opaqueData = malloc(opaqueSize); 240705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber data.read(opaqueData, opaqueSize); 241705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber } 242ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize)); 244ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 245705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber if (opaqueData != NULL) { 246705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber free(opaqueData); 247705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber opaqueData = NULL; 248705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber } 249ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 250ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 251ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 252ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2531bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case DESTROY_PLUGIN: 254ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 255ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2561bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(destroyPlugin()); 257ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 258ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 260ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2611bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case REQUIRES_SECURE_COMPONENT: 262ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const char *mime = data.readCString(); 2662afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia if (mime == NULL) { 2672afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(BAD_VALUE); 2682afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } else { 2692afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(requiresSecureDecoderComponent(mime)); 2702afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } 271ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2721bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 2731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 274ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case DECRYPT: 2761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber { 2771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber bool secure = data.readInt32() != 0; 2801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32(); 28118cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker CryptoPlugin::Pattern pattern; 28218cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker pattern.mEncryptBlocks = data.readInt32(); 28318cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker pattern.mSkipBlocks = data.readInt32(); 284ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t key[16]; 2861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(key, sizeof(key)); 287ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2881bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t iv[16]; 2891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(iv, sizeof(iv)); 290ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2911bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber size_t totalSize = data.readInt32(); 292c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> sharedBuffer = 293c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker interface_cast<IMemory>(data.readStrongBinder()); 2942afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia if (sharedBuffer == NULL) { 2952afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(BAD_VALUE); 2962afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia return OK; 2972afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } 298c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker int32_t offset = data.readInt32(); 299ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3001bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber int32_t numSubSamples = data.readInt32(); 301ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3021bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::SubSample *subSamples = 3031bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber new CryptoPlugin::SubSample[numSubSamples]; 304ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3051bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read( 3061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples, 3071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber sizeof(CryptoPlugin::SubSample) * numSubSamples); 308ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 309ed555d70d80964f40563d89a4e6d6a80f83f4b89Jeff Tinker void *secureBufferId, *dstPtr; 3101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (secure) { 311ed555d70d80964f40563d89a4e6d6a80f83f4b89Jeff Tinker secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64())); 3121bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 3131bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dstPtr = malloc(totalSize); 314ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 315ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3165b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString errorDetailMsg; 317c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker ssize_t result; 318c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 319c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker size_t sumSubsampleSizes = 0; 320c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker bool overflow = false; 321c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker for (int32_t i = 0; i < numSubSamples; ++i) { 322c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker CryptoPlugin::SubSample &ss = subSamples[i]; 323c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) { 324c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker sumSubsampleSizes += ss.mNumBytesOfEncryptedData; 325c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } else { 326c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker overflow = true; 327c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 328c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) { 329c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker sumSubsampleSizes += ss.mNumBytesOfClearData; 330c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } else { 331c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker overflow = true; 332c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 333c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 334c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker 335c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (overflow || sumSubsampleSizes != totalSize) { 336c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker result = -EINVAL; 337bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker } else if (totalSize > sharedBuffer->size()) { 338bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker result = -EINVAL; 339bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker } else if ((size_t)offset > sharedBuffer->size() - totalSize) { 340c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker result = -EINVAL; 341c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } else { 342c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker result = decrypt( 3431bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber secure, 3441bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 3451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 34618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker mode, pattern, 347c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sharedBuffer, offset, 3481bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples, numSubSamples, 349ed555d70d80964f40563d89a4e6d6a80f83f4b89Jeff Tinker secure ? secureBufferId : dstPtr, 3505b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber &errorDetailMsg); 351c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 352ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 353fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply->writeInt32(result); 354ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 355ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker if (isCryptoError(result)) { 3565b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber reply->writeCString(errorDetailMsg.c_str()); 3575b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 3585b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 3591bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber if (!secure) { 360fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result >= 0) { 361fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong CHECK_LE(result, static_cast<ssize_t>(totalSize)); 362fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply->write(dstPtr, result); 3631bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 3641bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber free(dstPtr); 3651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dstPtr = NULL; 366ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 367ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3681bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete[] subSamples; 3691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples = NULL; 370ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 371ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 372ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 373ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3742514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker case NOTIFY_RESOLUTION: 3752514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker { 3762514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker CHECK_INTERFACE(ICrypto, data, reply); 3772514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 3782514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker int32_t width = data.readInt32(); 3792514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker int32_t height = data.readInt32(); 3802514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker notifyResolution(width, height); 3812514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 3822514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker return OK; 3832514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 3842514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 3851849570240443d1f75775c205fa658f7070849c6Jeff Tinker case SET_MEDIADRM_SESSION: 3861849570240443d1f75775c205fa658f7070849c6Jeff Tinker { 3871849570240443d1f75775c205fa658f7070849c6Jeff Tinker CHECK_INTERFACE(IDrm, data, reply); 3881849570240443d1f75775c205fa658f7070849c6Jeff Tinker Vector<uint8_t> sessionId; 3891849570240443d1f75775c205fa658f7070849c6Jeff Tinker readVector(data, sessionId); 3901849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->writeInt32(setMediaDrmSession(sessionId)); 3911849570240443d1f75775c205fa658f7070849c6Jeff Tinker return OK; 3921849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 3931849570240443d1f75775c205fa658f7070849c6Jeff Tinker 394ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber default: 395ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return BBinder::onTransact(code, data, reply, flags); 396ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 397ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 398ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 399ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} // namespace android 400