1a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker/*
2a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Copyright (C) 2017 The Android Open Source Project
3a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
4a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
5a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * you may not use this file except in compliance with the License.
6a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * You may obtain a copy of the License at
7a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
8a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
9a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker *
10a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * Unless required by applicable law or agreed to in writing, software
11a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
12a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * See the License for the specific language governing permissions and
14a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * limitations under the License.
15a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker */
16a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
17a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker//#define LOG_NDEBUG 0
18a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#define LOG_TAG "CryptoHal"
19a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <utils/Log.h>
20a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
21a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <android/hardware/drm/1.0/types.h>
22abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker#include <android/hidl/manager/1.0/IServiceManager.h>
23a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
24a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <binder/IMemory.h>
25a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <cutils/native_handle.h>
26a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/CryptoHal.h>
27a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/hardware/CryptoAPI.h>
28a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/ADebug.h>
29a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/AString.h>
30a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/foundation/hexdump.h>
31a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker#include <media/stagefright/MediaErrors.h>
32a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
33a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::BufferType;
34a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::DestinationBuffer;
35a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::ICryptoFactory;
36a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::ICryptoPlugin;
37a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::Mode;
38a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::Pattern;
39a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::SharedBuffer;
40a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::Status;
41a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::drm::V1_0::SubSample;
42a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_array;
43a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_handle;
44a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_memory;
45a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_string;
46a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::hidl_vec;
47a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Return;
48a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::hardware::Void;
49abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerusing ::android::hidl::manager::V1_0::IServiceManager;
50a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerusing ::android::sp;
51a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
52a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
53a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkernamespace android {
54a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
55a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic status_t toStatusT(Status status) {
56a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch (status) {
57a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::OK:
58a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return OK;
59a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_NO_LICENSE:
60a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_NO_LICENSE;
61a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_LICENSE_EXPIRED:
62a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_LICENSE_EXPIRED;
63a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_RESOURCE_BUSY:
64a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_RESOURCE_BUSY;
65a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
66a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION;
67a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_SESSION_NOT_OPENED:
68a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_SESSION_NOT_OPENED;
69a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case Status::ERROR_DRM_CANNOT_HANDLE:
70a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return ERROR_DRM_CANNOT_HANDLE;
71d0cb831e7f14c43359aeb080d9564185d28c7a75Jeff Tinker    case Status::ERROR_DRM_DECRYPT:
72d0cb831e7f14c43359aeb080d9564185d28c7a75Jeff Tinker        return ERROR_DRM_DECRYPT;
73a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
74a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return UNKNOWN_ERROR;
75a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
76a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
77a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
78a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
79a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
80a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
81a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
82a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
83a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
84a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
85a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) {
86a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
87a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.resize(size);
88a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    memcpy(vec.data(), ptr, size);
89a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
90a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
91a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
92a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) {
93a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!ptr) {
94a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return hidl_array<uint8_t, 16>();
95a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
96a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hidl_array<uint8_t, 16>(ptr);
97a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
98a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
99a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
100a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic String8 toString8(hidl_string hString) {
101a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return String8(hString.c_str());
102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
104a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
105a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerCryptoHal::CryptoHal()
106abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    : mFactories(makeCryptoFactories()),
107abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
1086dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang      mNextBufferId(0),
1096dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang      mHeapSeqNum(0) {
110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
112a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerCryptoHal::~CryptoHal() {
113a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
114a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
115abeb36a8c2f044772297536e70340c3b245863e4Jeff TinkerVector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
116abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Vector<sp<ICryptoFactory>> factories;
117abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
1186a4921ae044186bf64dab3903e8fead9499fc7f6Jeff Tinker    auto manager = ::IServiceManager::getService();
119abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (manager != NULL) {
120abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        manager->listByInterface(ICryptoFactory::descriptor,
121abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
122abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    for (const auto &instance : registered) {
123abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        auto factory = ICryptoFactory::getService(instance);
124abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        if (factory != NULL) {
125abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            factories.push_back(factory);
126abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            ALOGI("makeCryptoFactories: factory instance %s is %s",
127abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    instance.c_str(),
128abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    factory->isRemote() ? "Remote" : "Not Remote");
129abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        }
130abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    }
131abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
132abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            );
133abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
134a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
135abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (factories.size() == 0) {
136abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        // must be in passthrough mode, load the default passthrough service
137e309b22bff1719f1fea84b247e4b2bc4c5f09eb5Jeff Tinker        auto passthrough = ICryptoFactory::getService();
138abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (passthrough != NULL) {
139abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGI("makeCryptoFactories: using default crypto instance");
140abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            factories.push_back(passthrough);
141abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        } else {
142abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGE("Failed to find any crypto factories");
143abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
144a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
145abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return factories;
146a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
147a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
148abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkersp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
149abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
150a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
151a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<ICryptoPlugin> plugin;
152abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
153a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(initData, initDataSize),
154a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
155a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status != Status::OK) {
156a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    ALOGE("Failed to make crypto plugin");
157a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    return;
158a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                plugin = hPlugin;
160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return plugin;
163a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::initCheck() const {
167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
171a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
172a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
173abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
174abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
175abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
176abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            return true;
177abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return false;
180a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
181a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
182abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatus_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
183abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        size_t size) {
184a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
185a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
186abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
187abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
188abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
189abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
190abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mPlugin == NULL) {
193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
194a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
195a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = OK;
196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
198a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
199a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
200a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
201a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::destroyPlugin() {
202a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
203a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
204a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
205a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
206a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
207a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
208a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
209a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::requiresSecureDecoderComponent(const char *mime) const {
213a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
214a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
215a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
216a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
217a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
218a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
219a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mPlugin->requiresSecureDecoderComponent(hidl_string(mime));
220a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
221a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
222a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
223a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker/**
224a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * If the heap base isn't set, get the heap base from the IMemory
225a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * and send it to the HAL so it can map a remote heap of the same
226a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * size.  Once the heap base is established, shared memory buffers
227a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * are sent by providing an offset into the heap and a buffer size.
228a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker */
2296dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhangint32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
2306dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    if (heap == NULL) {
2316dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        ALOGE("setHeapBase(): heap is NULL");
2326dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        return -1;
2336dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    }
2343cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    native_handle_t* nativeHandle = native_handle_create(1, 0);
2353cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (!nativeHandle) {
236d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        ALOGE("setHeapBase(), failed to create native handle");
2376dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        return -1;
238a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
2396dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
2406dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    Mutex::Autolock autoLock(mLock);
2416dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
2426dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    int32_t seqNum = mHeapSeqNum++;
2433cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    int fd = heap->getHeapID();
2443cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    nativeHandle->data[0] = fd;
2453cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlHandle = hidl_handle(nativeHandle);
2463cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
2476dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    mHeapBases.add(seqNum, mNextBufferId);
2483cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
2493cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
2506dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    return seqNum;
2513cb5316c442d182ada75a1394e1505a017400526Jeff Tinker}
2523cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2536dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhangvoid CryptoHal::clearHeapBase(int32_t seqNum) {
2546dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    Mutex::Autolock autoLock(mLock);
2556dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang
2566dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    mHeapBases.removeItem(seqNum);
257d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang}
258d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
2596dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhangstatus_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) {
2603cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ssize_t offset;
2613cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    size_t size;
2623cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2633cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (memory == NULL && buffer == NULL) {
2643cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2653cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2663cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2673cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    sp<IMemoryHeap> heap = memory->getMemory(&offset, &size);
2683cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (heap == NULL) {
2693cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2703cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2713cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
272d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    // memory must be in the declared heap
2736dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    CHECK(mHeapBases.indexOfKey(seqNum) >= 0);
2743cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2756dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    buffer->bufferId = mHeapBases.valueFor(seqNum);
2763cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->offset = offset >= 0 ? offset : 0;
2773cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->size = size;
278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
279a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
280a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
281a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
282a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
2836dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        const ICrypto::SourceBuffer &source, size_t offset,
284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) {
286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
289a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
290a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
291a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
292a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mode hMode;
293a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch(mode) {
294a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_Unencrypted:
295a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::UNENCRYPTED ;
296a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
297a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CTR:
298a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CTR;
299a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
300a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_WV:
301a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC_CTS;
302a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
303a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CBC:
304a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC;
305a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
306a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
307a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return UNKNOWN_ERROR;
308a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
309a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
310a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Pattern hPattern;
311a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.encryptBlocks = pattern.mEncryptBlocks;
312a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.skipBlocks = pattern.mSkipBlocks;
313a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
314a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    std::vector<SubSample> stdSubSamples;
315a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < numSubSamples; i++) {
316a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        SubSample subSample;
317a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
318a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
319a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        stdSubSamples.push_back(subSample);
320a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
321a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
322a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
3236dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    int32_t heapSeqNum = source.mHeapSeqNum;
324a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool secure;
325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::DestinationBuffer hDestination;
326a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (destination.mType == kDestinationTypeSharedMemory) {
327a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::SHARED_MEMORY;
3286dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang        status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum,
3293cb5316c442d182ada75a1394e1505a017400526Jeff Tinker                &hDestination.nonsecureMemory);
3303cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        if (status != OK) {
3313cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            return status;
3323cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        }
333a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = false;
334a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
335a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::NATIVE_HANDLE;
336a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.secureMemory = hidl_handle(destination.mHandle);
337a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = true;
338a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
339a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
3403cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ::SharedBuffer hSource;
3416dcab2bafd847be84c2c2230bbd04af9c45c491eChong Zhang    status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource);
3423cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (status != OK) {
3433cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return status;
3443cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
346a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    uint32_t bytesWritten = 0;
348a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
349a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
3503cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            hPattern, hSubSamples, hSource, offset, hDestination,
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    bytesWritten = hBytesWritten;
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    *errorDetailMsg = toString8(hDetailedError);
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!hResult.isOk()) {
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        err = DEAD_OBJECT;
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
363a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (err == OK) {
365a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return bytesWritten;
366a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
367a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return err;
368a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
369a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
370a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid CryptoHal::notifyResolution(uint32_t width, uint32_t height) {
371a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
372a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
373a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
374a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return;
375a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
376a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
377a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin->notifyResolution(width, height);
378a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
379a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
380a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::setMediaDrmSession(const Vector<uint8_t> &sessionId) {
381a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
382a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
383a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
384a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
385a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
386