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
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index 5e324ad..a4bfaf8 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -46,8 +46,14 @@
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,
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 79059c6..26dd2c9 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -95,7 +95,7 @@
}
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 @@
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 @@
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 @@
errorDetailMsg->setTo(reply.readCString());
}
- if (!secure && result >= 0) {
+ if (dstType == kDestinationTypeVmPointer && result >= 0) {
reply.read(dstPtr, result);
}
@@ -276,7 +280,7 @@
{
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 @@
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 @@
result = -EINVAL;
} else {
result = decrypt(
- secure,
+ dstType,
key,
iv,
mode, pattern,
sharedBuffer, offset,
subSamples, numSubSamples,
- secure ? secureBufferId : dstPtr,
+ dstPtr,
&errorDetailMsg);
}
@@ -356,13 +366,21 @@
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;
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index b57f6ef..9165b9d 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -235,7 +235,7 @@
}
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 @@
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);
}
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 7705f30..7d181d3 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -50,7 +50,7 @@
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,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 1be9a3e..fb1f401 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2494,11 +2494,18 @@
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,