Session.cpp revision 1fe11a5d1b7932a8a4a4e6e8cf1aedd21fcdb3aa
1ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/*
2ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Copyright (C) 2014 The Android Open Source Project
3ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
4ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Licensed under the Apache License, Version 2.0 (the "License");
5ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * you may not use this file except in compliance with the License.
6ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * You may obtain a copy of the License at
7ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
8ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *      http://www.apache.org/licenses/LICENSE-2.0
9ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa *
10ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Unless required by applicable law or agreed to in writing, software
11ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * distributed under the License is distributed on an "AS IS" BASIS,
12ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * See the License for the specific language governing permissions and
14ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * limitations under the License.
15ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */
16ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
17ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa//#define LOG_NDEBUG 0
18ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#define LOG_TAG "ClearKeyCryptoPlugin"
19ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <utils/Log.h>
206568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
21ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <media/stagefright/MediaErrors.h>
22ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include <utils/String8.h>
23ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
24ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include "Session.h"
25ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
26ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa#include "AesCtrDecryptor.h"
276568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include "InitDataParser.h"
286568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa#include "JsonWebKey.h"
294b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa
306568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaanamespace clearkeydrm {
31ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
326568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaausing android::Mutex;
33ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaausing android::String8;
346568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaausing android::Vector;
356568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaausing android::status_t;
366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
376568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaastatus_t Session::getKeyRequest(
386568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        const Vector<uint8_t>& initData,
396568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        const String8& initDataType,
406568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        Vector<uint8_t>* keyRequest) const {
416568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    InitDataParser parser;
426568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    return parser.parse(initData, initDataType, keyRequest);
436568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa}
446568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
456568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaastatus_t Session::provideKeyResponse(const Vector<uint8_t>& response) {
466568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    String8 responseString(
476568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            reinterpret_cast<const char*>(response.array()), response.size());
486568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    KeyMap keys;
49ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
506568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    Mutex::Autolock lock(mMapLock);
516568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    JsonWebKey parser;
526568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    if (parser.extractKeysFromJsonWebKeySet(responseString, &keys)) {
536568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        for (size_t i = 0; i < keys.size(); ++i) {
546568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            const KeyMap::key_type& keyId = keys.keyAt(i);
556568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            const KeyMap::value_type& key = keys.valueAt(i);
566568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa            mKeyMap.add(keyId, key);
576568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        }
586568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        return android::OK;
596568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    } else {
606568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        return android::ERROR_DRM_UNKNOWN;
616568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    }
626568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa}
636568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
646568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaastatus_t Session::decrypt(
656568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        const KeyId keyId, const Iv iv, const void* source,
666568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        void* destination, const SubSample* subSamples,
676568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa        size_t numSubSamples, size_t* bytesDecryptedOut) {
68ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    Mutex::Autolock lock(mMapLock);
69ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
70ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    Vector<uint8_t> keyIdVector;
716568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa    keyIdVector.appendArray(keyId, kBlockSize);
72ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    if (mKeyMap.indexOfKey(keyIdVector) < 0) {
73ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa        return android::ERROR_DRM_NO_LICENSE;
74ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    }
756568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa
76ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    const Vector<uint8_t>& key = mKeyMap.valueFor(keyIdVector);
77ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    AesCtrDecryptor decryptor;
78ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa    return decryptor.decrypt(
79ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            key, iv,
80ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            reinterpret_cast<const uint8_t*>(source),
81ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            reinterpret_cast<uint8_t*>(destination), subSamples,
82ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa            numSubSamples, bytesDecryptedOut);
83ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa}
84ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa
85ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa} // namespace clearkeydrm
86ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa