CryptoHal.cpp revision 6a4921ae044186bf64dab3903e8fead9499fc7f6
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;
71a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
72a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return UNKNOWN_ERROR;
73a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
74a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
75a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
76a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
77a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) {
78a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
79a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size());
80a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
81a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
82a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
83a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) {
84a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hidl_vec<uint8_t> vec;
85a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    vec.resize(size);
86a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    memcpy(vec.data(), ptr, size);
87a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return vec;
88a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
89a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
90a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) {
91a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!ptr) {
92a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return hidl_array<uint8_t, 16>();
93a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
94a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return hidl_array<uint8_t, 16>(ptr);
95a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
96a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
97a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
98a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatic String8 toString8(hidl_string hString) {
99a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return String8(hString.c_str());
100a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
101a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
102a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
103a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerCryptoHal::CryptoHal()
104abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    : mFactories(makeCryptoFactories()),
105abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker      mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT),
1063cb5316c442d182ada75a1394e1505a017400526Jeff Tinker      mNextBufferId(0) {
107a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
108a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
109a53d6553fce1818bdf87833f93633c93ad1b5915Jeff TinkerCryptoHal::~CryptoHal() {
110a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
111a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
112abeb36a8c2f044772297536e70340c3b245863e4Jeff TinkerVector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() {
113abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Vector<sp<ICryptoFactory>> factories;
114abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
1156a4921ae044186bf64dab3903e8fead9499fc7f6Jeff Tinker    auto manager = ::IServiceManager::getService();
116abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (manager != NULL) {
117abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        manager->listByInterface(ICryptoFactory::descriptor,
118abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                [&factories](const hidl_vec<hidl_string> &registered) {
119abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    for (const auto &instance : registered) {
120abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        auto factory = ICryptoFactory::getService(instance);
121abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        if (factory != NULL) {
122abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            factories.push_back(factory);
123abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                            ALOGI("makeCryptoFactories: factory instance %s is %s",
124abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    instance.c_str(),
125abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                                    factory->isRemote() ? "Remote" : "Not Remote");
126abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                        }
127abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                    }
128abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker                }
129abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            );
130abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
131a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
132abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    if (factories.size() == 0) {
133abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        // must be in passthrough mode, load the default passthrough service
134abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        auto passthrough = ICryptoFactory::getService("crypto");
135abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (passthrough != NULL) {
136abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGI("makeCryptoFactories: using default crypto instance");
137abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            factories.push_back(passthrough);
138abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        } else {
139abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            ALOGE("Failed to find any crypto factories");
140abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
141a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
142abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    return factories;
143a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
144a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
145abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkersp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory,
146abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        const uint8_t uuid[16], const void *initData, size_t initDataSize) {
147a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
148a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    sp<ICryptoPlugin> plugin;
149abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    Return<void> hResult = factory->createPlugin(toHidlArray16(uuid),
150a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            toHidlVec(initData, initDataSize),
151a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, const sp<ICryptoPlugin>& hPlugin) {
152a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status != Status::OK) {
153a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    ALOGE("Failed to make crypto plugin");
154a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    return;
155a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
156a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                plugin = hPlugin;
157a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
158a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
159a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return plugin;
160a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
161a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
162a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
163a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::initCheck() const {
164a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
165a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
166a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
167a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
168a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) {
169a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
170abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker
171abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
172abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
173abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            return true;
174abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
175a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
176a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return false;
177a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
178a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
179abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinkerstatus_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data,
180abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        size_t size) {
181a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
182a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
183abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    for (size_t i = 0; i < mFactories.size(); i++) {
184abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        if (mFactories[i]->isCryptoSchemeSupported(uuid)) {
185abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker            mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size);
186abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker        }
187abeb36a8c2f044772297536e70340c3b245863e4Jeff Tinker    }
188a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
189a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mPlugin == NULL) {
190a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = ERROR_UNSUPPORTED;
191a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
192a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        mInitCheck = OK;
193a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
194a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
195a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mInitCheck;
196a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
197a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
198a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::destroyPlugin() {
199a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
200a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
201a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
202a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
203a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
204a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
205a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin.clear();
206a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
207a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
208a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
209a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerbool CryptoHal::requiresSecureDecoderComponent(const char *mime) const {
210a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
211a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
212a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
213a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
214a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
215a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
216a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return mPlugin->requiresSecureDecoderComponent(hidl_string(mime));
217a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
218a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
219a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
220a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker/**
221a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * If the heap base isn't set, get the heap base from the IMemory
222a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * and send it to the HAL so it can map a remote heap of the same
223a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * size.  Once the heap base is established, shared memory buffers
224a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker * are sent by providing an offset into the heap and a buffer size.
225a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker */
2263cb5316c442d182ada75a1394e1505a017400526Jeff Tinkervoid CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) {
2273cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    native_handle_t* nativeHandle = native_handle_create(1, 0);
2283cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (!nativeHandle) {
2293cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        ALOGE("setSharedBufferBase(), failed to create native handle");
2303cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return;
2313cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2323cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (heap == NULL) {
2333cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        ALOGE("setSharedBufferBase(): heap is NULL");
2343cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return;
235a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
2363cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    int fd = heap->getHeapID();
2373cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    nativeHandle->data[0] = fd;
2383cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlHandle = hidl_handle(nativeHandle);
2393cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    auto hidlMemory = hidl_memory("ashmem", hidlHandle, heap->getSize());
2403cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    mHeapBases.add(heap->getBase(), mNextBufferId);
2413cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    Return<void> hResult = mPlugin->setSharedBufferBase(hidlMemory, mNextBufferId++);
2423cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed");
2433cb5316c442d182ada75a1394e1505a017400526Jeff Tinker}
2443cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2453cb5316c442d182ada75a1394e1505a017400526Jeff Tinkerstatus_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, ::SharedBuffer* buffer) {
2463cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ssize_t offset;
2473cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    size_t size;
2483cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2493cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (memory == NULL && buffer == NULL) {
2503cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2513cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2523cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2533cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    sp<IMemoryHeap> heap = memory->getMemory(&offset, &size);
2543cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (heap == NULL) {
2553cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return UNEXPECTED_NULL;
2563cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2573cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2583cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (mHeapBases.indexOfKey(heap->getBase()) < 0) {
2593cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        setHeapBase(heap);
2603cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
2613cb5316c442d182ada75a1394e1505a017400526Jeff Tinker
2623cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->bufferId = mHeapBases.valueFor(heap->getBase());
2633cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->offset = offset >= 0 ? offset : 0;
2643cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    buffer->size = size;
265a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return OK;
266a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
267a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
268a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16],
269a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern,
270a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const sp<IMemory> &source, size_t offset,
271a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
272a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) {
273a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
274a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
275a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
276a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
277a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
278a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
279a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mode hMode;
280a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    switch(mode) {
281a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_Unencrypted:
282a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::UNENCRYPTED ;
283a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
284a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CTR:
285a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CTR;
286a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
287a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_WV:
288a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC_CTS;
289a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
290a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    case CryptoPlugin::kMode_AES_CBC:
291a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hMode = Mode::AES_CBC;
292a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        break;
293a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    default:
294a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return UNKNOWN_ERROR;
295a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
296a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
297a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Pattern hPattern;
298a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.encryptBlocks = pattern.mEncryptBlocks;
299a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    hPattern.skipBlocks = pattern.mSkipBlocks;
300a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
301a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    std::vector<SubSample> stdSubSamples;
302a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    for (size_t i = 0; i < numSubSamples; i++) {
303a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        SubSample subSample;
304a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData;
305a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData;
306a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        stdSubSamples.push_back(subSample);
307a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
308a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    auto hSubSamples = hidl_vec<SubSample>(stdSubSamples);
309a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
310a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    bool secure;
311a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    ::DestinationBuffer hDestination;
312a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (destination.mType == kDestinationTypeSharedMemory) {
313a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::SHARED_MEMORY;
3143cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        status_t status = toSharedBuffer(destination.mSharedMemory,
3153cb5316c442d182ada75a1394e1505a017400526Jeff Tinker                &hDestination.nonsecureMemory);
3163cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        if (status != OK) {
3173cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            return status;
3183cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        }
319a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = false;
320a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    } else {
321a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.type = BufferType::NATIVE_HANDLE;
322a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        hDestination.secureMemory = hidl_handle(destination.mHandle);
323a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        secure = true;
324a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
325a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
3263cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    ::SharedBuffer hSource;
3273cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    status_t status = toSharedBuffer(source, &hSource);
3283cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    if (status != OK) {
3293cb5316c442d182ada75a1394e1505a017400526Jeff Tinker        return status;
3303cb5316c442d182ada75a1394e1505a017400526Jeff Tinker    }
331a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
332a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    status_t err = UNKNOWN_ERROR;
333a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    uint32_t bytesWritten = 0;
334a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
335a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Return<void> hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), hMode,
3363cb5316c442d182ada75a1394e1505a017400526Jeff Tinker            hPattern, hSubSamples, hSource, offset, hDestination,
337a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) {
338a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                if (status == Status::OK) {
339a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    bytesWritten = hBytesWritten;
340a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                    *errorDetailMsg = toString8(hDetailedError);
341a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                }
342a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker                err = toStatusT(status);
343a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker            }
344a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        );
345a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
346a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (!hResult.isOk()) {
347a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        err = DEAD_OBJECT;
348a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
349a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
350a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (err == OK) {
351a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return bytesWritten;
352a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
353a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return err;
354a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
355a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
356a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkervoid CryptoHal::notifyResolution(uint32_t width, uint32_t height) {
357a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
358a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
359a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
360a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return;
361a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
362a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
363a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    mPlugin->notifyResolution(width, height);
364a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
365a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
366a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinkerstatus_t CryptoHal::setMediaDrmSession(const Vector<uint8_t> &sessionId) {
367a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    Mutex::Autolock autoLock(mLock);
368a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
369a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    if (mInitCheck != OK) {
370a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker        return mInitCheck;
371a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    }
372a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
373a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker    return toStatusT(mPlugin->setMediaDrmSession(toHidlVec(sessionId)));
374a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}
375a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker
376a53d6553fce1818bdf87833f93633c93ad1b5915Jeff Tinker}  // namespace android
377