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

Commit 4c63a239 authored by Jeff Tinker's avatar Jeff Tinker
Browse files

MediaDrm API update

Clarify offline usage of sessions and keys and implement
implement CryptoSession to support additional crypto use
cases.

Change-Id: I5d8000ce7e1dd7eba08969fc50296c9e1456c4fc
parent 4fc3e841
Loading
Loading
Loading
Loading
+258 −21
Original line number Diff line number Diff line
@@ -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<uint8_t> const &sessionId,
    status_t MockDrmPlugin::getKeyRequest(Vector<uint8_t> const &sessionId,
                                          Vector<uint8_t> const &initData,
                                              String8 const &mimeType, LicenseType licenseType,
                                          String8 const &mimeType, KeyType keyType,
                                          KeyedVector<String8, String8> const &optionalParameters,
                                          Vector<uint8_t> &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<uint8_t> const &sessionId,
                                                   Vector<uint8_t> const &response)
    status_t MockDrmPlugin::provideKeyResponse(Vector<uint8_t> const &sessionId,
                                               Vector<uint8_t> const &response,
                                               Vector<uint8_t> &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<uint8_t> const &sessionId)
    status_t MockDrmPlugin::removeKeys(Vector<uint8_t> 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<uint8_t> const &sessionId,
                                        Vector<uint8_t> 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<uint8_t> const &sessionId,
    status_t MockDrmPlugin::queryKeyStatus(Vector<uint8_t> const &sessionId,
                                               KeyedVector<String8, String8> &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<uint8_t> 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<uint8_t> 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<uint8_t> const &sessionId,
                                    Vector<uint8_t> const &keyId,
                                    Vector<uint8_t> const &input,
                                    Vector<uint8_t> const &iv,
                                    Vector<uint8_t> &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<uint8_t> const &sessionId,
                                    Vector<uint8_t> const &keyId,
                                    Vector<uint8_t> const &input,
                                    Vector<uint8_t> const &iv,
                                    Vector<uint8_t> &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<uint8_t> const &sessionId,
                                 Vector<uint8_t> const &keyId,
                                 Vector<uint8_t> const &message,
                                 Vector<uint8_t> &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<uint8_t> const &sessionId,
                                   Vector<uint8_t> const &keyId,
                                   Vector<uint8_t> const &message,
                                   Vector<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> const &vector) const
    {
+45 −12
Original line number Diff line number Diff line
@@ -57,20 +57,22 @@ namespace android {
        status_t openSession(Vector<uint8_t> &sessionId);
        status_t closeSession(Vector<uint8_t> const &sessionId);

        status_t
            getLicenseRequest(Vector<uint8_t> const &sessionId,
        status_t getKeyRequest(Vector<uint8_t> const &sessionId,
                               Vector<uint8_t> const &initData,
                              String8 const &mimeType, LicenseType licenseType,
                               String8 const &mimeType, KeyType keyType,
                               KeyedVector<String8, String8> const &optionalParameters,
                               Vector<uint8_t> &request, String8 &defaultUrl);

        status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
                                                Vector<uint8_t> const &response);
        status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
                                    Vector<uint8_t> const &response,
                                    Vector<uint8_t> &keySetId);

        status_t removeLicense(Vector<uint8_t> const &sessionId);
        status_t removeKeys(Vector<uint8_t> const &keySetId);

        status_t
            queryLicenseStatus(Vector<uint8_t> const &sessionId,
        status_t restoreKeys(Vector<uint8_t> const &sessionId,
                             Vector<uint8_t> const &keySetId);

        status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
                                KeyedVector<String8, String8> &infoMap) const;

        status_t getProvisionRequest(Vector<uint8_t> &request,
@@ -90,15 +92,46 @@ namespace android {
        status_t setPropertyByteArray(String8 const &name,
                                      Vector<uint8_t> const &value );

        status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                    String8 const &algorithm);

        status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
                                 String8 const &algorithm);

        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);

        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);

        status_t sign(Vector<uint8_t> const &sessionId,
                      Vector<uint8_t> const &keyId,
                      Vector<uint8_t> const &message,
                      Vector<uint8_t> &signature);

        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);

    private:
        String8 vectorToString(Vector<uint8_t> const &vector) const;
        String8 arrayToString(uint8_t const *array, size_t len) const;
        String8 stringMapToString(KeyedVector<String8, String8> map) const;

        SortedVector<Vector<uint8_t> > mSessions;
        SortedVector<Vector<uint8_t> > mKeySets;

        static const ssize_t kNotFound = -1;
        ssize_t findSession(Vector<uint8_t> const &sessionId) const;
        ssize_t findKeySet(Vector<uint8_t> const &keySetId) const;

        Mutex mLock;
        KeyedVector<String8, String8> mStringProperties;
