Support AES-CBC sample encryption in MediaDrm
bug:23719082
Change-Id: I3028452f315122b65296881aed1fbf66c3ceeebc
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
index 53cbf80..6666343 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.cpp
@@ -33,7 +33,7 @@
// decrypted data. In theory, the output size can be larger than the input
// size, but in practice this will never happen for AES-CTR.
ssize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv,
- Mode mode, const void* srcPtr,
+ Mode mode, const Pattern &pattern, const void* srcPtr,
const SubSample* subSamples, size_t numSubSamples,
void* dstPtr, AString* errorDetailMsg) {
if (secure) {
diff --git a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
index fd38f28..de84c36 100644
--- a/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
+++ b/drm/mediadrm/plugins/clearkey/CryptoPlugin.h
@@ -44,7 +44,7 @@
virtual ssize_t decrypt(
bool secure, const KeyId keyId, const Iv iv,
- Mode mode, const void* srcPtr,
+ Mode mode, const Pattern &pattern, const void* srcPtr,
const SubSample* subSamples, size_t numSubSamples,
void* dstPtr, android::AString* errorDetailMsg);
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
index c856d7d..1e80f8e 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
@@ -792,15 +792,17 @@
ssize_t
MockCryptoPlugin::decrypt(bool secure, const uint8_t key[16], const uint8_t iv[16],
- Mode mode, const void *srcPtr, const SubSample *subSamples,
- size_t numSubSamples, void *dstPtr, AString * /* errorDetailMsg */)
+ Mode mode, const Pattern &pattern, const void *srcPtr,
+ const SubSample *subSamples, size_t numSubSamples,
+ void *dstPtr, AString * /* errorDetailMsg */)
{
- ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, src=%p, "
+ ALOGD("MockCryptoPlugin::decrypt(secure=%d, key=%s, iv=%s, mode=%d, "
+ "pattern:{encryptBlocks=%d, skipBlocks=%d} src=%p, "
"subSamples=%s, dst=%p)",
(int)secure,
arrayToString(key, sizeof(key)).string(),
arrayToString(iv, sizeof(iv)).string(),
- (int)mode, srcPtr,
+ (int)mode, pattern.mEncryptBlocks, pattern.mSkipBlocks, srcPtr,
subSamplesToString(subSamples, numSubSamples).string(),
dstPtr);
return OK;
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
index db266f9..40d4e84 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.h
@@ -159,7 +159,7 @@
ssize_t decrypt(bool secure,
const uint8_t key[16], const uint8_t iv[16],
- Mode mode, const void *srcPtr,
+ Mode mode, const Pattern &pattern, const void *srcPtr,
const SubSample *subSamples, size_t numSubSamples,
void *dstPtr, AString *errorDetailMsg);
private:
diff --git a/include/media/ICrypto.h b/include/media/ICrypto.h
index ea316de..5e324ad 100644
--- a/include/media/ICrypto.h
+++ b/include/media/ICrypto.h
@@ -51,6 +51,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index cdfa159..93ffa93 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -119,6 +119,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg = NULL);
diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h
index 4f6a1ef..034cb35 100644
--- a/include/ndk/NdkMediaCodec.h
+++ b/include/ndk/NdkMediaCodec.h
@@ -170,6 +170,11 @@
AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1
} cryptoinfo_mode_t;
+typedef struct {
+ int32_t encryptBlocks;
+ int32_t skipBlocks;
+} cryptoinfo_pattern_t;
+
/**
* Create an AMediaCodecCryptoInfo from scratch. Use this if you need to use custom
* crypto info, rather than one obtained from AMediaExtractor.
@@ -199,6 +204,13 @@
media_status_t AMediaCodecCryptoInfo_delete(AMediaCodecCryptoInfo*);
/**
+ * Set the crypto pattern on an AMediaCryptoInfo object
+ */
+void AMediaCodecCryptoInfo_setPattern(
+ AMediaCodecCryptoInfo *info,
+ cryptoinfo_pattern_t *pattern);
+
+/**
* The number of subsamples that make up the buffer's contents.
*/
size_t AMediaCodecCryptoInfo_getNumSubSamples(AMediaCodecCryptoInfo*);
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 433cb02..79059c6 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -98,7 +98,7 @@
bool secure,
const uint8_t key[16],
const uint8_t iv[16],
- CryptoPlugin::Mode mode,
+ CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
@@ -107,6 +107,8 @@
data.writeInterfaceToken(ICrypto::getInterfaceDescriptor());
data.writeInt32(secure);
data.writeInt32(mode);
+ data.writeInt32(pattern.mEncryptBlocks);
+ data.writeInt32(pattern.mSkipBlocks);
static const uint8_t kDummy[16] = { 0 };
@@ -276,6 +278,9 @@
bool secure = data.readInt32() != 0;
CryptoPlugin::Mode mode = (CryptoPlugin::Mode)data.readInt32();
+ CryptoPlugin::Pattern pattern;
+ pattern.mEncryptBlocks = data.readInt32();
+ pattern.mSkipBlocks = data.readInt32();
uint8_t key[16];
data.read(key, sizeof(key));
@@ -338,7 +343,7 @@
secure,
key,
iv,
- mode,
+ mode, pattern,
sharedBuffer, offset,
subSamples, numSubSamples,
secure ? secureBufferId : dstPtr,
diff --git a/media/libmediaplayerservice/Crypto.cpp b/media/libmediaplayerservice/Crypto.cpp
index 147d35f..b57f6ef 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/media/libmediaplayerservice/Crypto.cpp
@@ -239,6 +239,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
@@ -256,7 +257,7 @@
const void *srcPtr = static_cast<uint8_t *>(sharedBuffer->pointer()) + offset;
return mPlugin->decrypt(
- secure, key, iv, mode, srcPtr, subSamples, numSubSamples, dstPtr,
+ secure, key, iv, mode, pattern, srcPtr, subSamples, numSubSamples, dstPtr,
errorDetailMsg);
}
diff --git a/media/libmediaplayerservice/Crypto.h b/media/libmediaplayerservice/Crypto.h
index 99ea95d..7705f30 100644
--- a/media/libmediaplayerservice/Crypto.h
+++ b/media/libmediaplayerservice/Crypto.h
@@ -54,6 +54,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
const sp<IMemory> &sharedBuffer, size_t offset,
const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
void *dstPtr,
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8c61108..77722be 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -688,6 +688,7 @@
const uint8_t key[16],
const uint8_t iv[16],
CryptoPlugin::Mode mode,
+ const CryptoPlugin::Pattern &pattern,
int64_t presentationTimeUs,
uint32_t flags,
AString *errorDetailMsg) {
@@ -703,6 +704,8 @@
msg->setPointer("key", (void *)key);
msg->setPointer("iv", (void *)iv);
msg->setInt32("mode", mode);
+ msg->setInt32("encryptBlocks", pattern.mEncryptBlocks);
+ msg->setInt32("skipBlocks", pattern.mSkipBlocks);
msg->setInt64("timeUs", presentationTimeUs);
msg->setInt32("flags", flags);
msg->setPointer("errorDetailMsg", errorDetailMsg);
@@ -2452,11 +2455,16 @@
AString *errorDetailMsg;
CHECK(msg->findPointer("errorDetailMsg", (void **)&errorDetailMsg));
+ CryptoPlugin::Pattern pattern;
+ CHECK(msg->findInt32("encryptBlocks", (int32_t *)&pattern.mEncryptBlocks));
+ CHECK(msg->findInt32("skipBlocks", (int32_t *)&pattern.mSkipBlocks));
+
ssize_t result = mCrypto->decrypt(
(mFlags & kFlagIsSecure) != 0,
key,
iv,
mode,
+ pattern,
info->mSharedEncryptedBuffer,
offset,
subSamples,
diff --git a/media/ndk/NdkMediaCodec.cpp b/media/ndk/NdkMediaCodec.cpp
index cd0c462..8e36065 100644
--- a/media/ndk/NdkMediaCodec.cpp
+++ b/media/ndk/NdkMediaCodec.cpp
@@ -372,6 +372,7 @@
uint8_t key[16];
uint8_t iv[16];
cryptoinfo_mode_t mode;
+ cryptoinfo_pattern_t pattern;
size_t *clearbytes;
size_t *encryptedbytes;
} AMediaCodecCryptoInfo;
@@ -391,6 +392,10 @@
subSamples[i].mNumBytesOfEncryptedData = crypto->encryptedbytes[i];
}
+ CryptoPlugin::Pattern pattern;
+ pattern.mEncryptBlocks = crypto->pattern.encryptBlocks;
+ pattern.mSkipBlocks = crypto->pattern.skipBlocks;
+
AString errormsg;
status_t err = codec->mCodec->queueSecureInputBuffer(idx,
offset,
@@ -398,7 +403,8 @@
crypto->numsubsamples,
crypto->key,
crypto->iv,
- (CryptoPlugin::Mode) crypto->mode,
+ (CryptoPlugin::Mode)crypto->mode,
+ pattern,
time,
flags,
&errormsg);
@@ -410,6 +416,12 @@
}
+EXPORT
+void AMediaCodecCryptoInfo_setPattern(AMediaCodecCryptoInfo *info,
+ cryptoinfo_pattern_t *pattern) {
+ info->pattern.encryptBlocks = pattern->encryptBlocks;
+ info->pattern.skipBlocks = pattern->skipBlocks;
+}
EXPORT
AMediaCodecCryptoInfo *AMediaCodecCryptoInfo_new(
@@ -431,6 +443,8 @@
memcpy(ret->key, key, 16);
memcpy(ret->iv, iv, 16);
ret->mode = mode;
+ ret->pattern.encryptBlocks = 0;
+ ret->pattern.skipBlocks = 0;
// clearbytes and encryptedbytes point at the actual data, which follows
ret->clearbytes = (size_t*) (ret + 1); // point immediately after the struct