1*4d7e907cSAndroid Build Coastguard Worker /* 2*4d7e907cSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*4d7e907cSAndroid Build Coastguard Worker * 4*4d7e907cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*4d7e907cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*4d7e907cSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*4d7e907cSAndroid Build Coastguard Worker * 8*4d7e907cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*4d7e907cSAndroid Build Coastguard Worker * 10*4d7e907cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*4d7e907cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*4d7e907cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*4d7e907cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*4d7e907cSAndroid Build Coastguard Worker * limitations under the License. 15*4d7e907cSAndroid Build Coastguard Worker */ 16*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "[email protected]" 17*4d7e907cSAndroid Build Coastguard Worker 18*4d7e907cSAndroid Build Coastguard Worker #include "CryptoPlugin.h" 19*4d7e907cSAndroid Build Coastguard Worker #include "TypeConvert.h" 20*4d7e907cSAndroid Build Coastguard Worker 21*4d7e907cSAndroid Build Coastguard Worker #include <android/hidl/memory/1.0/IMemory.h> 22*4d7e907cSAndroid Build Coastguard Worker #include <hidlmemory/mapping.h> 23*4d7e907cSAndroid Build Coastguard Worker #include <log/log.h> 24*4d7e907cSAndroid Build Coastguard Worker #include <media/stagefright/foundation/AString.h> 25*4d7e907cSAndroid Build Coastguard Worker 26*4d7e907cSAndroid Build Coastguard Worker using android::hardware::hidl_memory; 27*4d7e907cSAndroid Build Coastguard Worker using android::hidl::memory::V1_0::IMemory; 28*4d7e907cSAndroid Build Coastguard Worker 29*4d7e907cSAndroid Build Coastguard Worker namespace android { 30*4d7e907cSAndroid Build Coastguard Worker namespace hardware { 31*4d7e907cSAndroid Build Coastguard Worker namespace drm { 32*4d7e907cSAndroid Build Coastguard Worker namespace V1_0 { 33*4d7e907cSAndroid Build Coastguard Worker namespace implementation { 34*4d7e907cSAndroid Build Coastguard Worker 35*4d7e907cSAndroid Build Coastguard Worker // Methods from ::android::hardware::drm::V1_0::ICryptoPlugin follow requiresSecureDecoderComponent(const hidl_string & mime)36*4d7e907cSAndroid Build Coastguard Worker Return<bool> CryptoPlugin::requiresSecureDecoderComponent( 37*4d7e907cSAndroid Build Coastguard Worker const hidl_string& mime) { 38*4d7e907cSAndroid Build Coastguard Worker return mLegacyPlugin->requiresSecureDecoderComponent(mime.c_str()); 39*4d7e907cSAndroid Build Coastguard Worker } 40*4d7e907cSAndroid Build Coastguard Worker notifyResolution(uint32_t width,uint32_t height)41*4d7e907cSAndroid Build Coastguard Worker Return<void> CryptoPlugin::notifyResolution(uint32_t width, 42*4d7e907cSAndroid Build Coastguard Worker uint32_t height) { 43*4d7e907cSAndroid Build Coastguard Worker mLegacyPlugin->notifyResolution(width, height); 44*4d7e907cSAndroid Build Coastguard Worker return Void(); 45*4d7e907cSAndroid Build Coastguard Worker } 46*4d7e907cSAndroid Build Coastguard Worker setMediaDrmSession(const hidl_vec<uint8_t> & sessionId)47*4d7e907cSAndroid Build Coastguard Worker Return<Status> CryptoPlugin::setMediaDrmSession( 48*4d7e907cSAndroid Build Coastguard Worker const hidl_vec<uint8_t>& sessionId) { 49*4d7e907cSAndroid Build Coastguard Worker return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId))); 50*4d7e907cSAndroid Build Coastguard Worker } 51*4d7e907cSAndroid Build Coastguard Worker setSharedBufferBase(const hidl_memory & base,uint32_t bufferId)52*4d7e907cSAndroid Build Coastguard Worker Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base, 53*4d7e907cSAndroid Build Coastguard Worker uint32_t bufferId) { 54*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> hidlMemory = mapMemory(base); 55*4d7e907cSAndroid Build Coastguard Worker 56*4d7e907cSAndroid Build Coastguard Worker std::lock_guard<std::mutex> shared_buffer_lock(mSharedBufferLock); 57*4d7e907cSAndroid Build Coastguard Worker 58*4d7e907cSAndroid Build Coastguard Worker // allow mapMemory to return nullptr 59*4d7e907cSAndroid Build Coastguard Worker mSharedBufferMap[bufferId] = hidlMemory; 60*4d7e907cSAndroid Build Coastguard Worker return Void(); 61*4d7e907cSAndroid Build Coastguard Worker } 62*4d7e907cSAndroid Build Coastguard Worker decrypt(bool secure,const hidl_array<uint8_t,16> & keyId,const hidl_array<uint8_t,16> & iv,Mode mode,const Pattern & pattern,const hidl_vec<SubSample> & subSamples,const SharedBuffer & source,uint64_t offset,const DestinationBuffer & destination,decrypt_cb _hidl_cb)63*4d7e907cSAndroid Build Coastguard Worker Return<void> CryptoPlugin::decrypt(bool secure, 64*4d7e907cSAndroid Build Coastguard Worker const hidl_array<uint8_t, 16>& keyId, 65*4d7e907cSAndroid Build Coastguard Worker const hidl_array<uint8_t, 16>& iv, Mode mode, 66*4d7e907cSAndroid Build Coastguard Worker const Pattern& pattern, const hidl_vec<SubSample>& subSamples, 67*4d7e907cSAndroid Build Coastguard Worker const SharedBuffer& source, uint64_t offset, 68*4d7e907cSAndroid Build Coastguard Worker const DestinationBuffer& destination, 69*4d7e907cSAndroid Build Coastguard Worker decrypt_cb _hidl_cb) { 70*4d7e907cSAndroid Build Coastguard Worker std::unique_lock<std::mutex> shared_buffer_lock(mSharedBufferLock); 71*4d7e907cSAndroid Build Coastguard Worker if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { 72*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source decrypt buffer base not set"); 73*4d7e907cSAndroid Build Coastguard Worker return Void(); 74*4d7e907cSAndroid Build Coastguard Worker } 75*4d7e907cSAndroid Build Coastguard Worker 76*4d7e907cSAndroid Build Coastguard Worker if (destination.type == BufferType::SHARED_MEMORY) { 77*4d7e907cSAndroid Build Coastguard Worker const SharedBuffer& dest = destination.nonsecureMemory; 78*4d7e907cSAndroid Build Coastguard Worker if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) { 79*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination decrypt buffer base not set"); 80*4d7e907cSAndroid Build Coastguard Worker return Void(); 81*4d7e907cSAndroid Build Coastguard Worker } 82*4d7e907cSAndroid Build Coastguard Worker } 83*4d7e907cSAndroid Build Coastguard Worker 84*4d7e907cSAndroid Build Coastguard Worker android::CryptoPlugin::Mode legacyMode = android::CryptoPlugin::kMode_Unencrypted; 85*4d7e907cSAndroid Build Coastguard Worker switch(mode) { 86*4d7e907cSAndroid Build Coastguard Worker case Mode::UNENCRYPTED: 87*4d7e907cSAndroid Build Coastguard Worker legacyMode = android::CryptoPlugin::kMode_Unencrypted; 88*4d7e907cSAndroid Build Coastguard Worker break; 89*4d7e907cSAndroid Build Coastguard Worker case Mode::AES_CTR: 90*4d7e907cSAndroid Build Coastguard Worker legacyMode = android::CryptoPlugin::kMode_AES_CTR; 91*4d7e907cSAndroid Build Coastguard Worker break; 92*4d7e907cSAndroid Build Coastguard Worker case Mode::AES_CBC_CTS: 93*4d7e907cSAndroid Build Coastguard Worker legacyMode = android::CryptoPlugin::kMode_AES_WV; 94*4d7e907cSAndroid Build Coastguard Worker break; 95*4d7e907cSAndroid Build Coastguard Worker case Mode::AES_CBC: 96*4d7e907cSAndroid Build Coastguard Worker legacyMode = android::CryptoPlugin::kMode_AES_CBC; 97*4d7e907cSAndroid Build Coastguard Worker break; 98*4d7e907cSAndroid Build Coastguard Worker } 99*4d7e907cSAndroid Build Coastguard Worker android::CryptoPlugin::Pattern legacyPattern; 100*4d7e907cSAndroid Build Coastguard Worker legacyPattern.mEncryptBlocks = pattern.encryptBlocks; 101*4d7e907cSAndroid Build Coastguard Worker legacyPattern.mSkipBlocks = pattern.skipBlocks; 102*4d7e907cSAndroid Build Coastguard Worker 103*4d7e907cSAndroid Build Coastguard Worker std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples = 104*4d7e907cSAndroid Build Coastguard Worker std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size()); 105*4d7e907cSAndroid Build Coastguard Worker 106*4d7e907cSAndroid Build Coastguard Worker size_t destSize = 0; 107*4d7e907cSAndroid Build Coastguard Worker for (size_t i = 0; i < subSamples.size(); i++) { 108*4d7e907cSAndroid Build Coastguard Worker uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData; 109*4d7e907cSAndroid Build Coastguard Worker legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData; 110*4d7e907cSAndroid Build Coastguard Worker uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData; 111*4d7e907cSAndroid Build Coastguard Worker legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData; 112*4d7e907cSAndroid Build Coastguard Worker if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) { 113*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow"); 114*4d7e907cSAndroid Build Coastguard Worker return Void(); 115*4d7e907cSAndroid Build Coastguard Worker } 116*4d7e907cSAndroid Build Coastguard Worker if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) { 117*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow"); 118*4d7e907cSAndroid Build Coastguard Worker return Void(); 119*4d7e907cSAndroid Build Coastguard Worker } 120*4d7e907cSAndroid Build Coastguard Worker } 121*4d7e907cSAndroid Build Coastguard Worker 122*4d7e907cSAndroid Build Coastguard Worker AString detailMessage; 123*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId]; 124*4d7e907cSAndroid Build Coastguard Worker if (sourceBase == nullptr) { 125*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr"); 126*4d7e907cSAndroid Build Coastguard Worker return Void(); 127*4d7e907cSAndroid Build Coastguard Worker } 128*4d7e907cSAndroid Build Coastguard Worker 129*4d7e907cSAndroid Build Coastguard Worker size_t totalSize = 0; 130*4d7e907cSAndroid Build Coastguard Worker if (__builtin_add_overflow(source.offset, offset, &totalSize) || 131*4d7e907cSAndroid Build Coastguard Worker __builtin_add_overflow(totalSize, source.size, &totalSize) || 132*4d7e907cSAndroid Build Coastguard Worker totalSize > sourceBase->getSize()) { 133*4d7e907cSAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "176496160"); 134*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); 135*4d7e907cSAndroid Build Coastguard Worker return Void(); 136*4d7e907cSAndroid Build Coastguard Worker } 137*4d7e907cSAndroid Build Coastguard Worker 138*4d7e907cSAndroid Build Coastguard Worker uint8_t *base = static_cast<uint8_t *> 139*4d7e907cSAndroid Build Coastguard Worker (static_cast<void *>(sourceBase->getPointer())); 140*4d7e907cSAndroid Build Coastguard Worker void *srcPtr = static_cast<void *>(base + source.offset + offset); 141*4d7e907cSAndroid Build Coastguard Worker 142*4d7e907cSAndroid Build Coastguard Worker void *destPtr = NULL; 143*4d7e907cSAndroid Build Coastguard Worker if (destination.type == BufferType::SHARED_MEMORY) { 144*4d7e907cSAndroid Build Coastguard Worker const SharedBuffer& destBuffer = destination.nonsecureMemory; 145*4d7e907cSAndroid Build Coastguard Worker sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId]; 146*4d7e907cSAndroid Build Coastguard Worker if (destBase == nullptr) { 147*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); 148*4d7e907cSAndroid Build Coastguard Worker return Void(); 149*4d7e907cSAndroid Build Coastguard Worker } 150*4d7e907cSAndroid Build Coastguard Worker 151*4d7e907cSAndroid Build Coastguard Worker size_t totalSize = 0; 152*4d7e907cSAndroid Build Coastguard Worker if (__builtin_add_overflow(destBuffer.offset, destBuffer.size, &totalSize) || 153*4d7e907cSAndroid Build Coastguard Worker totalSize > destBase->getSize()) { 154*4d7e907cSAndroid Build Coastguard Worker android_errorWriteLog(0x534e4554, "176496353"); 155*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); 156*4d7e907cSAndroid Build Coastguard Worker return Void(); 157*4d7e907cSAndroid Build Coastguard Worker } 158*4d7e907cSAndroid Build Coastguard Worker 159*4d7e907cSAndroid Build Coastguard Worker if (destSize > destBuffer.size) { 160*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large"); 161*4d7e907cSAndroid Build Coastguard Worker return Void(); 162*4d7e907cSAndroid Build Coastguard Worker } 163*4d7e907cSAndroid Build Coastguard Worker 164*4d7e907cSAndroid Build Coastguard Worker base = static_cast<uint8_t *>(static_cast<void *>(destBase->getPointer())); 165*4d7e907cSAndroid Build Coastguard Worker destPtr = static_cast<void*>(base + destination.nonsecureMemory.offset); 166*4d7e907cSAndroid Build Coastguard Worker } else if (destination.type == BufferType::NATIVE_HANDLE) { 167*4d7e907cSAndroid Build Coastguard Worker if (!secure) { 168*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure"); 169*4d7e907cSAndroid Build Coastguard Worker return Void(); 170*4d7e907cSAndroid Build Coastguard Worker } 171*4d7e907cSAndroid Build Coastguard Worker native_handle_t *handle = const_cast<native_handle_t *>( 172*4d7e907cSAndroid Build Coastguard Worker destination.secureMemory.getNativeHandle()); 173*4d7e907cSAndroid Build Coastguard Worker destPtr = static_cast<void *>(handle); 174*4d7e907cSAndroid Build Coastguard Worker } else { 175*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(Status::BAD_VALUE, 0, "invalid destination type"); 176*4d7e907cSAndroid Build Coastguard Worker return Void(); 177*4d7e907cSAndroid Build Coastguard Worker } 178*4d7e907cSAndroid Build Coastguard Worker 179*4d7e907cSAndroid Build Coastguard Worker // release mSharedBufferLock 180*4d7e907cSAndroid Build Coastguard Worker shared_buffer_lock.unlock(); 181*4d7e907cSAndroid Build Coastguard Worker 182*4d7e907cSAndroid Build Coastguard Worker ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(), 183*4d7e907cSAndroid Build Coastguard Worker legacyMode, legacyPattern, srcPtr, legacySubSamples.get(), 184*4d7e907cSAndroid Build Coastguard Worker subSamples.size(), destPtr, &detailMessage); 185*4d7e907cSAndroid Build Coastguard Worker 186*4d7e907cSAndroid Build Coastguard Worker uint32_t status; 187*4d7e907cSAndroid Build Coastguard Worker uint32_t bytesWritten; 188*4d7e907cSAndroid Build Coastguard Worker 189*4d7e907cSAndroid Build Coastguard Worker if (result >= 0) { 190*4d7e907cSAndroid Build Coastguard Worker status = android::OK; 191*4d7e907cSAndroid Build Coastguard Worker bytesWritten = result; 192*4d7e907cSAndroid Build Coastguard Worker } else { 193*4d7e907cSAndroid Build Coastguard Worker status = result; 194*4d7e907cSAndroid Build Coastguard Worker bytesWritten = 0; 195*4d7e907cSAndroid Build Coastguard Worker } 196*4d7e907cSAndroid Build Coastguard Worker 197*4d7e907cSAndroid Build Coastguard Worker _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str()); 198*4d7e907cSAndroid Build Coastguard Worker return Void(); 199*4d7e907cSAndroid Build Coastguard Worker } 200*4d7e907cSAndroid Build Coastguard Worker 201*4d7e907cSAndroid Build Coastguard Worker } // namespace implementation 202*4d7e907cSAndroid Build Coastguard Worker } // namespace V1_0 203*4d7e907cSAndroid Build Coastguard Worker } // namespace drm 204*4d7e907cSAndroid Build Coastguard Worker } // namespace hardware 205*4d7e907cSAndroid Build Coastguard Worker } // namespace android 206