diff --git a/drm/libmediadrm/CryptoHal.cpp b/drm/libmediadrm/CryptoHal.cpp index 6a0e75eca8..55b9bb883d 100644 --- a/drm/libmediadrm/CryptoHal.cpp +++ b/drm/libmediadrm/CryptoHal.cpp @@ -45,6 +45,7 @@ using ::android::hardware::hidl_handle; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; +using ::android::hardware::HidlMemory; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; @@ -255,10 +256,7 @@ 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. */ -int32_t CryptoHal::setHeapBase(const sp& heap) { - using ::android::hardware::fromHeap; - using ::android::hardware::HidlMemory; - +int32_t CryptoHal::setHeapBase(const sp& heap) { if (heap == NULL || mHeapSeqNum < 0) { ALOGE("setHeapBase(): heap %p mHeapSeqNum %d", heap.get(), mHeapSeqNum); return -1; @@ -268,9 +266,8 @@ int32_t CryptoHal::setHeapBase(const sp& heap) { int32_t seqNum = mHeapSeqNum++; uint32_t bufferId = static_cast(seqNum); - sp hidlMemory = fromHeap(heap); - mHeapBases.add(seqNum, HeapBase(bufferId, heap->getSize())); - Return hResult = mPlugin->setSharedBufferBase(*hidlMemory, bufferId); + mHeapSizes.add(seqNum, heap->size()); + Return hResult = mPlugin->setSharedBufferBase(*heap, bufferId); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); return seqNum; } @@ -285,64 +282,40 @@ void CryptoHal::clearHeapBase(int32_t seqNum) { * TODO: Add a releaseSharedBuffer method in a future DRM HAL * API version to make this explicit. */ - ssize_t index = mHeapBases.indexOfKey(seqNum); + ssize_t index = mHeapSizes.indexOfKey(seqNum); if (index >= 0) { if (mPlugin != NULL) { - uint32_t bufferId = mHeapBases[index].getBufferId(); + uint32_t bufferId = static_cast(seqNum); Return hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId); ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); } - mHeapBases.removeItem(seqNum); + mHeapSizes.removeItem(seqNum); } } -status_t CryptoHal::toSharedBuffer(const sp& memory, int32_t seqNum, ::SharedBuffer* buffer) { - ssize_t offset; - size_t size; - - if (memory == NULL || buffer == NULL) { - return UNEXPECTED_NULL; - } - - sp heap = memory->getMemory(&offset, &size); - if (heap == NULL) { - return UNEXPECTED_NULL; - } - +status_t CryptoHal::checkSharedBuffer(const ::SharedBuffer &buffer) { + int32_t seqNum = static_cast(buffer.bufferId); // memory must be in one of the heaps that have been set - if (mHeapBases.indexOfKey(seqNum) < 0) { + if (mHeapSizes.indexOfKey(seqNum) < 0) { return UNKNOWN_ERROR; } - // heap must be the same size as the one that was set in setHeapBase - if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) { - android_errorWriteLog(0x534e4554, "76221123"); - return UNKNOWN_ERROR; - } - // memory must be within the address space of the heap - // TODO: Using unsecurePointer() has some associated security pitfalls - // (see declaration for details). - // Either document why it is safe in this case or address the - // issue (e.g. by copying). - if (memory->unsecurePointer() != static_cast(heap->getBase()) + memory->offset() || - heap->getSize() < memory->offset() + memory->size() || - SIZE_MAX - memory->offset() < memory->size()) { + size_t heapSize = mHeapSizes.valueFor(seqNum); + if (heapSize < buffer.offset + buffer.size || + SIZE_MAX - buffer.offset < buffer.size) { android_errorWriteLog(0x534e4554, "76221123"); return UNKNOWN_ERROR; } - buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId(); - buffer->offset = offset >= 0 ? offset : 0; - buffer->size = size; return OK; } ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, - const ICrypto::SourceBuffer &source, size_t offset, + const ::SharedBuffer &hSource, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, - const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) { + const ::DestinationBuffer &hDestination, AString *errorDetailMsg) { Mutex::Autolock autoLock(mLock); if (mInitCheck != OK) { @@ -380,28 +353,21 @@ ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], } auto hSubSamples = hidl_vec(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, heapSeqNum, - &hDestination.nonsecureMemory); + if (hDestination.type == BufferType::SHARED_MEMORY) { + status_t status = checkSharedBuffer(hDestination.nonsecureMemory); if (status != OK) { return status; } secure = false; - } else if (destination.mType == kDestinationTypeNativeHandle) { - hDestination.type = BufferType::NATIVE_HANDLE; - hDestination.secureMemory = hidl_handle(destination.mHandle); + } else if (hDestination.type == BufferType::NATIVE_HANDLE) { secure = true; } else { android_errorWriteLog(0x534e4554, "70526702"); return UNKNOWN_ERROR; } - ::SharedBuffer hSource; - status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource); + status_t status = checkSharedBuffer(hSource); if (status != OK) { return status; } diff --git a/drm/libmediadrm/include/mediadrm/CryptoHal.h b/drm/libmediadrm/include/mediadrm/CryptoHal.h index 865ca38cc0..c9fda679b7 100644 --- a/drm/libmediadrm/include/mediadrm/CryptoHal.h +++ b/drm/libmediadrm/include/mediadrm/CryptoHal.h @@ -31,6 +31,9 @@ namespace drm = ::android::hardware::drm; using drm::V1_0::ICryptoFactory; using drm::V1_0::ICryptoPlugin; using drm::V1_0::SharedBuffer; +using drm::V1_0::DestinationBuffer; + +using ::android::hardware::HidlMemory; class IMemoryHeap; @@ -58,12 +61,12 @@ struct CryptoHal : public ICrypto { virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, - const ICrypto::SourceBuffer &source, size_t offset, + const ::SharedBuffer &source, size_t offset, const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, - const ICrypto::DestinationBuffer &destination, + const ::DestinationBuffer &destination, AString *errorDetailMsg); - virtual int32_t setHeap(const sp& heap) { + virtual int32_t setHeap(const sp& heap) { return setHeapBase(heap); } virtual void unsetHeap(int32_t seqNum) { clearHeapBase(seqNum); } @@ -83,30 +86,17 @@ private: */ status_t mInitCheck; - struct HeapBase { - HeapBase() : mBufferId(0), mSize(0) {} - HeapBase(uint32_t bufferId, size_t size) : - mBufferId(bufferId), mSize(size) {} - - uint32_t getBufferId() const {return mBufferId;} - size_t getSize() const {return mSize;} - - private: - uint32_t mBufferId; - size_t mSize; - }; - - KeyedVector mHeapBases; + KeyedVector mHeapSizes; int32_t mHeapSeqNum; Vector> makeCryptoFactories(); sp makeCryptoPlugin(const sp& factory, const uint8_t uuid[16], const void *initData, size_t size); - int32_t setHeapBase(const sp& heap); + int32_t setHeapBase(const sp& heap); void clearHeapBase(int32_t seqNum); - status_t toSharedBuffer(const sp& memory, int32_t seqNum, ::SharedBuffer* buffer); + status_t checkSharedBuffer(const ::SharedBuffer& buffer); DISALLOW_EVIL_CONSTRUCTORS(CryptoHal); }; diff --git a/drm/libmediadrm/interface/mediadrm/ICrypto.h b/drm/libmediadrm/interface/mediadrm/ICrypto.h index 48a0c443a4..df980aede5 100644 --- a/drm/libmediadrm/interface/mediadrm/ICrypto.h +++ b/drm/libmediadrm/interface/mediadrm/ICrypto.h @@ -24,11 +24,24 @@ #define ANDROID_ICRYPTO_H_ +namespace android { +namespace hardware { +class HidlMemory; +namespace drm { +namespace V1_0 { +struct SharedBuffer; +struct DestinationBuffer; +} // namespace V1_0 +} // namespace drm +} // namespace hardware +} // namespace android + +namespace drm = ::android::hardware::drm; +using drm::V1_0::SharedBuffer; + namespace android { struct AString; -class IMemory; -class IMemoryHeap; struct ICrypto : public RefBase { @@ -50,27 +63,16 @@ struct ICrypto : public RefBase { virtual status_t setMediaDrmSession(const Vector &sessionId) = 0; - struct SourceBuffer { - sp mSharedMemory; - int32_t mHeapSeqNum; - }; - enum DestinationType { kDestinationTypeSharedMemory, // non-secure kDestinationTypeNativeHandle // secure }; - struct DestinationBuffer { - DestinationType mType; - native_handle_t *mHandle; - sp mSharedMemory; - }; - - virtual ssize_t decrypt(const uint8_t key[16], const uint8_t iv[16], - CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, - const SourceBuffer &source, size_t offset, - const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, - const DestinationBuffer &destination, AString *errorDetailMsg) = 0; + virtual ssize_t decrypt(const uint8_t /*key*/[16], const uint8_t /*iv*/[16], + CryptoPlugin::Mode /*mode*/, const CryptoPlugin::Pattern &/*pattern*/, + const drm::V1_0::SharedBuffer &/*source*/, size_t /*offset*/, + const CryptoPlugin::SubSample * /*subSamples*/, size_t /*numSubSamples*/, + const drm::V1_0::DestinationBuffer &/*destination*/, AString * /*errorDetailMsg*/) = 0; /** * Declare the heap that the shared memory source buffers passed @@ -78,7 +80,7 @@ struct ICrypto : public RefBase { * that subsequent decrypt calls can use to refer to the heap, * with -1 indicating failure. */ - virtual int32_t setHeap(const sp& heap) = 0; + virtual int32_t setHeap(const sp& heap) = 0; virtual void unsetHeap(int32_t seqNum) = 0; protected: diff --git a/media/codec2/sfplugin/Android.bp b/media/codec2/sfplugin/Android.bp index e1747515d7..59ac94ba3b 100644 --- a/media/codec2/sfplugin/Android.bp +++ b/media/codec2/sfplugin/Android.bp @@ -27,6 +27,7 @@ cc_library_shared { shared_libs: [ "android.hardware.cas.native@1.0", + "android.hardware.drm@1.0", "android.hardware.media.c2@1.0", "android.hardware.media.omx@1.0", "libbase", diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp index d61b7513b4..39f3f3596c 100644 --- a/media/codec2/sfplugin/CCodecBufferChannel.cpp +++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp @@ -27,10 +27,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -52,10 +54,14 @@ using android::base::StringPrintf; using hardware::hidl_handle; using hardware::hidl_string; using hardware::hidl_vec; +using hardware::fromHeap; +using hardware::HidlMemory; + using namespace hardware::cas::V1_0; using namespace hardware::cas::native::V1_0; using CasStatus = hardware::cas::V1_0::Status; +using DrmBufferType = hardware::drm::V1_0::BufferType; namespace { @@ -431,15 +437,16 @@ status_t CCodecBufferChannel::queueSecureInputBuffer( ssize_t result = -1; ssize_t codecDataOffset = 0; if (mCrypto != nullptr) { - ICrypto::DestinationBuffer destination; + hardware::drm::V1_0::DestinationBuffer destination; if (secure) { - destination.mType = ICrypto::kDestinationTypeNativeHandle; - destination.mHandle = encryptedBuffer->handle(); + destination.type = DrmBufferType::NATIVE_HANDLE; + destination.secureMemory = hidl_handle(encryptedBuffer->handle()); } else { - destination.mType = ICrypto::kDestinationTypeSharedMemory; - destination.mSharedMemory = mDecryptDestination; + destination.type = DrmBufferType::SHARED_MEMORY; + IMemoryToSharedBuffer( + mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory); } - ICrypto::SourceBuffer source; + hardware::drm::V1_0::SharedBuffer source; encryptedBuffer->fillSourceBuffer(&source); result = mCrypto->decrypt( key, iv, mode, pattern, source, buffer->offset(), @@ -447,7 +454,7 @@ status_t CCodecBufferChannel::queueSecureInputBuffer( if (result < 0) { return result; } - if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { + if (destination.type == DrmBufferType::SHARED_MEMORY) { encryptedBuffer->copyDecryptedContent(mDecryptDestination, result); } } else { @@ -919,7 +926,8 @@ status_t CCodecBufferChannel::start( mDecryptDestination = mDealer->allocate((size_t)capacity); } if (mCrypto != nullptr && mHeapSeqNum < 0) { - mHeapSeqNum = mCrypto->setHeap(mDealer->getMemoryHeap()); + sp heap = fromHeap(mDealer->getMemoryHeap()); + mHeapSeqNum = mCrypto->setHeap(heap); } else { mHeapSeqNum = -1; } diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp index b339a922df..b6d18e212d 100644 --- a/media/codec2/sfplugin/Codec2Buffer.cpp +++ b/media/codec2/sfplugin/Codec2Buffer.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -779,9 +780,8 @@ std::shared_ptr EncryptedLinearBlockBuffer::asC2Buffer() { } void EncryptedLinearBlockBuffer::fillSourceBuffer( - ICrypto::SourceBuffer *source) { - source->mSharedMemory = mMemory; - source->mHeapSeqNum = mHeapSeqNum; + hardware::drm::V1_0::SharedBuffer *source) { + BufferChannelBase::IMemoryToSharedBuffer(mMemory, mHeapSeqNum, source); } void EncryptedLinearBlockBuffer::fillSourceBuffer( diff --git a/media/codec2/sfplugin/Codec2Buffer.h b/media/codec2/sfplugin/Codec2Buffer.h index 6f87101d52..9291c52f8e 100644 --- a/media/codec2/sfplugin/Codec2Buffer.h +++ b/media/codec2/sfplugin/Codec2Buffer.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -361,7 +362,8 @@ public: * * \param source source buffer structure to fill. */ - void fillSourceBuffer(ICrypto::SourceBuffer *source); + void fillSourceBuffer( + hardware::drm::V1_0::SharedBuffer *source); void fillSourceBuffer( hardware::cas::native::V1_0::SharedBuffer *source); diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp index dd6f7b42bd..aa4c22a00b 100644 --- a/media/libstagefright/ACodecBufferChannel.cpp +++ b/media/libstagefright/ACodecBufferChannel.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -41,6 +42,7 @@ using hardware::hidl_string; using hardware::hidl_vec; using namespace hardware::cas::V1_0; using namespace hardware::cas::native::V1_0; +using DrmBufferType = hardware::drm::V1_0::BufferType; using BufferInfo = ACodecBufferChannel::BufferInfo; using BufferInfoIterator = std::vector::const_iterator; @@ -131,18 +133,18 @@ status_t ACodecBufferChannel::queueSecureInputBuffer( ssize_t result = -1; ssize_t codecDataOffset = 0; if (mCrypto != NULL) { - ICrypto::DestinationBuffer destination; + hardware::drm::V1_0::DestinationBuffer destination; if (secure) { - destination.mType = ICrypto::kDestinationTypeNativeHandle; - destination.mHandle = secureHandle; + destination.type = DrmBufferType::NATIVE_HANDLE; + destination.secureMemory = hidl_handle(secureHandle); } else { - destination.mType = ICrypto::kDestinationTypeSharedMemory; - destination.mSharedMemory = mDecryptDestination; + destination.type = DrmBufferType::SHARED_MEMORY; + IMemoryToSharedBuffer( + mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory); } - ICrypto::SourceBuffer source; - source.mSharedMemory = it->mSharedEncryptedBuffer; - source.mHeapSeqNum = mHeapSeqNum; + hardware::drm::V1_0::SharedBuffer source; + IMemoryToSharedBuffer(it->mSharedEncryptedBuffer, mHeapSeqNum, &source); result = mCrypto->decrypt(key, iv, mode, pattern, source, it->mClientBuffer->offset(), @@ -152,9 +154,8 @@ status_t ACodecBufferChannel::queueSecureInputBuffer( return result; } - if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { - memcpy(it->mCodecBuffer->base(), - destination.mSharedMemory->unsecurePointer(), result); + if (destination.type == DrmBufferType::SHARED_MEMORY) { + memcpy(it->mCodecBuffer->base(), mDecryptDestination->unsecurePointer(), result); } } else { // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample @@ -315,7 +316,8 @@ sp ACodecBufferChannel::makeMemoryDealer(size_t heapSize) { } dealer = new MemoryDealer(heapSize, "ACodecBufferChannel"); if (mCrypto != nullptr) { - int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap()); + sp hHeap = fromHeap(dealer->getMemoryHeap()); + int32_t seqNum = mCrypto->setHeap(hHeap); if (seqNum >= 0) { mHeapSeqNum = seqNum; ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum); diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp index afd5017ab5..76eadf7012 100644 --- a/media/libstagefright/Android.bp +++ b/media/libstagefright/Android.bp @@ -252,6 +252,7 @@ cc_library { "libhidlmemory", "android.hidl.allocator@1.0", "android.hardware.cas.native@1.0", + "android.hardware.drm@1.0", "android.hardware.media.omx@1.0", ],