+49 −13
Original line number Diff line number Diff line
@@ -42,18 +42,22 @@ struct IDrm : public IInterface {
    virtual status_t closeSession(Vector<uint8_t> const &sessionId) = 0;

    virtual status_t
        getLicenseRequest(Vector<uint8_t> const &sessionId,
        getKeyRequest(Vector<uint8_t> const &sessionId,
                      Vector<uint8_t> const &initData,
                          String8 const &mimeType, DrmPlugin::LicenseType licenseType,
                      String8 const &mimeType, DrmPlugin::KeyType keyType,
                      KeyedVector<String8, String8> const &optionalParameters,
                      Vector<uint8_t> &request, String8 &defaultUrl) = 0;

    virtual status_t provideLicenseResponse(Vector<uint8_t> const &sessionId,
                                            Vector<uint8_t> const &response) = 0;
    virtual status_t provideKeyResponse(Vector<uint8_t> const &sessionId,
                                        Vector<uint8_t> const &response,
                                        Vector<uint8_t> &keySetId) = 0;

    virtual status_t removeLicense(Vector<uint8_t> const &sessionId) = 0;
    virtual status_t removeKeys(Vector<uint8_t> const &keySetId) = 0;

    virtual status_t queryLicenseStatus(Vector<uint8_t> const &sessionId,
    virtual status_t restoreKeys(Vector<uint8_t> const &sessionId,
                                 Vector<uint8_t> const &keySetId) = 0;

    virtual status_t queryKeyStatus(Vector<uint8_t> const &sessionId,
                                    KeyedVector<String8, String8> &infoMap) const = 0;

    virtual status_t getProvisionRequest(Vector<uint8_t> &request,
@@ -73,6 +77,35 @@ struct IDrm : public IInterface {
    virtual status_t setPropertyByteArray(String8 const &name,
                                          Vector<uint8_t> const &value) const = 0;

    virtual status_t setCipherAlgorithm(Vector<uint8_t> const &sessionId,
                                        String8 const &algorithm) = 0;

    virtual status_t setMacAlgorithm(Vector<uint8_t> const &sessionId,
                                     String8 const &algorithm) = 0;

    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) = 0;

    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) = 0;

    virtual status_t sign(Vector<uint8_t> const &sessionId,
                          Vector<uint8_t> const &keyId,
                          Vector<uint8_t> const &message,
                          Vector<uint8_t> &signature) = 0;

    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) = 0;

private:
    DISALLOW_EVIL_CONSTRUCTORS(IDrm);
};
@@ -81,6 +114,9 @@ struct BnDrm : public BnInterface<IDrm> {
    virtual status_t onTransact(
            uint32_t code, const Parcel &data, Parcel *reply,
            uint32_t flags = 0);
private:
    void readVector(const Parcel &data, Vector<uint8_t> &vector) const;
    void writeVector(Parcel *reply, Vector<uint8_t> const &vector) const;
};

}  // namespace android
+289 −119

File changed.

Preview size limit exceeded, changes collapsed.

+133 −15

File changed.

Preview size limit exceeded, changes collapsed.

Loading