CryptoPlugin.cpp revision 1fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aa
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ClearKeyCryptoPlugin"
19#include <utils/Log.h>
20
21#include <media/stagefright/MediaErrors.h>
22#include <utils/Errors.h>
23
24#include "CryptoPlugin.h"
25
26namespace clearkeydrm {
27
28using android::Vector;
29using android::AString;
30using android::status_t;
31
32// Returns negative values for error code and positive values for the size of
33// decrypted data.  In theory, the output size can be larger than the input
34// size, but in practice this will never happen for AES-CTR.
35ssize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv,
36                              Mode mode, const void* srcPtr,
37                              const SubSample* subSamples, size_t numSubSamples,
38                              void* dstPtr, AString* errorDetailMsg) {
39    if (secure) {
40        errorDetailMsg->setTo("Secure decryption is not supported with "
41                              "ClearKey.");
42        return android::ERROR_DRM_CANNOT_HANDLE;
43    }
44
45    if (mode == kMode_Unencrypted) {
46        size_t offset = 0;
47        for (size_t i = 0; i < numSubSamples; ++i) {
48            const SubSample& subSample = subSamples[i];
49
50            if (subSample.mNumBytesOfEncryptedData != 0) {
51                errorDetailMsg->setTo(
52                        "Encrypted subsamples found in allegedly unencrypted "
53                        "data.");
54                return android::ERROR_DRM_DECRYPT;
55            }
56
57            if (subSample.mNumBytesOfClearData != 0) {
58                memcpy(reinterpret_cast<uint8_t*>(dstPtr) + offset,
59                       reinterpret_cast<const uint8_t*>(srcPtr) + offset,
60                       subSample.mNumBytesOfClearData);
61                offset += subSample.mNumBytesOfClearData;
62            }
63        }
64        return static_cast<ssize_t>(offset);
65    } else if (mode == kMode_AES_CTR) {
66        size_t bytesDecrypted;
67        status_t res = mSession->decrypt(keyId, iv, srcPtr, dstPtr, subSamples,
68                                         numSubSamples, &bytesDecrypted);
69        if (res == android::OK) {
70            return static_cast<ssize_t>(bytesDecrypted);
71        } else {
72            errorDetailMsg->setTo("Decryption Error");
73            return static_cast<ssize_t>(res);
74        }
75    } else {
76        errorDetailMsg->setTo(
77                "Selected encryption mode is not supported by the ClearKey DRM "
78                "Plugin.");
79        return android::ERROR_DRM_CANNOT_HANDLE;
80    }
81}
82
83}  // namespace clearkeydrm
84