Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 #define LOG_TAG "android.hardware.drm (at) 1.0-impl"
     17 
     18 #include "CryptoPlugin.h"
     19 #include "TypeConvert.h"
     20 
     21 #include <android/hidl/memory/1.0/IMemory.h>
     22 #include <hidlmemory/mapping.h>
     23 #include <log/log.h>
     24 #include <media/stagefright/foundation/AString.h>
     25 
     26 using android::hardware::hidl_memory;
     27 using android::hidl::memory::V1_0::IMemory;
     28 
     29 namespace android {
     30 namespace hardware {
     31 namespace drm {
     32 namespace V1_0 {
     33 namespace implementation {
     34 
     35     // Methods from ::android::hardware::drm::V1_0::ICryptoPlugin follow
     36     Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
     37             const hidl_string& mime) {
     38         return mLegacyPlugin->requiresSecureDecoderComponent(mime.c_str());
     39     }
     40 
     41     Return<void> CryptoPlugin::notifyResolution(uint32_t width,
     42             uint32_t height) {
     43         mLegacyPlugin->notifyResolution(width, height);
     44         return Void();
     45     }
     46 
     47     Return<Status> CryptoPlugin::setMediaDrmSession(
     48             const hidl_vec<uint8_t>& sessionId) {
     49         return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
     50     }
     51 
     52     Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base,
     53             uint32_t bufferId) {
     54         mSharedBufferMap[bufferId] = mapMemory(base);
     55         return Void();
     56     }
     57 
     58     Return<void> CryptoPlugin::decrypt(bool secure,
     59             const hidl_array<uint8_t, 16>& keyId,
     60             const hidl_array<uint8_t, 16>& iv, Mode mode,
     61             const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
     62             const SharedBuffer& source, uint64_t offset,
     63             const DestinationBuffer& destination,
     64             decrypt_cb _hidl_cb) {
     65 
     66         if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
     67             _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set");
     68             return Void();
     69         }
     70 
     71         if (destination.type == BufferType::SHARED_MEMORY) {
     72             const SharedBuffer& dest = destination.nonsecureMemory;
     73             if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
     74                 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set");
     75                 return Void();
     76             }
     77         }
     78 
     79         android::CryptoPlugin::Mode legacyMode;
     80         switch(mode) {
     81         case Mode::UNENCRYPTED:
     82             legacyMode = android::CryptoPlugin::kMode_Unencrypted;
     83             break;
     84         case Mode::AES_CTR:
     85             legacyMode = android::CryptoPlugin::kMode_AES_CTR;
     86             break;
     87         case Mode::AES_CBC_CTS:
     88             legacyMode = android::CryptoPlugin::kMode_AES_WV;
     89             break;
     90         case Mode::AES_CBC:
     91             legacyMode = android::CryptoPlugin::kMode_AES_CBC;
     92             break;
     93         }
     94         android::CryptoPlugin::Pattern legacyPattern;
     95         legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
     96         legacyPattern.mSkipBlocks = pattern.skipBlocks;
     97 
     98         android::CryptoPlugin::SubSample *legacySubSamples =
     99             new android::CryptoPlugin::SubSample[subSamples.size()];
    100 
    101         for (size_t i = 0; i < subSamples.size(); i++) {
    102             legacySubSamples[i].mNumBytesOfClearData
    103                 = subSamples[i].numBytesOfClearData;
    104             legacySubSamples[i].mNumBytesOfEncryptedData
    105                 = subSamples[i].numBytesOfEncryptedData;
    106         }
    107 
    108         AString detailMessage;
    109         sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
    110 
    111         if (source.offset + offset + source.size > sourceBase->getSize()) {
    112             _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
    113             return Void();
    114         }
    115 
    116         uint8_t *base = static_cast<uint8_t *>
    117                 (static_cast<void *>(sourceBase->getPointer()));
    118         void *srcPtr = static_cast<void *>(base + source.offset + offset);
    119 
    120         void *destPtr = NULL;
    121         if (destination.type == BufferType::SHARED_MEMORY) {
    122             const SharedBuffer& destBuffer = destination.nonsecureMemory;
    123             sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
    124             if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
    125                 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
    126                 return Void();
    127             }
    128             destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
    129         } else if (destination.type == BufferType::NATIVE_HANDLE) {
    130             native_handle_t *handle = const_cast<native_handle_t *>(
    131                     destination.secureMemory.getNativeHandle());
    132             destPtr = static_cast<void *>(handle);
    133         }
    134         ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
    135                 legacyMode, legacyPattern, srcPtr, legacySubSamples,
    136                 subSamples.size(), destPtr, &detailMessage);
    137 
    138         delete[] legacySubSamples;
    139 
    140         uint32_t status;
    141         uint32_t bytesWritten;
    142 
    143         if (result >= 0) {
    144             status = android::OK;
    145             bytesWritten = result;
    146         } else {
    147             status = result;
    148             bytesWritten = 0;
    149         }
    150 
    151         _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
    152         return Void();
    153     }
    154 
    155 } // namespace implementation
    156 }  // namespace V1_0
    157 }  // namespace drm
    158 }  // namespace hardware
    159 }  // namespace android
    160