11917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker/* 21917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Copyright (C) 2018 The Android Open Source Project 31917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * 41917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License"); 51917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * you may not use this file except in compliance with the License. 61917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * You may obtain a copy of the License at 71917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * 81917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * http://www.apache.org/licenses/LICENSE-2.0 91917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * 101917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Unless required by applicable law or agreed to in writing, software 111917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS, 121917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * See the License for the specific language governing permissions and 141917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * limitations under the License. 151917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker */ 161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 171917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker//#define LOG_NDEBUG 0 181917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#define LOG_TAG "hidl_ClearKeyCryptoPlugin" 191917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include <utils/Log.h> 201917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 211917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "CryptoPlugin.h" 221917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "SessionLibrary.h" 231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "TypeConvert.h" 241917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 251917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include <hidlmemory/mapping.h> 261917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace android { 281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace hardware { 291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace drm { 301917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace V1_1 { 311917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace clearkey { 321917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerusing ::android::hardware::drm::V1_0::BufferType; 341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 351917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<void> CryptoPlugin::setSharedBufferBase( 361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const hidl_memory& base, uint32_t bufferId) { 371917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker sp<IMemory> hidlMemory = mapMemory(base); 381917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr"); 391917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 401917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker // allow mapMemory to return nullptr 411917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker mSharedBufferMap[bufferId] = hidlMemory; 421917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 431917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} 441917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 451917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// Returns negative values for error code and positive values for the size of 461917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// decrypted data. In theory, the output size can be larger than the input 471917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// size, but in practice this will never happen for AES-CTR. 481917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<void> CryptoPlugin::decrypt( 491917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker bool secure, 501917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const hidl_array<uint8_t, KEY_ID_SIZE>& keyId, 511917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const hidl_array<uint8_t, KEY_IV_SIZE>& iv, 521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker Mode mode, 531917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const Pattern& pattern, 541917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const hidl_vec<SubSample>& subSamples, 551917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const SharedBuffer& source, 561917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker uint64_t offset, 571917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const DestinationBuffer& destination, 581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker decrypt_cb _hidl_cb) { 591917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker UNUSED(pattern); 601917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 611917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (secure) { 621917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, 631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "Secure decryption is not supported with ClearKey."); 641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 651917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 661917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 671917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) { 681917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, 691917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "source decrypt buffer base not set"); 701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 731917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (destination.type == BufferType::SHARED_MEMORY) { 741917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const SharedBuffer& dest = destination.nonsecureMemory; 751917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) { 761917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, 771917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "destination decrypt buffer base not set"); 781917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 791917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 801917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 811917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 821917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId]; 831917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (sourceBase == nullptr) { 841917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr"); 851917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 861917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 871917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 881917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (source.offset + offset + source.size > sourceBase->getSize()) { 891917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); 901917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 911917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 921917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 931917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker uint8_t *base = static_cast<uint8_t *> 941917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker (static_cast<void *>(sourceBase->getPointer())); 951917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker uint8_t* srcPtr = static_cast<uint8_t *>(base + source.offset + offset); 961917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker void* destPtr = NULL; 971917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (destination.type == BufferType::SHARED_MEMORY) { 981917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const SharedBuffer& destBuffer = destination.nonsecureMemory; 991917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId]; 1001917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (destBase == nullptr) { 1011917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr"); 1021917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1031917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1041917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1051917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (destBuffer.offset + destBuffer.size > destBase->getSize()) { 1061917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size"); 1071917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1081917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1091917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset); 1101917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } else if (destination.type == BufferType::NATIVE_HANDLE) { 1111917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker native_handle_t *handle = const_cast<native_handle_t *>( 1121917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker destination.secureMemory.getNativeHandle()); 1131917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker destPtr = static_cast<void *>(handle); 1141917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1151917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker // Calculate the output buffer size and determine if any subsamples are 1171917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker // encrypted. 1181917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker size_t destSize = 0; 1191917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker bool haveEncryptedSubsamples = false; 1201917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker for (size_t i = 0; i < subSamples.size(); i++) { 1211917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const SubSample &subSample = subSamples[i]; 1221917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker destSize += subSample.numBytesOfClearData; 1231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker destSize += subSample.numBytesOfEncryptedData; 1241917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (subSample.numBytesOfEncryptedData > 0) { 1251917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker haveEncryptedSubsamples = true; 1261917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (mode == Mode::UNENCRYPTED) { 1301917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (haveEncryptedSubsamples) { 1311917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, 1321917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "Encrypted subsamples found in allegedly unencrypted data."); 1331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1351917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker size_t offset = 0; 1371917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker for (size_t i = 0; i < subSamples.size(); ++i) { 1381917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const SubSample& subSample = subSamples[i]; 1391917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (subSample.numBytesOfClearData != 0) { 1401917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker memcpy(reinterpret_cast<uint8_t*>(destPtr) + offset, 1411917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker reinterpret_cast<const uint8_t*>(srcPtr) + offset, 1421917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker subSample.numBytesOfClearData); 1431917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker offset += subSample.numBytesOfClearData; 1441917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1451917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1461917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1471917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::OK, static_cast<ssize_t>(offset), ""); 1481917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1491917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } else if (mode == Mode::AES_CTR) { 1501917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker size_t bytesDecrypted; 1511917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr, 1521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted); 1531917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (res == Status::OK) { 1541917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), ""); 1551917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1561917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } else { 1571917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res), 1581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "Decryption Error"); 1591917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1601917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1611917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } else { 1621917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, 1631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker "Selected encryption mode is not supported by the ClearKey DRM Plugin."); 1641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Void(); 1651917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1661917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} 1671917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1681917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<Status> CryptoPlugin::setMediaDrmSession( 1691917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker const hidl_vec<uint8_t>& sessionId) { 1701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (!sessionId.size()) { 1711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker mSession = nullptr; 1721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } else { 1731917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker mSession = SessionLibrary::get()->findSession(sessionId); 1741917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker if (!mSession.get()) { 1751917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Status::ERROR_DRM_SESSION_NOT_OPENED; 1761917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1771917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker } 1781917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker return Status::OK; 1791917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} 1801917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker 1811917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace clearkey 1821917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace V1_1 1831917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace drm 1841917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace hardware 1851917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace android 186