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/String8.h> 23 24 #include "Session.h" 25 26 #include "AesCtrDecryptor.h" 27 #include "InitDataParser.h" 28 #include "JsonWebKey.h" 29 30 namespace clearkeydrm { 31 32 using android::Mutex; 33 using android::String8; 34 using android::Vector; 35 using android::status_t; 36 37 status_t Session::getKeyRequest( 38 const Vector<uint8_t>& initData, 39 const String8& initDataType, 40 Vector<uint8_t>* keyRequest) const { 41 InitDataParser parser; 42 return parser.parse(initData, initDataType, keyRequest); 43 } 44 45 status_t Session::provideKeyResponse(const Vector<uint8_t>& response) { 46 String8 responseString( 47 reinterpret_cast<const char*>(response.array()), response.size()); 48 KeyMap keys; 49 50 Mutex::Autolock lock(mMapLock); 51 JsonWebKey parser; 52 if (parser.extractKeysFromJsonWebKeySet(responseString, &keys)) { 53 for (size_t i = 0; i < keys.size(); ++i) { 54 const KeyMap::key_type& keyId = keys.keyAt(i); 55 const KeyMap::value_type& key = keys.valueAt(i); 56 mKeyMap.add(keyId, key); 57 } 58 return android::OK; 59 } else { 60 return android::ERROR_DRM_UNKNOWN; 61 } 62 } 63 64 status_t Session::decrypt( 65 const KeyId keyId, const Iv iv, const void* source, 66 void* destination, const SubSample* subSamples, 67 size_t numSubSamples, size_t* bytesDecryptedOut) { 68 Mutex::Autolock lock(mMapLock); 69 70 Vector<uint8_t> keyIdVector; 71 keyIdVector.appendArray(keyId, kBlockSize); 72 if (mKeyMap.indexOfKey(keyIdVector) < 0) { 73 return android::ERROR_DRM_NO_LICENSE; 74 } 75 76 const Vector<uint8_t>& key = mKeyMap.valueFor(keyIdVector); 77 AesCtrDecryptor decryptor; 78 return decryptor.decrypt( 79 key, iv, 80 reinterpret_cast<const uint8_t*>(source), 81 reinterpret_cast<uint8_t*>(destination), subSamples, 82 numSubSamples, bytesDecryptedOut); 83 } 84 85 } // namespace clearkeydrm 86