Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 895fba9a authored by Robert Shih's avatar Robert Shih
Browse files

ICrypto: use hidl memory instead of binder memory

Bug: 134787536
Test: GtsMediaTestCases
Change-Id: Ib20600eac13c668c8dc6a964faad1874844e4026
parent 5406f263
Loading
Loading
Loading
Loading
+19 −53
Original line number Diff line number Diff line
@@ -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) {
        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");
    if (mHeapSizes.indexOfKey(seqNum) < 0) {
        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;
    }
+9 −19
Original line number Diff line number Diff line
@@ -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);
};
+21 −19
Original line number Diff line number Diff line
@@ -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:
+1 −0
Original line number Diff line number Diff line
@@ -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",
+16 −8
Original line number Diff line number Diff line
@@ -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;
                }
Loading