CryptoHal.cpp revision d07c92742fc5801cab8e99801f591365986acbe9
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),
1083cb5316c442d182ada75a1394e1505a017400526Jeff Tinker      mNextBufferId(0) {
109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerCryptoHal::~CryptoHal() {
112a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
113a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
114abeb36a8c2f044772297536e70340c3b245863e4Jeff TinkerVector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
115abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Vector<sp<ICryptoFactory>> factories;
116abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
1176a4921ae044186bf64dab3903e8fead9499fc7f6Jeff Tinker    auto manager = ::IServiceManager::getService();
118abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (manager != NULL) {
119abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        manager->listByInterface(ICryptoFactory::descriptor,
120abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
121abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    for (const auto &instance : registered) {
122abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        auto factory = ICryptoFactory::getService(instance);
123abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        if (factory != NULL) {
124abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            factories.push_back(factory);
125abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            ALOGI("makeCryptoFactories: factory instance %s is %s",
126abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    instance.c_str(),
127abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    factory->isRemote() ? "Remote" : "Not Remote");
128abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        }
129abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    }
130abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
131abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            );
132abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
133a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
134abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (factories.size() == 0) {
135abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        // must be in passthrough mode, load the default passthrough service
136abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        auto passthrough = ICryptoFactory::getService("crypto");
137abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (passthrough != NULL) {
138abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGI("makeCryptoFactories: using default crypto instance");
139abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            factories.push_back(passthrough);
140abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        } else {
141abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGE("Failed to find any crypto factories");
142abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
143a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
144abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return factories;
145a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
146a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
147abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkersp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
148abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
149a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
150a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<ICryptoPlugin> plugin;
151abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
152a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(initData, initDataSize),
153a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
154a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status != Status::OK) {
155a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    ALOGE("Failed to make crypto plugin");
156a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    return;
157a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
158a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                plugin = hPlugin;
159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return plugin;
162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
163a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::initCheck() const {
166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
170a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
171a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
172abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
173abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
174abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
175abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            return true;
176abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return false;
179a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
180a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
181abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatus_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
182abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        size_t size) {
183a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
184a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
185abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
186abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
187abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
188abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
189abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
190a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mPlugin == NULL) {
192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
194a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = OK;
195a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
198a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
199a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
200a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::destroyPlugin() {
201a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
202a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
203a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
204a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
205a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
206a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
207a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
208a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
209a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::requiresSecureDecoderComponent(const char *mime) const {
212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
213a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
214a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
215a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
216a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
217a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
218a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mPlugin->requiresSecureDecoderComponent(hidl_string(mime));
219a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
220a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
221a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
222a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker/**
223a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * If the heap base isn't set, get the heap base from the IMemory
224a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * and send it to the HAL so it can map a remote heap of the same
225a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * size.  Once the heap base is established, shared memory buffers
226a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * are sent by providing an offset into the heap and a buffer size.
227a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker */
2283cb5316c442d182ada75a1394e1505a017400526Jeff Tinkervoid CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
2293cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    native_handle_t* nativeHandle = native_handle_create(1, 0);
2303cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (!nativeHandle) {
231d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        ALOGE("setHeapBase(), failed to create native handle");
2323cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return;
2333cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2343cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (heap == NULL) {
235d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang        ALOGE("setHeapBase(): heap is NULL");
2363cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return;
237a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
2383cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    int fd = heap->getHeapID();
2393cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    nativeHandle->data[0] = fd;
2403cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlHandle = hidl_handle(nativeHandle);
2413cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
2423cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    mHeapBases.add(heap->getBase(), mNextBufferId);
2433cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
2443cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
2453cb5316c442d182ada75a1394e1505a017400526Jeff Tinker}
2463cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
247d07c92742fc5801cab8e99801f591365986acbe9Chong Zhangvoid CryptoHal::clearHeapBase(const sp<IMemoryHeap>& heap) {
248d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    mHeapBases.removeItem(heap->getBase());
249d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang}
250d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang
2513cb5316c442d182ada75a1394e1505a017400526Jeff Tinkerstatus_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer) {
2523cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ssize_t offset;
2533cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    size_t size;
2543cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2553cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (memory == NULL && buffer == NULL) {
2563cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2573cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2583cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2593cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    sp<IMemoryHeap> heap = memory->getMemory(&offset, &size);
2603cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (heap == NULL) {
2613cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2623cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2633cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
264d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    // memory must be in the declared heap
265d07c92742fc5801cab8e99801f591365986acbe9Chong Zhang    CHECK(mHeapBases.indexOfKey(heap->getBase()) >= 0);
2663cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2673cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->bufferId = mHeapBases.valueFor(heap->getBase());
2683cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->offset = offset >= 0 ? offset : 0;
2693cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->size = size;
270a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
271a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
272a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
273a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
274a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
275a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const sp<IMemory> &source, size_t offset,
276a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
277a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) {
278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
279a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
280a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
281a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
282a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
283a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mode hMode;
285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch(mode) {
286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_Unencrypted:
287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::UNENCRYPTED ;
288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
289a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CTR:
290a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CTR;
291a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
292a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_WV:
293a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC_CTS;
294a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
295a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CBC:
296a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC;
297a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
298a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
299a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return UNKNOWN_ERROR;
300a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
301a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
302a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Pattern hPattern;
303a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.encryptBlocks = pattern.mEncryptBlocks;
304a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.skipBlocks = pattern.mSkipBlocks;
305a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
306a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    std::vector<SubSample> stdSubSamples;
307a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < numSubSamples; i++) {
308a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        SubSample subSample;
309a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
310a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
311a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        stdSubSamples.push_back(subSample);
312a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
313a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
314a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
315a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool secure;
316a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::DestinationBuffer hDestination;
317a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (destination.mType == kDestinationTypeSharedMemory) {
318a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::SHARED_MEMORY;
3193cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        status_t status = toSharedBuffer(destination.mSharedMemory,
3203cb5316c442d182ada75a1394e1505a017400526Jeff Tinker                &hDestination.nonsecureMemory);
3213cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        if (status != OK) {
3223cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            return status;
3233cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        }
324a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = false;
325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
326a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::NATIVE_HANDLE;
327a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.secureMemory = hidl_handle(destination.mHandle);
328a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = true;
329a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
330a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
3313cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ::SharedBuffer hSource;
3323cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    status_t status = toSharedBuffer(source, &hSource);
3333cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (status != OK) {
3343cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return status;
3353cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
336a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
337a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
338a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    uint32_t bytesWritten = 0;
339a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
340a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
3413cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            hPattern, hSubSamples, hSource, offset, hDestination,
342a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
343a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
344a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    bytesWritten = hBytesWritten;
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    *errorDetailMsg = toString8(hDetailedError);
346a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
348a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
349a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
350a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!hResult.isOk()) {
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        err = DEAD_OBJECT;
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (err == OK) {
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return bytesWritten;
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return err;
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid CryptoHal::notifyResolution(uint32_t width, uint32_t height) {
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
363a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
365a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return;
366a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
367a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
368a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin->notifyResolution(width, height);
369a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
370a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
371a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::setMediaDrmSession(const Vector<uint8_t> &sessionId) {
372a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
373a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
374a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
375a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
376a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
377a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
378a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->setMediaDrmSession(toHidlVec(sessionId)));
379a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
380a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
381a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}  // namespace android
382