Loading drm/libmediadrm/CryptoHal.cpp +29 −17 Original line number Diff line number Diff line Loading @@ -105,7 +105,8 @@ static String8 toString8(hidl_string hString) { CryptoHal::CryptoHal() : mFactories(makeCryptoFactories()), mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT), mNextBufferId(0) { mNextBufferId(0), mHeapSeqNum(0) { } CryptoHal::~CryptoHal() { Loading Loading @@ -225,26 +226,37 @@ bool CryptoHal::requiresSecureDecoderComponent(const char *mime) const { * size. Once the heap base is established, shared memory buffers * are sent by providing an offset into the heap and a buffer size. */ void CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) { int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) { if (heap == NULL) { ALOGE("setHeapBase(): heap is NULL"); return -1; } native_handle_t* nativeHandle = native_handle_create(1, 0); if (!nativeHandle) { ALOGE("setSharedBufferBase(), failed to create native handle"); return; } if (heap == NULL) { ALOGE("setSharedBufferBase(): heap is NULL"); return; ALOGE("setHeapBase(), failed to create native handle"); return -1; } Mutex::Autolock autoLock(mLock); int32_t seqNum = mHeapSeqNum++; int fd = heap->getHeapID(); nativeHandle->data[0] = fd; auto hidlHandle = hidl_handle(nativeHandle); auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize()); mHeapBases.add(heap->getBase(), mNextBufferId); mHeapBases.add(seqNum, mNextBufferId); Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); return seqNum; } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer) { void CryptoHal::clearHeapBase(int32_t seqNum) { Mutex::Autolock autoLock(mLock); mHeapBases.removeItem(seqNum); } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) { ssize_t offset; size_t size; Loading @@ -257,11 +269,10 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* bu return UNEXPECTED_NULL; } if (mHeapBases.indexOfKey(heap->getBase()) < 0) { setHeapBase(heap); } // memory must be in the declared heap CHECK(mHeapBases.indexOfKey(seqNum) >= 0); buffer->bufferId = mHeapBases.valueFor(heap->getBase()); buffer->bufferId = mHeapBases.valueFor(seqNum); buffer->offset = offset >= 0 ? offset : 0; buffer->size = size; return OK; Loading @@ -269,7 +280,7 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* bu ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const ICrypto::SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) { Mutex::Autolock autoLock(mLock); Loading Loading @@ -309,11 +320,12 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], } auto hSubSamples = hidl_vec<SubSample>(stdSubSamples); int32_t heapSeqNum = source.mHeapSeqNum; bool secure; ::DestinationBuffer hDestination; if (destination.mType == kDestinationTypeSharedMemory) { hDestination.type = BufferType::SHARED_MEMORY; status_t status = toSharedBuffer(destination.mSharedMemory, status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum, &hDestination.nonsecureMemory); if (status != OK) { return status; Loading @@ -326,7 +338,7 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], } ::SharedBuffer hSource; status_t status = toSharedBuffer(source, &hSource); status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource); if (status != OK) { return status; } Loading drm/libmediadrm/ICrypto.cpp +55 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ enum { DECRYPT, NOTIFY_RESOLUTION, SET_MEDIADRM_SESSION, SET_HEAP, UNSET_HEAP, }; struct BpCrypto : public BpInterface<ICrypto> { Loading Loading @@ -96,7 +98,7 @@ struct BpCrypto : public BpInterface<ICrypto> { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg) { Parcel data, reply; Loading Loading @@ -125,7 +127,8 @@ struct BpCrypto : public BpInterface<ICrypto> { } data.writeInt32(totalSize); data.writeStrongBinder(IInterface::asBinder(source)); data.writeStrongBinder(IInterface::asBinder(source.mSharedMemory)); data.writeInt32(source.mHeapSeqNum); data.writeInt32(offset); data.writeInt32(numSubSamples); Loading Loading @@ -177,6 +180,30 @@ struct BpCrypto : public BpInterface<ICrypto> { return reply.readInt32(); } virtual int32_t setHeap(const sp<IMemoryHeap> &heap) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(heap)); status_t err = remote()->transact(SET_HEAP, data, &reply); if (err != NO_ERROR) { return -1; } int32_t seqNum; if (reply.readInt32(&seqNum) != NO_ERROR) { return -1; } return seqNum; } virtual void unsetHeap(int32_t seqNum) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInt32(seqNum); remote()->transact(UNSET_HEAP, data, &reply); return; } private: void readVector(Parcel &reply, Vector<uint8_t> &vector) const { uint32_t size = reply.readInt32(); Loading Loading @@ -295,12 +322,17 @@ status_t BnCrypto::onTransact( data.read(iv, sizeof(iv)); size_t totalSize = data.readInt32(); sp<IMemory> source = SourceBuffer source; source.mSharedMemory = interface_cast<IMemory>(data.readStrongBinder()); if (source == NULL) { if (source.mSharedMemory == NULL) { reply->writeInt32(BAD_VALUE); return OK; } source.mHeapSeqNum = data.readInt32(); int32_t offset = data.readInt32(); int32_t numSubSamples = data.readInt32(); Loading Loading @@ -353,9 +385,9 @@ status_t BnCrypto::onTransact( if (overflow || sumSubsampleSizes != totalSize) { result = -EINVAL; } else if (totalSize > source->size()) { } else if (totalSize > source.mSharedMemory->size()) { result = -EINVAL; } else if ((size_t)offset > source->size() - totalSize) { } else if ((size_t)offset > source.mSharedMemory->size() - totalSize) { result = -EINVAL; } else { result = decrypt(key, iv, mode, pattern, source, offset, Loading Loading @@ -404,6 +436,23 @@ status_t BnCrypto::onTransact( return OK; } case SET_HEAP: { CHECK_INTERFACE(ICrypto, data, reply); sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder()); reply->writeInt32(setHeap(heap)); return OK; } case UNSET_HEAP: { CHECK_INTERFACE(ICrypto, data, reply); int32_t seqNum = data.readInt32(); unsetHeap(seqNum); return OK; } default: return BBinder::onTransact(code, data, reply, flags); } Loading media/libmedia/include/Crypto.h +3 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ struct Crypto : public BnCrypto { const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg); virtual void setHeap(const sp<IMemoryHeap>&) {} virtual void unsetHeap(const sp<IMemoryHeap>&) {} private: mutable Mutex mLock; Loading media/libmedia/include/CryptoHal.h +11 −4 Original line number Diff line number Diff line Loading @@ -55,11 +55,16 @@ struct CryptoHal : public BnCrypto { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const ICrypto::SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg); virtual int32_t setHeap(const sp<IMemoryHeap>& heap) { return setHeapBase(heap); } virtual void unsetHeap(int32_t seqNum) { clearHeapBase(seqNum); } private: mutable Mutex mLock; Loading @@ -74,16 +79,18 @@ private: */ status_t mInitCheck; KeyedVector<void *, uint32_t> mHeapBases; KeyedVector<int32_t, uint32_t> mHeapBases; uint32_t mNextBufferId; int32_t mHeapSeqNum; Vector<sp<ICryptoFactory>> makeCryptoFactories(); sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory, const uint8_t uuid[16], const void *initData, size_t size); void setHeapBase(const sp<IMemoryHeap>& heap); int32_t setHeapBase(const sp<IMemoryHeap>& heap); void clearHeapBase(int32_t seqNum); status_t toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer); status_t toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer); DISALLOW_EVIL_CONSTRUCTORS(CryptoHal); }; Loading media/libmedia/include/ICrypto.h +16 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ namespace android { struct AString; class IMemory; class IMemoryHeap; struct ICrypto : public IInterface { DECLARE_META_INTERFACE(Crypto); Loading @@ -47,6 +48,11 @@ struct ICrypto : public IInterface { virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0; struct SourceBuffer { sp<IMemory> mSharedMemory; int32_t mHeapSeqNum; }; enum DestinationType { kDestinationTypeSharedMemory, // non-secure kDestinationTypeNativeHandle // secure Loading @@ -60,10 +66,19 @@ struct ICrypto : public IInterface { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg) = 0; /** * Declare the heap that the shared memory source buffers passed * to decrypt will be allocated from. Returns a sequence number * that subsequent decrypt calls can use to refer to the heap, * with -1 indicating failure. */ virtual int32_t setHeap(const sp<IMemoryHeap>& heap) = 0; virtual void unsetHeap(int32_t seqNum) = 0; private: DISALLOW_EVIL_CONSTRUCTORS(ICrypto); }; Loading Loading
drm/libmediadrm/CryptoHal.cpp +29 −17 Original line number Diff line number Diff line Loading @@ -105,7 +105,8 @@ static String8 toString8(hidl_string hString) { CryptoHal::CryptoHal() : mFactories(makeCryptoFactories()), mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT), mNextBufferId(0) { mNextBufferId(0), mHeapSeqNum(0) { } CryptoHal::~CryptoHal() { Loading Loading @@ -225,26 +226,37 @@ bool CryptoHal::requiresSecureDecoderComponent(const char *mime) const { * size. Once the heap base is established, shared memory buffers * are sent by providing an offset into the heap and a buffer size. */ void CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) { int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) { if (heap == NULL) { ALOGE("setHeapBase(): heap is NULL"); return -1; } native_handle_t* nativeHandle = native_handle_create(1, 0); if (!nativeHandle) { ALOGE("setSharedBufferBase(), failed to create native handle"); return; } if (heap == NULL) { ALOGE("setSharedBufferBase(): heap is NULL"); return; ALOGE("setHeapBase(), failed to create native handle"); return -1; } Mutex::Autolock autoLock(mLock); int32_t seqNum = mHeapSeqNum++; int fd = heap->getHeapID(); nativeHandle->data[0] = fd; auto hidlHandle = hidl_handle(nativeHandle); auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize()); mHeapBases.add(heap->getBase(), mNextBufferId); mHeapBases.add(seqNum, mNextBufferId); Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); return seqNum; } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer) { void CryptoHal::clearHeapBase(int32_t seqNum) { Mutex::Autolock autoLock(mLock); mHeapBases.removeItem(seqNum); } status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) { ssize_t offset; size_t size; Loading @@ -257,11 +269,10 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* bu return UNEXPECTED_NULL; } if (mHeapBases.indexOfKey(heap->getBase()) < 0) { setHeapBase(heap); } // memory must be in the declared heap CHECK(mHeapBases.indexOfKey(seqNum) >= 0); buffer->bufferId = mHeapBases.valueFor(heap->getBase()); buffer->bufferId = mHeapBases.valueFor(seqNum); buffer->offset = offset >= 0 ? offset : 0; buffer->size = size; return OK; Loading @@ -269,7 +280,7 @@ status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* bu ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const ICrypto::SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) { Mutex::Autolock autoLock(mLock); Loading Loading @@ -309,11 +320,12 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], } auto hSubSamples = hidl_vec<SubSample>(stdSubSamples); int32_t heapSeqNum = source.mHeapSeqNum; bool secure; ::DestinationBuffer hDestination; if (destination.mType == kDestinationTypeSharedMemory) { hDestination.type = BufferType::SHARED_MEMORY; status_t status = toSharedBuffer(destination.mSharedMemory, status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum, &hDestination.nonsecureMemory); if (status != OK) { return status; Loading @@ -326,7 +338,7 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], } ::SharedBuffer hSource; status_t status = toSharedBuffer(source, &hSource); status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource); if (status != OK) { return status; } Loading
drm/libmediadrm/ICrypto.cpp +55 −6 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ enum { DECRYPT, NOTIFY_RESOLUTION, SET_MEDIADRM_SESSION, SET_HEAP, UNSET_HEAP, }; struct BpCrypto : public BpInterface<ICrypto> { Loading Loading @@ -96,7 +98,7 @@ struct BpCrypto : public BpInterface<ICrypto> { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg) { Parcel data, reply; Loading Loading @@ -125,7 +127,8 @@ struct BpCrypto : public BpInterface<ICrypto> { } data.writeInt32(totalSize); data.writeStrongBinder(IInterface::asBinder(source)); data.writeStrongBinder(IInterface::asBinder(source.mSharedMemory)); data.writeInt32(source.mHeapSeqNum); data.writeInt32(offset); data.writeInt32(numSubSamples); Loading Loading @@ -177,6 +180,30 @@ struct BpCrypto : public BpInterface<ICrypto> { return reply.readInt32(); } virtual int32_t setHeap(const sp<IMemoryHeap> &heap) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(heap)); status_t err = remote()->transact(SET_HEAP, data, &reply); if (err != NO_ERROR) { return -1; } int32_t seqNum; if (reply.readInt32(&seqNum) != NO_ERROR) { return -1; } return seqNum; } virtual void unsetHeap(int32_t seqNum) { Parcel data, reply; data.writeInterfaceToken(ICrypto::getInterfaceDescriptor()); data.writeInt32(seqNum); remote()->transact(UNSET_HEAP, data, &reply); return; } private: void readVector(Parcel &reply, Vector<uint8_t> &vector) const { uint32_t size = reply.readInt32(); Loading Loading @@ -295,12 +322,17 @@ status_t BnCrypto::onTransact( data.read(iv, sizeof(iv)); size_t totalSize = data.readInt32(); sp<IMemory> source = SourceBuffer source; source.mSharedMemory = interface_cast<IMemory>(data.readStrongBinder()); if (source == NULL) { if (source.mSharedMemory == NULL) { reply->writeInt32(BAD_VALUE); return OK; } source.mHeapSeqNum = data.readInt32(); int32_t offset = data.readInt32(); int32_t numSubSamples = data.readInt32(); Loading Loading @@ -353,9 +385,9 @@ status_t BnCrypto::onTransact( if (overflow || sumSubsampleSizes != totalSize) { result = -EINVAL; } else if (totalSize > source->size()) { } else if (totalSize > source.mSharedMemory->size()) { result = -EINVAL; } else if ((size_t)offset > source->size() - totalSize) { } else if ((size_t)offset > source.mSharedMemory->size() - totalSize) { result = -EINVAL; } else { result = decrypt(key, iv, mode, pattern, source, offset, Loading Loading @@ -404,6 +436,23 @@ status_t BnCrypto::onTransact( return OK; } case SET_HEAP: { CHECK_INTERFACE(ICrypto, data, reply); sp<IMemoryHeap> heap = interface_cast<IMemoryHeap>(data.readStrongBinder()); reply->writeInt32(setHeap(heap)); return OK; } case UNSET_HEAP: { CHECK_INTERFACE(ICrypto, data, reply); int32_t seqNum = data.readInt32(); unsetHeap(seqNum); return OK; } default: return BBinder::onTransact(code, data, reply, flags); } Loading
media/libmedia/include/Crypto.h +3 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,9 @@ struct Crypto : public BnCrypto { const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg); virtual void setHeap(const sp<IMemoryHeap>&) {} virtual void unsetHeap(const sp<IMemoryHeap>&) {} private: mutable Mutex mLock; Loading
media/libmedia/include/CryptoHal.h +11 −4 Original line number Diff line number Diff line Loading @@ -55,11 +55,16 @@ struct CryptoHal : public BnCrypto { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const ICrypto::SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg); virtual int32_t setHeap(const sp<IMemoryHeap>& heap) { return setHeapBase(heap); } virtual void unsetHeap(int32_t seqNum) { clearHeapBase(seqNum); } private: mutable Mutex mLock; Loading @@ -74,16 +79,18 @@ private: */ status_t mInitCheck; KeyedVector<void *, uint32_t> mHeapBases; KeyedVector<int32_t, uint32_t> mHeapBases; uint32_t mNextBufferId; int32_t mHeapSeqNum; Vector<sp<ICryptoFactory>> makeCryptoFactories(); sp<ICryptoPlugin> makeCryptoPlugin(const sp<ICryptoFactory>& factory, const uint8_t uuid[16], const void *initData, size_t size); void setHeapBase(const sp<IMemoryHeap>& heap); int32_t setHeapBase(const sp<IMemoryHeap>& heap); void clearHeapBase(int32_t seqNum); status_t toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer); status_t toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer); DISALLOW_EVIL_CONSTRUCTORS(CryptoHal); }; Loading
media/libmedia/include/ICrypto.h +16 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ namespace android { struct AString; class IMemory; class IMemoryHeap; struct ICrypto : public IInterface { DECLARE_META_INTERFACE(Crypto); Loading @@ -47,6 +48,11 @@ struct ICrypto : public IInterface { virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0; struct SourceBuffer { sp<IMemory> mSharedMemory; int32_t mHeapSeqNum; }; enum DestinationType { kDestinationTypeSharedMemory, // non-secure kDestinationTypeNativeHandle // secure Loading @@ -60,10 +66,19 @@ struct ICrypto : public IInterface { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, const sp<IMemory> &source, size_t offset, const SourceBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, const DestinationBuffer &destination, AString *errorDetailMsg) = 0; /** * Declare the heap that the shared memory source buffers passed * to decrypt will be allocated from. Returns a sequence number * that subsequent decrypt calls can use to refer to the heap, * with -1 indicating failure. */ virtual int32_t setHeap(const sp<IMemoryHeap>& heap) = 0; virtual void unsetHeap(int32_t seqNum) = 0; private: DISALLOW_EVIL_CONSTRUCTORS(ICrypto); }; Loading