From 4c63a239c404af1e055e5f9939939ab0fd09d98a Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Sat, 30 Mar 2013 16:19:44 -0700 Subject: MediaDrm API update Clarify offline usage of sessions and keys and implement implement CryptoSession to support additional crypto use cases. Change-Id: I5d8000ce7e1dd7eba08969fc50296c9e1456c4fc --- drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp | 279 ++++++++++++++++++++-- 1 file changed, 258 insertions(+), 21 deletions(-) (limited to 'drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp') diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp index 91f5c9c..c34690b 100644 --- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp +++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp @@ -21,6 +21,7 @@ #include "drm/DrmAPI.h" #include "MockDrmCryptoPlugin.h" +#include "media/stagefright/MediaErrors.h" using namespace android; @@ -98,17 +99,17 @@ namespace android { } - status_t MockDrmPlugin::getLicenseRequest(Vector const &sessionId, - Vector const &initData, - String8 const &mimeType, LicenseType licenseType, - KeyedVector const &optionalParameters, - Vector &request, String8 &defaultUrl) + status_t MockDrmPlugin::getKeyRequest(Vector const &sessionId, + Vector const &initData, + String8 const &mimeType, KeyType keyType, + KeyedVector const &optionalParameters, + Vector &request, String8 &defaultUrl) { Mutex::Autolock lock(mLock); - ALOGD("MockDrmPlugin::getLicenseRequest(sessionId=%s, initData=%s, mimeType=%s" - ", licenseType=%d, optionalParameters=%s))", + ALOGD("MockDrmPlugin::getKeyRequest(sessionId=%s, initData=%s, mimeType=%s" + ", keyType=%d, optionalParameters=%s))", vectorToString(sessionId).string(), vectorToString(initData).string(), mimeType.string(), - licenseType, stringMapToString(optionalParameters).string()); + keyType, stringMapToString(optionalParameters).string()); ssize_t index = findSession(sessionId); if (index == kNotFound) { @@ -119,15 +120,15 @@ namespace android { // Properties used in mock test, set by mock plugin and verifed cts test app // byte[] initData -> mock-initdata // string mimeType -> mock-mimetype - // string licenseType -> mock-licensetype + // string keyType -> mock-keytype // string optionalParameters -> mock-optparams formatted as {key1,value1},{key2,value2} mByteArrayProperties.add(String8("mock-initdata"), initData); mStringProperties.add(String8("mock-mimetype"), mimeType); - String8 licenseTypeStr; - licenseTypeStr.appendFormat("%d", (int)licenseType); - mStringProperties.add(String8("mock-licensetype"), licenseTypeStr); + String8 keyTypeStr; + keyTypeStr.appendFormat("%d", (int)keyType); + mStringProperties.add(String8("mock-keytype"), keyTypeStr); String8 params; for (size_t i = 0; i < optionalParameters.size(); i++) { @@ -159,11 +160,12 @@ namespace android { return OK; } - status_t MockDrmPlugin::provideLicenseResponse(Vector const &sessionId, - Vector const &response) + status_t MockDrmPlugin::provideKeyResponse(Vector const &sessionId, + Vector const &response, + Vector &keySetId) { Mutex::Autolock lock(mLock); - ALOGD("MockDrmPlugin::provideLicenseResponse(sessionId=%s, response=%s)", + ALOGD("MockDrmPlugin::provideKeyResponse(sessionId=%s, response=%s)", vectorToString(sessionId).string(), vectorToString(response).string()); ssize_t index = findSession(sessionId); if (index == kNotFound) { @@ -176,30 +178,61 @@ namespace android { // Properties used in mock test, set by mock plugin and verifed cts test app // byte[] response -> mock-response - mByteArrayProperties.add(String8("mock-response"), response); + const size_t kKeySetIdSize = 8; + + for (size_t i = 0; i < kKeySetIdSize / sizeof(long); i++) { + long r = random(); + keySetId.appendArray((uint8_t *)&r, sizeof(long)); + } + mKeySets.add(keySetId); + return OK; } - status_t MockDrmPlugin::removeLicense(Vector const &sessionId) + status_t MockDrmPlugin::removeKeys(Vector const &keySetId) { Mutex::Autolock lock(mLock); - ALOGD("MockDrmPlugin::removeLicense(sessionId=%s)", - vectorToString(sessionId).string()); + ALOGD("MockDrmPlugin::removeKeys(keySetId=%s)", + vectorToString(keySetId).string()); + + ssize_t index = findKeySet(keySetId); + if (index == kNotFound) { + ALOGD("Invalid keySetId"); + return BAD_VALUE; + } + mKeySets.removeAt(index); + + return OK; + } + + status_t MockDrmPlugin::restoreKeys(Vector const &sessionId, + Vector const &keySetId) + { + Mutex::Autolock lock(mLock); + ALOGD("MockDrmPlugin::restoreKeys(sessionId=%s, keySetId=%s)", + vectorToString(sessionId).string(), + vectorToString(keySetId).string()); ssize_t index = findSession(sessionId); if (index == kNotFound) { ALOGD("Invalid sessionId"); return BAD_VALUE; } + index = findKeySet(keySetId); + if (index == kNotFound) { + ALOGD("Invalid keySetId"); + return BAD_VALUE; + } + return OK; } - status_t MockDrmPlugin::queryLicenseStatus(Vector const &sessionId, + status_t MockDrmPlugin::queryKeyStatus(Vector const &sessionId, KeyedVector &infoMap) const { - ALOGD("MockDrmPlugin::queryLicenseStatus(sessionId=%s)", + ALOGD("MockDrmPlugin::queryKeyStatus(sessionId=%s)", vectorToString(sessionId).string()); ssize_t index = findSession(sessionId); @@ -324,6 +357,198 @@ namespace android { return OK; } + status_t MockDrmPlugin::setCipherAlgorithm(Vector const &sessionId, + String8 const &algorithm) + { + Mutex::Autolock lock(mLock); + + ALOGD("MockDrmPlugin::setCipherAlgorithm(sessionId=%s, algorithm=%s)", + vectorToString(sessionId).string(), algorithm.string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + if (algorithm == "AES/CBC/NoPadding") { + return OK; + } + return BAD_VALUE; + } + + status_t MockDrmPlugin::setMacAlgorithm(Vector const &sessionId, + String8 const &algorithm) + { + Mutex::Autolock lock(mLock); + + ALOGD("MockDrmPlugin::setMacAlgorithm(sessionId=%s, algorithm=%s)", + vectorToString(sessionId).string(), algorithm.string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + if (algorithm == "HmacSHA256") { + return OK; + } + return BAD_VALUE; + } + + status_t MockDrmPlugin::encrypt(Vector const &sessionId, + Vector const &keyId, + Vector const &input, + Vector const &iv, + Vector &output) + { + Mutex::Autolock lock(mLock); + ALOGD("MockDrmPlugin::encrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", + vectorToString(sessionId).string(), + vectorToString(keyId).string(), + vectorToString(input).string(), + vectorToString(iv).string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + // Properties used in mock test, set by mock plugin and verifed cts test app + // byte[] keyId -> mock-keyid + // byte[] input -> mock-input + // byte[] iv -> mock-iv + mByteArrayProperties.add(String8("mock-keyid"), keyId); + mByteArrayProperties.add(String8("mock-input"), input); + mByteArrayProperties.add(String8("mock-iv"), iv); + + // Properties used in mock test, set by cts test app returned from mock plugin + // byte[] mock-output -> output + index = mByteArrayProperties.indexOfKey(String8("mock-output")); + if (index < 0) { + ALOGD("Missing 'mock-request' parameter for mock"); + return BAD_VALUE; + } else { + output = mByteArrayProperties.valueAt(index); + } + return OK; + } + + status_t MockDrmPlugin::decrypt(Vector const &sessionId, + Vector const &keyId, + Vector const &input, + Vector const &iv, + Vector &output) + { + Mutex::Autolock lock(mLock); + ALOGD("MockDrmPlugin::decrypt(sessionId=%s, keyId=%s, input=%s, iv=%s)", + vectorToString(sessionId).string(), + vectorToString(keyId).string(), + vectorToString(input).string(), + vectorToString(iv).string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + // Properties used in mock test, set by mock plugin and verifed cts test app + // byte[] keyId -> mock-keyid + // byte[] input -> mock-input + // byte[] iv -> mock-iv + mByteArrayProperties.add(String8("mock-keyid"), keyId); + mByteArrayProperties.add(String8("mock-input"), input); + mByteArrayProperties.add(String8("mock-iv"), iv); + + // Properties used in mock test, set by cts test app returned from mock plugin + // byte[] mock-output -> output + index = mByteArrayProperties.indexOfKey(String8("mock-output")); + if (index < 0) { + ALOGD("Missing 'mock-request' parameter for mock"); + return BAD_VALUE; + } else { + output = mByteArrayProperties.valueAt(index); + } + return OK; + } + + status_t MockDrmPlugin::sign(Vector const &sessionId, + Vector const &keyId, + Vector const &message, + Vector &signature) + { + Mutex::Autolock lock(mLock); + ALOGD("MockDrmPlugin::sign(sessionId=%s, keyId=%s, message=%s)", + vectorToString(sessionId).string(), + vectorToString(keyId).string(), + vectorToString(message).string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + // Properties used in mock test, set by mock plugin and verifed cts test app + // byte[] keyId -> mock-keyid + // byte[] message -> mock-message + mByteArrayProperties.add(String8("mock-keyid"), keyId); + mByteArrayProperties.add(String8("mock-message"), message); + + // Properties used in mock test, set by cts test app returned from mock plugin + // byte[] mock-signature -> signature + index = mByteArrayProperties.indexOfKey(String8("mock-signature")); + if (index < 0) { + ALOGD("Missing 'mock-request' parameter for mock"); + return BAD_VALUE; + } else { + signature = mByteArrayProperties.valueAt(index); + } + return OK; + } + + status_t MockDrmPlugin::verify(Vector const &sessionId, + Vector const &keyId, + Vector const &message, + Vector const &signature, + bool &match) + { + Mutex::Autolock lock(mLock); + ALOGD("MockDrmPlugin::verify(sessionId=%s, keyId=%s, message=%s, signature=%s)", + vectorToString(sessionId).string(), + vectorToString(keyId).string(), + vectorToString(message).string(), + vectorToString(signature).string()); + + ssize_t index = findSession(sessionId); + if (index == kNotFound) { + ALOGD("Invalid sessionId"); + return BAD_VALUE; + } + + // Properties used in mock test, set by mock plugin and verifed cts test app + // byte[] keyId -> mock-keyid + // byte[] message -> mock-message + // byte[] signature -> mock-signature + mByteArrayProperties.add(String8("mock-keyid"), keyId); + mByteArrayProperties.add(String8("mock-message"), message); + mByteArrayProperties.add(String8("mock-signature"), signature); + + // Properties used in mock test, set by cts test app returned from mock plugin + // String mock-match "1" or "0" -> match + index = mStringProperties.indexOfKey(String8("mock-match")); + if (index < 0) { + ALOGD("Missing 'mock-request' parameter for mock"); + return BAD_VALUE; + } else { + match = atol(mStringProperties.valueAt(index).string()); + } + return OK; + } + ssize_t MockDrmPlugin::findSession(Vector const &sessionId) const { ALOGD("findSession: nsessions=%d, size=%d", mSessions.size(), sessionId.size()); @@ -335,6 +560,18 @@ namespace android { return kNotFound; } + ssize_t MockDrmPlugin::findKeySet(Vector const &keySetId) const + { + ALOGD("findKeySet: nkeySets=%d, size=%d", mKeySets.size(), keySetId.size()); + for (size_t i = 0; i < mKeySets.size(); ++i) { + if (memcmp(mKeySets[i].array(), keySetId.array(), keySetId.size()) == 0) { + return i; + } + } + return kNotFound; + } + + // Conversion utilities String8 MockDrmPlugin::vectorToString(Vector const &vector) const { -- cgit v1.1