ICrypto.cpp revision 9ac86b3cae9a1e14b12bf97223ddde96142aae43
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( 989ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker DestinationType dstType, 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()); 1089ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker data.writeInt32((int32_t)dstType); 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 1399ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if (dstType == kDestinationTypeNativeHandle) { 1409ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr)); 1419ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } else if (dstType == kDestinationTypeOpaqueHandle) { 142bcca9e072c1f288a53ce6862936f57dc36488f96Jeff Tinker data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr))); 1439ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } else { 1449ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstType = kDestinationTypeVmPointer; 1451bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 146ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber remote()->transact(DECRYPT, data, &reply); 148ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 149fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong ssize_t result = reply.readInt32(); 150ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 151ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker if (isCryptoError(result)) { 1525b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber errorDetailMsg->setTo(reply.readCString()); 1535b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 1545b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 1559ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if (dstType == kDestinationTypeVmPointer && result >= 0) { 156fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply.read(dstPtr, result); 157ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 158ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 159fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong return result; 160ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 161ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 1622514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker virtual void notifyResolution( 1632514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker uint32_t width, uint32_t height) { 1642514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker Parcel data, reply; 1652514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 1662514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInt32(width); 1672514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker data.writeInt32(height); 1682514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker remote()->transact(NOTIFY_RESOLUTION, data, &reply); 1692514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 1702514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 1711849570240443d1f75775c205fa658f7070849c6Jeff Tinker virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) { 1721849570240443d1f75775c205fa658f7070849c6Jeff Tinker Parcel data, reply; 1731849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); 1741849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1751849570240443d1f75775c205fa658f7070849c6Jeff Tinker writeVector(data, sessionId); 1761849570240443d1f75775c205fa658f7070849c6Jeff Tinker remote()->transact(SET_MEDIADRM_SESSION, data, &reply); 1771849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1781849570240443d1f75775c205fa658f7070849c6Jeff Tinker return reply.readInt32(); 1791849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1801849570240443d1f75775c205fa658f7070849c6Jeff Tinker 181ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberprivate: 1821849570240443d1f75775c205fa658f7070849c6Jeff Tinker void readVector(Parcel &reply, Vector<uint8_t> &vector) const { 1831849570240443d1f75775c205fa658f7070849c6Jeff Tinker uint32_t size = reply.readInt32(); 1841849570240443d1f75775c205fa658f7070849c6Jeff Tinker vector.insertAt((size_t)0, size); 1851849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply.read(vector.editArray(), size); 1861849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1871849570240443d1f75775c205fa658f7070849c6Jeff Tinker 1881849570240443d1f75775c205fa658f7070849c6Jeff Tinker void writeVector(Parcel &data, Vector<uint8_t> const &vector) const { 1891849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.writeInt32(vector.size()); 1901849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.write(vector.array(), vector.size()); 1911849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 1921849570240443d1f75775c205fa658f7070849c6Jeff Tinker 193ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber DISALLOW_EVIL_CONSTRUCTORS(BpCrypto); 194ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber}; 195ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 196ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas HuberIMPLEMENT_META_INTERFACE(Crypto, "android.hardware.ICrypto"); 197ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 198ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber//////////////////////////////////////////////////////////////////////////////// 199ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2001849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::readVector(const Parcel &data, Vector<uint8_t> &vector) const { 2011849570240443d1f75775c205fa658f7070849c6Jeff Tinker uint32_t size = data.readInt32(); 2021849570240443d1f75775c205fa658f7070849c6Jeff Tinker vector.insertAt((size_t)0, size); 2031849570240443d1f75775c205fa658f7070849c6Jeff Tinker data.read(vector.editArray(), size); 2041849570240443d1f75775c205fa658f7070849c6Jeff Tinker} 2051849570240443d1f75775c205fa658f7070849c6Jeff Tinker 2061849570240443d1f75775c205fa658f7070849c6Jeff Tinkervoid BnCrypto::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const { 2071849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->writeInt32(vector.size()); 2081849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->write(vector.array(), vector.size()); 2091849570240443d1f75775c205fa658f7070849c6Jeff Tinker} 2101849570240443d1f75775c205fa658f7070849c6Jeff Tinker 211ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huberstatus_t BnCrypto::onTransact( 212ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { 213ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber switch (code) { 2141bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case INIT_CHECK: 215ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 216ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2171bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(initCheck()); 218ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 219ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 220ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 221ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2221bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case IS_CRYPTO_SUPPORTED: 223ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 224ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2251bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t uuid[16]; 2261bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(uuid, sizeof(uuid)); 2271bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(isCryptoSchemeSupported(uuid)); 228ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 229ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 230ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 231ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2321bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case CREATE_PLUGIN: 233ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 234ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 235ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2361bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t uuid[16]; 2371bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(uuid, sizeof(uuid)); 2381bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber 2391bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber size_t opaqueSize = data.readInt32(); 240705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber void *opaqueData = NULL; 241705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber 242705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber if (opaqueSize > 0) { 243705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber opaqueData = malloc(opaqueSize); 244705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber data.read(opaqueData, opaqueSize); 245705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber } 246ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2471bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize)); 248ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 249705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber if (opaqueData != NULL) { 250705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber free(opaqueData); 251705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber opaqueData = NULL; 252705868c0f2a6e85a39addefe4db9f2130627c219Andreas Huber } 253ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 254ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 255ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 256ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2571bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case DESTROY_PLUGIN: 258ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 2601bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber reply->writeInt32(destroyPlugin()); 261ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 262ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 263ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 264ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2651bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case REQUIRES_SECURE_COMPONENT: 266ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber { 267ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 268ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2691bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber const char *mime = data.readCString(); 2702afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia if (mime == NULL) { 2712afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(BAD_VALUE); 2722afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } else { 2732afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(requiresSecureDecoderComponent(mime)); 2742afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } 275ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2761bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber return OK; 2771bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 278ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2791bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber case DECRYPT: 2801bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber { 2811bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CHECK_INTERFACE(ICrypto, data, reply); 282ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2839ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker DestinationType dstType = (DestinationType)data.readInt32(); 2841bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32(); 28518cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker CryptoPlugin::Pattern pattern; 28618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker pattern.mEncryptBlocks = data.readInt32(); 28718cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker pattern.mSkipBlocks = data.readInt32(); 288ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2891bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t key[16]; 2901bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(key, sizeof(key)); 291ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2921bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber uint8_t iv[16]; 2931bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read(iv, sizeof(iv)); 294ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 2951bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber size_t totalSize = data.readInt32(); 296c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sp<IMemory> sharedBuffer = 297c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker interface_cast<IMemory>(data.readStrongBinder()); 2982afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia if (sharedBuffer == NULL) { 2992afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia reply->writeInt32(BAD_VALUE); 3002afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia return OK; 3012afac0c7c42560ff5b8f133c6074b7e023279d6dWei Jia } 302c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker int32_t offset = data.readInt32(); 303ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3041bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber int32_t numSubSamples = data.readInt32(); 305ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3061bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber CryptoPlugin::SubSample *subSamples = 3071bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber new CryptoPlugin::SubSample[numSubSamples]; 308ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3091bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber data.read( 3101bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples, 3111bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber sizeof(CryptoPlugin::SubSample) * numSubSamples); 312ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3139ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker native_handle_t *nativeHandle = NULL; 3149ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker void *secureBufferId = NULL, *dstPtr; 3159ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if (dstType == kDestinationTypeNativeHandle) { 3169ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker nativeHandle = data.readNativeHandle(); 3179ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstPtr = static_cast<void *>(nativeHandle); 3189ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } else if (dstType == kDestinationTypeOpaqueHandle) { 319ed555d70d80964f40563d89a4e6d6a80f83f4b89Jeff Tinker secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64())); 3209ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstPtr = secureBufferId; 3211bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } else { 3229ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstType = kDestinationTypeVmPointer; 3231bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dstPtr = malloc(totalSize); 324ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 325ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3265b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber AString errorDetailMsg; 327c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker ssize_t result; 328c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker 329c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker size_t sumSubsampleSizes = 0; 330c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker bool overflow = false; 331c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker for (int32_t i = 0; i < numSubSamples; ++i) { 332c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker CryptoPlugin::SubSample &ss = subSamples[i]; 333c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfEncryptedData) { 334c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker sumSubsampleSizes += ss.mNumBytesOfEncryptedData; 335c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } else { 336c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker overflow = true; 337c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 338c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (sumSubsampleSizes <= SIZE_MAX - ss.mNumBytesOfClearData) { 339c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker sumSubsampleSizes += ss.mNumBytesOfClearData; 340c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } else { 341c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker overflow = true; 342c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 343c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker } 344c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker 345c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker if (overflow || sumSubsampleSizes != totalSize) { 346c6fc6a3ca618b0e72ee565ded2e4960797f53fa6Jeff Tinker result = -EINVAL; 347bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker } else if (totalSize > sharedBuffer->size()) { 348bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker result = -EINVAL; 349bb4877d143c6c7ec9b42e3c490fed58af4f39deaJeff Tinker } else if ((size_t)offset > sharedBuffer->size() - totalSize) { 350c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker result = -EINVAL; 351c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } else { 352c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker result = decrypt( 3539ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstType, 3541bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber key, 3551bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber iv, 35618cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker mode, pattern, 357c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker sharedBuffer, offset, 3581bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples, numSubSamples, 3599ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker dstPtr, 3605b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber &errorDetailMsg); 361c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker } 362ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 363fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply->writeInt32(result); 364ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 365ceffd8cc911bd2e685b525f838cd3d8198ab35cfJeff Tinker if (isCryptoError(result)) { 3665b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber reply->writeCString(errorDetailMsg.c_str()); 3675b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber } 3685b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber 3699ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if (dstType == kDestinationTypeVmPointer) { 370fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong if (result >= 0) { 371fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong CHECK_LE(result, static_cast<ssize_t>(totalSize)); 372fa2b8f243eb048fb2b8e5a14356190f69eb31a36Edwin Wong reply->write(dstPtr, result); 3731bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber } 3741bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber free(dstPtr); 3751bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber dstPtr = NULL; 3769ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } else if (dstType == kDestinationTypeNativeHandle) { 3779ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker int err; 3789ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if ((err = native_handle_close(nativeHandle)) < 0) { 3799ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker ALOGW("secure buffer native_handle_close failed: %d", err); 3809ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } 3819ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker if ((err = native_handle_delete(nativeHandle)) < 0) { 3829ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker ALOGW("secure buffer native_handle_delete failed: %d", err); 3839ac86b3cae9a1e14b12bf97223ddde96142aae43Jeff Tinker } 384ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 385ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3861bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber delete[] subSamples; 3871bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huber subSamples = NULL; 388ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 389ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return OK; 390ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 391ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 3922514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker case NOTIFY_RESOLUTION: 3932514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker { 3942514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker CHECK_INTERFACE(ICrypto, data, reply); 3952514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 3962514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker int32_t width = data.readInt32(); 3972514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker int32_t height = data.readInt32(); 3982514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker notifyResolution(width, height); 3992514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 4002514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker return OK; 4012514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker } 4022514d080c8a54ff603a45d7e336de668fe7329dbJeff Tinker 4031849570240443d1f75775c205fa658f7070849c6Jeff Tinker case SET_MEDIADRM_SESSION: 4041849570240443d1f75775c205fa658f7070849c6Jeff Tinker { 4051849570240443d1f75775c205fa658f7070849c6Jeff Tinker CHECK_INTERFACE(IDrm, data, reply); 4061849570240443d1f75775c205fa658f7070849c6Jeff Tinker Vector<uint8_t> sessionId; 4071849570240443d1f75775c205fa658f7070849c6Jeff Tinker readVector(data, sessionId); 4081849570240443d1f75775c205fa658f7070849c6Jeff Tinker reply->writeInt32(setMediaDrmSession(sessionId)); 4091849570240443d1f75775c205fa658f7070849c6Jeff Tinker return OK; 4101849570240443d1f75775c205fa658f7070849c6Jeff Tinker } 4111849570240443d1f75775c205fa658f7070849c6Jeff Tinker 412ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber default: 413ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber return BBinder::onTransact(code, data, reply, flags); 414ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber } 415ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} 416ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber 417ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber} // namespace android 418