ICrypto: use hidl memory instead of binder memory

Bug: 134787536
Test: GtsMediaTestCases
Change-Id: Ib20600eac13c668c8dc6a964faad1874844e4026
gugelfrei
Robert Shih 5 years ago
parent 5406f2634c
commit 895fba9a49

@ -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<IMemoryHeap>& heap) {
using ::android::hardware::fromHeap;
using ::android::hardware::HidlMemory;
int32_t CryptoHal::setHeapBase(const sp<HidlMemory>& 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<IMemoryHeap>& heap) {
int32_t seqNum = mHeapSeqNum++;
uint32_t bufferId = static_cast<uint32_t>(seqNum);
sp<HidlMemory> hidlMemory = fromHeap(heap);
mHeapBases.add(seqNum, HeapBase(bufferId, heap->getSize()));
Return<void> hResult = mPlugin->setSharedBufferBase(*hidlMemory, bufferId);
mHeapSizes.add(seqNum, heap->size());
Return<void> 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<uint32_t>(seqNum);
Return<void> 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<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) {
ssize_t offset;
size_t size;
if (memory == NULL || buffer == NULL) {
return UNEXPECTED_NULL;
}
sp<IMemoryHeap> heap = memory->getMemory(&offset, &size);
if (heap == NULL) {
return UNEXPECTED_NULL;
}
status_t CryptoHal::checkSharedBuffer(const ::SharedBuffer &buffer) {
int32_t seqNum = static_cast<int32_t>(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<uint8_t *>(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<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, 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;
}

@ -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<IMemoryHeap>& heap) {
virtual int32_t setHeap(const sp<HidlMemory>& 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<int32_t, HeapBase> mHeapBases;
KeyedVector<int32_t, size_t> mHeapSizes;
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);
int32_t setHeapBase(const sp<IMemoryHeap>& heap);
int32_t setHeapBase(const sp<HidlMemory>& heap);
void clearHeapBase(int32_t seqNum);
status_t toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer);
status_t checkSharedBuffer(const ::SharedBuffer& buffer);
DISALLOW_EVIL_CONSTRUCTORS(CryptoHal);
};

@ -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<uint8_t> &sessionId) = 0;
struct SourceBuffer {
sp<IMemory> mSharedMemory;
int32_t mHeapSeqNum;
};
enum DestinationType {
kDestinationTypeSharedMemory, // non-secure
kDestinationTypeNativeHandle // secure
};
struct DestinationBuffer {
DestinationType mType;
native_handle_t *mHandle;
sp<IMemory> 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<IMemoryHeap>& heap) = 0;
virtual int32_t setHeap(const sp<hardware::HidlMemory>& heap) = 0;
virtual void unsetHeap(int32_t seqNum) = 0;
protected:

@ -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",

@ -27,10 +27,12 @@
#include <C2Debug.h>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/drm/1.0/types.h>
#include <android-base/stringprintf.h>
#include <binder/MemoryDealer.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
#include <hidlmemory/FrameworkUtils.h>
#include <media/openmax/OMX_Core.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ALookup.h>
@ -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<HidlMemory> heap = fromHeap(mDealer->getMemoryHeap());
mHeapSeqNum = mCrypto->setHeap(heap);
} else {
mHeapSeqNum = -1;
}

@ -20,6 +20,7 @@
#include <hidlmemory/FrameworkUtils.h>
#include <media/hardware/HardwareAPI.h>
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
@ -779,9 +780,8 @@ std::shared_ptr<C2Buffer> 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(

@ -21,6 +21,7 @@
#include <C2Buffer.h>
#include <android/hardware/cas/native/1.0/types.h>
#include <android/hardware/drm/1.0/types.h>
#include <binder/IMemory.h>
#include <media/hardware/VideoAPI.h>
#include <media/stagefright/foundation/ABuffer.h>
@ -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);

@ -21,6 +21,7 @@
#include <numeric>
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android/hardware/drm/1.0/types.h>
#include <binder/MemoryDealer.h>
#include <hidlmemory/FrameworkUtils.h>
#include <media/openmax/OMX_Core.h>
@ -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 BufferInfo>::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<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) {
}
dealer = new MemoryDealer(heapSize, "ACodecBufferChannel");
if (mCrypto != nullptr) {
int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap());
sp<HidlMemory> hHeap = fromHeap(dealer->getMemoryHeap());
int32_t seqNum = mCrypto->setHeap(hHeap);
if (seqNum >= 0) {
mHeapSeqNum = seqNum;
ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);

@ -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",
],

Loading…
Cancel
Save