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

Commit 9ac86b3c authored by Jeff Tinker's avatar Jeff Tinker Committed by Lajos Molnar
Browse files

stagefright: ICrypto: enable passing secure buffers in native_handle

Previously secure buffers were passed as opaque
void * values, which no longer works since
mediadrmserver is now a separate process from
mediaserver.

Bug: 22990512
Change-Id: I5c458ba19e78e20d1bd5a5899df0bce16f71bfd8
parent aef47bf8
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -46,8 +46,14 @@ struct ICrypto : public IInterface {

    virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId) = 0;

    enum DestinationType {
        kDestinationTypeVmPointer,    // non-secure
        kDestinationTypeOpaqueHandle, // secure
        kDestinationTypeNativeHandle  // secure
    };

    virtual ssize_t decrypt(
            bool secure,
            DestinationType dstType,
            const uint8_t key[16],
            const uint8_t iv[16],
            CryptoPlugin::Mode mode,
+28 −10
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ struct BpCrypto : public BpInterface<ICrypto> {
    }

    virtual ssize_t decrypt(
            bool secure,
            DestinationType dstType,
            const uint8_t key[16],
            const uint8_t iv[16],
            CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
@@ -105,7 +105,7 @@ struct BpCrypto : public BpInterface<ICrypto> {
            AString *errorDetailMsg) {
        Parcel data, reply;
        data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
        data.writeInt32(secure);
        data.writeInt32((int32_t)dstType);
        data.writeInt32(mode);
        data.writeInt32(pattern.mEncryptBlocks);
        data.writeInt32(pattern.mSkipBlocks);
@@ -136,8 +136,12 @@ struct BpCrypto : public BpInterface<ICrypto> {
        data.writeInt32(numSubSamples);
        data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);

        if (secure) {
        if (dstType == kDestinationTypeNativeHandle) {
            data.writeNativeHandle(static_cast<native_handle_t *>(dstPtr));
        } else if (dstType == kDestinationTypeOpaqueHandle) {
            data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
        } else {
            dstType = kDestinationTypeVmPointer;
        }

        remote()->transact(DECRYPT, data, &reply);
@@ -148,7 +152,7 @@ struct BpCrypto : public BpInterface<ICrypto> {
            errorDetailMsg->setTo(reply.readCString());
        }

        if (!secure && result >= 0) {
        if (dstType == kDestinationTypeVmPointer && result >= 0) {
            reply.read(dstPtr, result);
        }

@@ -276,7 +280,7 @@ status_t BnCrypto::onTransact(
        {
            CHECK_INTERFACE(ICrypto, data, reply);

            bool secure = data.readInt32() != 0;
            DestinationType dstType = (DestinationType)data.readInt32();
            CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
            CryptoPlugin::Pattern pattern;
            pattern.mEncryptBlocks = data.readInt32();
@@ -306,10 +310,16 @@ status_t BnCrypto::onTransact(
                    subSamples,
                    sizeof(CryptoPlugin::SubSample) * numSubSamples);

            void *secureBufferId, *dstPtr;
            if (secure) {
            native_handle_t *nativeHandle = NULL;
            void *secureBufferId = NULL, *dstPtr;
            if (dstType == kDestinationTypeNativeHandle) {
                nativeHandle = data.readNativeHandle();
                dstPtr = static_cast<void *>(nativeHandle);
            } else if (dstType == kDestinationTypeOpaqueHandle) {
                secureBufferId = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
                dstPtr = secureBufferId;
            } else {
                dstType = kDestinationTypeVmPointer;
                dstPtr = malloc(totalSize);
            }

@@ -340,13 +350,13 @@ status_t BnCrypto::onTransact(
                result = -EINVAL;
            } else {
                result = decrypt(
                    secure,
                    dstType,
                    key,
                    iv,
                    mode, pattern,
                    sharedBuffer, offset,
                    subSamples, numSubSamples,
                    secure ? secureBufferId : dstPtr,
                    dstPtr,
                    &errorDetailMsg);
            }

@@ -356,13 +366,21 @@ status_t BnCrypto::onTransact(
                reply->writeCString(errorDetailMsg.c_str());
            }

            if (!secure) {
            if (dstType == kDestinationTypeVmPointer) {
                if (result >= 0) {
                    CHECK_LE(result, static_cast<ssize_t>(totalSize));
                    reply->write(dstPtr, result);
                }
                free(dstPtr);
                dstPtr = NULL;
            } else if (dstType == kDestinationTypeNativeHandle) {
                int err;
                if ((err = native_handle_close(nativeHandle)) < 0) {
                    ALOGW("secure buffer native_handle_close failed: %d", err);
                }
                if ((err = native_handle_delete(nativeHandle)) < 0) {
                    ALOGW("secure buffer native_handle_delete failed: %d", err);
                }
            }

            delete[] subSamples;
+3 −2
Original line number Diff line number Diff line
@@ -235,7 +235,7 @@ bool Crypto::requiresSecureDecoderComponent(const char *mime) const {
}

ssize_t Crypto::decrypt(
        bool secure,
        DestinationType dstType,
        const uint8_t key[16],
        const uint8_t iv[16],
        CryptoPlugin::Mode mode,
@@ -257,7 +257,8 @@ ssize_t Crypto::decrypt(
    const void *srcPtr = static_cast<uint8_t *>(sharedBuffer->pointer()) + offset;

    return mPlugin->decrypt(
            secure, key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
            dstType != kDestinationTypeVmPointer,
            key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
            errorDetailMsg);
}

+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ struct Crypto : public BnCrypto {
    virtual status_t setMediaDrmSession(const Vector<uint8_t> &sessionId);

    virtual ssize_t decrypt(
            bool secure,
            DestinationType dstType,
            const uint8_t key[16],
            const uint8_t iv[16],
            CryptoPlugin::Mode mode,
+11 −4
Original line number Diff line number Diff line
@@ -2494,11 +2494,18 @@ status_t MediaCodec::onQueueInputBuffer(const sp<AMessage> &msg) {
        AString *errorDetailMsg;
        CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));

        // TODO: use different decrypt based on native handle or not
        // use native handle if we have it; otherwise, use opaque handle
        void *dst_pointer = (void *)info->mNativeHandle.get() ? : info->mData->base();
        void *dst_pointer = info->mData->base();
        ICrypto::DestinationType dst_type = ICrypto::kDestinationTypeOpaqueHandle;

        if (info->mNativeHandle != NULL) {
            dst_pointer = (void *)info->mNativeHandle.get();
            dst_type = ICrypto::kDestinationTypeNativeHandle;
        } else if ((mFlags & kFlagIsSecure) == 0) {
            dst_type = ICrypto::kDestinationTypeVmPointer;
        }

        ssize_t result = mCrypto->decrypt(
                (mFlags & kFlagIsSecure) != 0,
                dst_type,
                key,
                iv,
                mode,