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 30namespace clearkeydrm { 31 32using android::Mutex; 33using android::String8; 34using android::Vector; 35using android::status_t; 36 37status_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 45status_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 64status_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