11fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce/* 21fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * Copyright (C) 2014 The Android Open Source Project 31fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * 41fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * Licensed under the Apache License, Version 2.0 (the "License"); 51fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * you may not use this file except in compliance with the License. 61fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * You may obtain a copy of the License at 71fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * 81fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * http://www.apache.org/licenses/LICENSE-2.0 91fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * 101fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * Unless required by applicable law or agreed to in writing, software 111fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * distributed under the License is distributed on an "AS IS" BASIS, 121fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * See the License for the specific language governing permissions and 141fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce * limitations under the License. 151fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce */ 161fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 171fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce//#define LOG_NDEBUG 0 181fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce#define LOG_TAG "ClearKeyCryptoPlugin" 191fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce#include <utils/Log.h> 201fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 211fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce#include <media/stagefright/MediaErrors.h> 221fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 231fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce#include "CryptoPlugin.h" 249472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker#include "SessionLibrary.h" 251fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 261fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Brucenamespace clearkeydrm { 271fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 281fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruceusing android::Vector; 291fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruceusing android::AString; 301fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruceusing android::status_t; 311fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 321fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce// Returns negative values for error code and positive values for the size of 331fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce// decrypted data. In theory, the output size can be larger than the input 341fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce// size, but in practice this will never happen for AES-CTR. 351fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Brucessize_t CryptoPlugin::decrypt(bool secure, const KeyId keyId, const Iv iv, 36b2231171d83c196dbb97aaa2563fa142e33a91c6Aurimas Liutikas Mode mode, const Pattern &/* pattern */, const void* srcPtr, 371fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce const SubSample* subSamples, size_t numSubSamples, 381fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce void* dstPtr, AString* errorDetailMsg) { 391fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce if (secure) { 401fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce errorDetailMsg->setTo("Secure decryption is not supported with " 411fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce "ClearKey."); 421fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return android::ERROR_DRM_CANNOT_HANDLE; 431fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 441fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 451fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce if (mode == kMode_Unencrypted) { 461fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce size_t offset = 0; 471fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce for (size_t i = 0; i < numSubSamples; ++i) { 481fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce const SubSample& subSample = subSamples[i]; 491fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 501fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce if (subSample.mNumBytesOfEncryptedData != 0) { 511fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce errorDetailMsg->setTo( 521fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce "Encrypted subsamples found in allegedly unencrypted " 531fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce "data."); 541fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return android::ERROR_DRM_DECRYPT; 551fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 561fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 571fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce if (subSample.mNumBytesOfClearData != 0) { 581fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce memcpy(reinterpret_cast<uint8_t*>(dstPtr) + offset, 591fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce reinterpret_cast<const uint8_t*>(srcPtr) + offset, 601fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce subSample.mNumBytesOfClearData); 611fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce offset += subSample.mNumBytesOfClearData; 621fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 631fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 641fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return static_cast<ssize_t>(offset); 651fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } else if (mode == kMode_AES_CTR) { 661fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce size_t bytesDecrypted; 671fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce status_t res = mSession->decrypt(keyId, iv, srcPtr, dstPtr, subSamples, 681fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce numSubSamples, &bytesDecrypted); 691fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce if (res == android::OK) { 701fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return static_cast<ssize_t>(bytesDecrypted); 711fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } else { 721fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce errorDetailMsg->setTo("Decryption Error"); 731fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return static_cast<ssize_t>(res); 741fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 751fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } else { 761fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce errorDetailMsg->setTo( 771fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce "Selected encryption mode is not supported by the ClearKey DRM " 781fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce "Plugin."); 791fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce return android::ERROR_DRM_CANNOT_HANDLE; 801fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce } 811fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce} 821fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce 839472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinkerandroid::status_t CryptoPlugin::setMediaDrmSession( 849472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker const android::Vector<uint8_t>& sessionId) { 859472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker if (!sessionId.size()) { 869472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker mSession.clear(); 879472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker } else { 889472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker mSession = SessionLibrary::get()->findSession(sessionId); 899472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker if (!mSession.get()) { 909472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker return android::ERROR_DRM_SESSION_NOT_OPENED; 919472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker } 929472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker } 939472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker return android::OK; 949472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker} 959472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker 969472e5f3ab44f04c92e44ad0f3e94c0ee508ec11Jeff Tinker 971fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aaJohn "Juce" Bruce} // namespace clearkeydrm 98