summaryrefslogtreecommitdiffstats
path: root/media/libmedia/IDrm.cpp
diff options
context:
space:
mode:
authorJeff Tinker <jtinker@google.com>2013-03-30 16:19:44 -0700
committerJeff Tinker <jtinker@google.com>2013-04-01 21:57:32 -0700
commit4c63a239c404af1e055e5f9939939ab0fd09d98a (patch)
tree5ec5bdcc0de9cb139df551a2b6e5c6010497e9ac /media/libmedia/IDrm.cpp
parent4fc3e841358164a661c78f78bc617f5ac879aa35 (diff)
downloadframeworks_av-4c63a239c404af1e055e5f9939939ab0fd09d98a.zip
frameworks_av-4c63a239c404af1e055e5f9939939ab0fd09d98a.tar.gz
frameworks_av-4c63a239c404af1e055e5f9939939ab0fd09d98a.tar.bz2
MediaDrm API update
Clarify offline usage of sessions and keys and implement implement CryptoSession to support additional crypto use cases. Change-Id: I5d8000ce7e1dd7eba08969fc50296c9e1456c4fc
Diffstat (limited to 'media/libmedia/IDrm.cpp')
-rw-r--r--media/libmedia/IDrm.cpp408
1 files changed, 289 insertions, 119 deletions
diff --git a/media/libmedia/IDrm.cpp b/media/libmedia/IDrm.cpp
index 3b13ec6..1641b56 100644
--- a/media/libmedia/IDrm.cpp
+++ b/media/libmedia/IDrm.cpp
@@ -33,10 +33,11 @@ enum {
DESTROY_PLUGIN,
OPEN_SESSION,
CLOSE_SESSION,
- GET_LICENSE_REQUEST,
- PROVIDE_LICENSE_RESPONSE,
- REMOVE_LICENSE,
- QUERY_LICENSE_STATUS,
+ GET_KEY_REQUEST,
+ PROVIDE_KEY_RESPONSE,
+ REMOVE_KEYS,
+ RESTORE_KEYS,
+ QUERY_KEY_STATUS,
GET_PROVISION_REQUEST,
PROVIDE_PROVISION_RESPONSE,
GET_SECURE_STOPS,
@@ -44,7 +45,13 @@ enum {
GET_PROPERTY_STRING,
GET_PROPERTY_BYTE_ARRAY,
SET_PROPERTY_STRING,
- SET_PROPERTY_BYTE_ARRAY
+ SET_PROPERTY_BYTE_ARRAY,
+ SET_CIPHER_ALGORITHM,
+ SET_MAC_ALGORITHM,
+ ENCRYPT,
+ DECRYPT,
+ SIGN,
+ VERIFY
};
struct BpDrm : public BpInterface<IDrm> {
@@ -92,9 +99,7 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
remote()->transact(OPEN_SESSION, data, &reply);
- uint32_t size = reply.readInt32();
- sessionId.insertAt((size_t)0, size);
- reply.read(sessionId.editArray(), size);
+ readVector(reply, sessionId);
return reply.readInt32();
}
@@ -103,80 +108,81 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(sessionId.size());
- data.write(sessionId.array(), sessionId.size());
+ writeVector(data, sessionId);
remote()->transact(CLOSE_SESSION, data, &reply);
return reply.readInt32();
}
virtual status_t
- getLicenseRequest(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &initData,
- String8 const &mimeType, DrmPlugin::LicenseType licenseType,
- KeyedVector<String8, String8> const &optionalParameters,
- Vector<uint8_t> &request, String8 &defaultUrl) {
+ getKeyRequest(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &initData,
+ String8 const &mimeType, DrmPlugin::KeyType keyType,
+ KeyedVector<String8, String8> const &optionalParameters,
+ Vector<uint8_t> &request, String8 &defaultUrl) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(sessionId.size());
- data.write(sessionId.array(), sessionId.size());
-
- data.writeInt32(initData.size());
- data.write(initData.array(), initData.size());
-
+ writeVector(data, sessionId);
+ writeVector(data, initData);
data.writeString8(mimeType);
- data.writeInt32((uint32_t)licenseType);
+ data.writeInt32((uint32_t)keyType);
data.writeInt32(optionalParameters.size());
for (size_t i = 0; i < optionalParameters.size(); ++i) {
data.writeString8(optionalParameters.keyAt(i));
data.writeString8(optionalParameters.valueAt(i));
}
- remote()->transact(GET_LICENSE_REQUEST, data, &reply);
+ remote()->transact(GET_KEY_REQUEST, data, &reply);
- uint32_t len = reply.readInt32();
- request.insertAt((size_t)0, len);
- reply.read(request.editArray(), len);
+ readVector(reply, request);
defaultUrl = reply.readString8();
return reply.readInt32();
}
- virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
- Vector<uint8_t> const &response) {
+ virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &response,
+ Vector<uint8_t> &keySetId) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+ writeVector(data, sessionId);
+ writeVector(data, response);
+ remote()->transact(PROVIDE_KEY_RESPONSE, data, &reply);
+ readVector(reply, keySetId);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t removeKeys(Vector<uint8_t> const &keySetId) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(sessionId.size());
- data.write(sessionId.array(), sessionId.size());
- data.writeInt32(response.size());
- data.write(response.array(), response.size());
- remote()->transact(PROVIDE_LICENSE_RESPONSE, data, &reply);
+ writeVector(data, keySetId);
+ remote()->transact(REMOVE_KEYS, data, &reply);
return reply.readInt32();
}
- virtual status_t removeLicense(Vector<uint8_t> const &sessionId) {
+ virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keySetId) {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(sessionId.size());
- data.write(sessionId.array(), sessionId.size());
- remote()->transact(REMOVE_LICENSE, data, &reply);
+ writeVector(data, sessionId);
+ writeVector(data, keySetId);
+ remote()->transact(RESTORE_KEYS, data, &reply);
return reply.readInt32();
}
- virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
+ virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
KeyedVector<String8, String8> &infoMap) const {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(sessionId.size());
- data.write(sessionId.array(), sessionId.size());
-
- remote()->transact(QUERY_LICENSE_STATUS, data, &reply);
+ writeVector(data, sessionId);
+ remote()->transact(QUERY_KEY_STATUS, data, &reply);
infoMap.clear();
size_t count = reply.readInt32();
@@ -195,9 +201,7 @@ struct BpDrm : public BpInterface<IDrm> {
remote()->transact(GET_PROVISION_REQUEST, data, &reply);
- uint32_t len = reply.readInt32();
- request.insertAt((size_t)0, len);
- reply.read(request.editArray(), len);
+ readVector(reply, request);
defaultUrl = reply.readString8();
return reply.readInt32();
@@ -207,8 +211,7 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(response.size());
- data.write(response.array(), response.size());
+ writeVector(data, response);
remote()->transact(PROVIDE_PROVISION_RESPONSE, data, &reply);
return reply.readInt32();
@@ -224,9 +227,7 @@ struct BpDrm : public BpInterface<IDrm> {
uint32_t count = reply.readInt32();
for (size_t i = 0; i < count; i++) {
Vector<uint8_t> secureStop;
- uint32_t len = reply.readInt32();
- secureStop.insertAt((size_t)0, len);
- reply.read(secureStop.editArray(), len);
+ readVector(reply, secureStop);
secureStops.push_back(secureStop);
}
return reply.readInt32();
@@ -236,8 +237,7 @@ struct BpDrm : public BpInterface<IDrm> {
Parcel data, reply;
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
- data.writeInt32(ssRelease.size());
- data.write(ssRelease.array(), ssRelease.size());
+ writeVector(data, ssRelease);
remote()->transact(RELEASE_SECURE_STOPS, data, &reply);
return reply.readInt32();
@@ -261,10 +261,7 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeString8(name);
remote()->transact(GET_PROPERTY_BYTE_ARRAY, data, &reply);
- uint32_t len = reply.readInt32();
- value.insertAt((size_t)0, len);
- reply.read(value.editArray(), len);
-
+ readVector(reply, value);
return reply.readInt32();
}
@@ -285,15 +282,120 @@ struct BpDrm : public BpInterface<IDrm> {
data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
data.writeString8(name);
- data.writeInt32(value.size());
- data.write(value.array(), value.size());
+ writeVector(data, value);
remote()->transact(SET_PROPERTY_BYTE_ARRAY, data, &reply);
return reply.readInt32();
}
+ virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ data.writeString8(algorithm);
+ remote()->transact(SET_CIPHER_ALGORITHM, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
+ String8 const &algorithm) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ data.writeString8(algorithm);
+ remote()->transact(SET_MAC_ALGORITHM, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual status_t encrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ writeVector(data, keyId);
+ writeVector(data, input);
+ writeVector(data, iv);
+
+ remote()->transact(ENCRYPT, data, &reply);
+ readVector(reply, output);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t decrypt(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &input,
+ Vector<uint8_t> const &iv,
+ Vector<uint8_t> &output) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ writeVector(data, keyId);
+ writeVector(data, input);
+ writeVector(data, iv);
+
+ remote()->transact(DECRYPT, data, &reply);
+ readVector(reply, output);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t sign(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> &signature) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ writeVector(data, keyId);
+ writeVector(data, message);
+
+ remote()->transact(SIGN, data, &reply);
+ readVector(reply, signature);
+
+ return reply.readInt32();
+ }
+
+ virtual status_t verify(Vector<uint8_t> const &sessionId,
+ Vector<uint8_t> const &keyId,
+ Vector<uint8_t> const &message,
+ Vector<uint8_t> const &signature,
+ bool &match) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDrm::getInterfaceDescriptor());
+
+ writeVector(data, sessionId);
+ writeVector(data, keyId);
+ writeVector(data, message);
+ writeVector(data, signature);
+
+ remote()->transact(VERIFY, data, &reply);
+ match = (bool)reply.readInt32();
+ return reply.readInt32();
+ }
+
private:
+ void readVector(Parcel &reply, Vector<uint8_t> &vector) const {
+ uint32_t size = reply.readInt32();
+ vector.insertAt((size_t)0, size);
+ reply.read(vector.editArray(), size);
+ }
+
+ void writeVector(Parcel &data, Vector<uint8_t> const &vector) const {
+ data.writeInt32(vector.size());
+ data.write(vector.array(), vector.size());
+ }
+
DISALLOW_EVIL_CONSTRUCTORS(BpDrm);
};
@@ -301,6 +403,17 @@ IMPLEMENT_META_INTERFACE(Drm, "android.drm.IDrm");
////////////////////////////////////////////////////////////////////////////////
+void BnDrm::readVector(const Parcel &data, Vector<uint8_t> &vector) const {
+ uint32_t size = data.readInt32();
+ vector.insertAt((size_t)0, size);
+ data.read(vector.editArray(), size);
+}
+
+void BnDrm::writeVector(Parcel *reply, Vector<uint8_t> const &vector) const {
+ reply->writeInt32(vector.size());
+ reply->write(vector.array(), vector.size());
+}
+
status_t BnDrm::onTransact(
uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
switch (code) {
@@ -341,8 +454,7 @@ status_t BnDrm::onTransact(
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> sessionId;
status_t result = openSession(sessionId);
- reply->writeInt32(sessionId.size());
- reply->write(sessionId.array(), sessionId.size());
+ writeVector(reply, sessionId);
reply->writeInt32(result);
return OK;
}
@@ -351,28 +463,20 @@ status_t BnDrm::onTransact(
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> sessionId;
- uint32_t size = data.readInt32();
- sessionId.insertAt((size_t)0, size);
- data.read(sessionId.editArray(), size);
+ readVector(data, sessionId);
reply->writeInt32(closeSession(sessionId));
return OK;
}
- case GET_LICENSE_REQUEST:
+ case GET_KEY_REQUEST:
{
CHECK_INTERFACE(IDrm, data, reply);
- Vector<uint8_t> sessionId;
- uint32_t size = data.readInt32();
- sessionId.insertAt((size_t)0, size);
- data.read(sessionId.editArray(), size);
-
- Vector<uint8_t> initData;
- size = data.readInt32();
- initData.insertAt((size_t)0, size);
- data.read(initData.editArray(), size);
+ Vector<uint8_t> sessionId, initData;
+ readVector(data, sessionId);
+ readVector(data, initData);
String8 mimeType = data.readString8();
- DrmPlugin::LicenseType licenseType = (DrmPlugin::LicenseType)data.readInt32();
+ DrmPlugin::KeyType keyType = (DrmPlugin::KeyType)data.readInt32();
KeyedVector<String8, String8> optionalParameters;
uint32_t count = data.readInt32();
@@ -386,55 +490,54 @@ status_t BnDrm::onTransact(
Vector<uint8_t> request;
String8 defaultUrl;
- status_t result = getLicenseRequest(sessionId, initData,
- mimeType, licenseType,
- optionalParameters,
- request, defaultUrl);
- reply->writeInt32(request.size());
- reply->write(request.array(), request.size());
+ status_t result = getKeyRequest(sessionId, initData,
+ mimeType, keyType,
+ optionalParameters,
+ request, defaultUrl);
+ writeVector(reply, request);
reply->writeString8(defaultUrl);
reply->writeInt32(result);
return OK;
}
- case PROVIDE_LICENSE_RESPONSE:
+ case PROVIDE_KEY_RESPONSE:
{
CHECK_INTERFACE(IDrm, data, reply);
- Vector<uint8_t> sessionId;
- uint32_t size = data.readInt32();
- sessionId.insertAt((size_t)0, size);
- data.read(sessionId.editArray(), size);
- Vector<uint8_t> response;
- size = data.readInt32();
- response.insertAt((size_t)0, size);
- data.read(response.editArray(), size);
+ Vector<uint8_t> sessionId, response, keySetId;
+ readVector(data, sessionId);
+ readVector(data, response);
+ uint32_t result = provideKeyResponse(sessionId, response, keySetId);
+ writeVector(reply, keySetId);
+ reply->writeInt32(result);
+ return OK;
+ }
- reply->writeInt32(provideLicenseResponse(sessionId, response));
+ case REMOVE_KEYS:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> keySetId;
+ readVector(data, keySetId);
+ reply->writeInt32(removeKeys(keySetId));
return OK;
}
- case REMOVE_LICENSE:
+ case RESTORE_KEYS:
{
CHECK_INTERFACE(IDrm, data, reply);
- Vector<uint8_t> sessionId;
- uint32_t size = data.readInt32();
- sessionId.insertAt((size_t)0, size);
- data.read(sessionId.editArray(), size);
- reply->writeInt32(removeLicense(sessionId));
+ Vector<uint8_t> sessionId, keySetId;
+ readVector(data, sessionId);
+ readVector(data, keySetId);
+ reply->writeInt32(restoreKeys(sessionId, keySetId));
return OK;
}
- case QUERY_LICENSE_STATUS:
+ case QUERY_KEY_STATUS:
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> sessionId;
- uint32_t size = data.readInt32();
- sessionId.insertAt((size_t)0, size);
- data.read(sessionId.editArray(), size);
+ readVector(data, sessionId);
KeyedVector<String8, String8> infoMap;
-
- status_t result = queryLicenseStatus(sessionId, infoMap);
-
+ status_t result = queryKeyStatus(sessionId, infoMap);
size_t count = infoMap.size();
reply->writeInt32(count);
for (size_t i = 0; i < count; ++i) {
@@ -451,8 +554,7 @@ status_t BnDrm::onTransact(
Vector<uint8_t> request;
String8 defaultUrl;
status_t result = getProvisionRequest(request, defaultUrl);
- reply->writeInt32(request.size());
- reply->write(request.array(), request.size());
+ writeVector(reply, request);
reply->writeString8(defaultUrl);
reply->writeInt32(result);
return OK;
@@ -462,11 +564,8 @@ status_t BnDrm::onTransact(
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> response;
- uint32_t size = data.readInt32();
- response.insertAt((size_t)0, size);
- data.read(response.editArray(), size);
+ readVector(data, response);
reply->writeInt32(provideProvisionResponse(response));
-
return OK;
}
@@ -491,9 +590,7 @@ status_t BnDrm::onTransact(
{
CHECK_INTERFACE(IDrm, data, reply);
Vector<uint8_t> ssRelease;
- uint32_t size = data.readInt32();
- ssRelease.insertAt((size_t)0, size);
- data.read(ssRelease.editArray(), size);
+ readVector(data, ssRelease);
reply->writeInt32(releaseSecureStops(ssRelease));
return OK;
}
@@ -515,8 +612,7 @@ status_t BnDrm::onTransact(
String8 name = data.readString8();
Vector<uint8_t> value;
status_t result = getPropertyByteArray(name, value);
- reply->writeInt32(value.size());
- reply->write(value.array(), value.size());
+ writeVector(reply, value);
reply->writeInt32(result);
return OK;
}
@@ -535,15 +631,89 @@ status_t BnDrm::onTransact(
CHECK_INTERFACE(IDrm, data, reply);
String8 name = data.readString8();
Vector<uint8_t> value;
- size_t count = data.readInt32();
- value.insertAt((size_t)0, count);
- data.read(value.editArray(), count);
+ readVector(data, value);
reply->writeInt32(setPropertyByteArray(name, value));
return OK;
}
- default:
- return BBinder::onTransact(code, data, reply, flags);
+ case SET_CIPHER_ALGORITHM:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId;
+ readVector(data, sessionId);
+ String8 algorithm = data.readString8();
+ reply->writeInt32(setCipherAlgorithm(sessionId, algorithm));
+ return OK;
+ }
+
+ case SET_MAC_ALGORITHM:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId;
+ readVector(data, sessionId);
+ String8 algorithm = data.readString8();
+ reply->writeInt32(setMacAlgorithm(sessionId, algorithm));
+ return OK;
+ }
+
+ case ENCRYPT:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, keyId, input, iv, output;
+ readVector(data, sessionId);
+ readVector(data, keyId);
+ readVector(data, input);
+ readVector(data, iv);
+ uint32_t result = encrypt(sessionId, keyId, input, iv, output);
+ writeVector(reply, output);
+ reply->writeInt32(result);
+ return OK;
+ }
+
+ case DECRYPT:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, keyId, input, iv, output;
+ readVector(data, sessionId);
+ readVector(data, keyId);
+ readVector(data, input);
+ readVector(data, iv);
+ uint32_t result = decrypt(sessionId, keyId, input, iv, output);
+ writeVector(reply, output);
+ reply->writeInt32(result);
+ return OK;
+ }
+
+ case SIGN:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, keyId, message, signature;
+ readVector(data, sessionId);
+ readVector(data, keyId);
+ readVector(data, message);
+ uint32_t result = sign(sessionId, keyId, message, signature);
+ writeVector(reply, signature);
+ reply->writeInt32(result);
+ return OK;
+ }
+
+ case VERIFY:
+ {
+ CHECK_INTERFACE(IDrm, data, reply);
+ Vector<uint8_t> sessionId, keyId, message, signature;
+ readVector(data, sessionId);
+ readVector(data, keyId);
+ readVector(data, message);
+ readVector(data, signature);
+ bool match;
+ uint32_t result = verify(sessionId, keyId, message, signature, match);
+ reply->writeInt32(match);
+ reply->writeInt32(result);
+ return OK;
+ }
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
}
}