11917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker/*
21917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Copyright (C) 2018 The Android Open Source Project
31917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker *
41917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Licensed under the Apache License, Version 2.0 (the "License");
51917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * you may not use this file except in compliance with the License.
61917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * You may obtain a copy of the License at
71917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker *
81917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker *      http://www.apache.org/licenses/LICENSE-2.0
91917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker *
101917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * Unless required by applicable law or agreed to in writing, software
111917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * distributed under the License is distributed on an "AS IS" BASIS,
121917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * See the License for the specific language governing permissions and
141917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker * limitations under the License.
151917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker */
161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
171917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker//#define LOG_NDEBUG 0
181917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#define LOG_TAG "hidl_ClearKeyCryptoPlugin"
191917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include <utils/Log.h>
201917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
211917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "CryptoPlugin.h"
221917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "SessionLibrary.h"
231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include "TypeConvert.h"
241917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
251917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker#include <hidlmemory/mapping.h>
261917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace android {
281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace hardware {
291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace drm {
301917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace V1_1 {
311917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkernamespace clearkey {
321917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinkerusing ::android::hardware::drm::V1_0::BufferType;
341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
351917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<void> CryptoPlugin::setSharedBufferBase(
361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const hidl_memory& base, uint32_t bufferId) {
371917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    sp<IMemory> hidlMemory = mapMemory(base);
381917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    ALOGE_IF(hidlMemory == nullptr, "mapMemory returns nullptr");
391917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
401917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    // allow mapMemory to return nullptr
411917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    mSharedBufferMap[bufferId] = hidlMemory;
421917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    return Void();
431917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker}
441917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
451917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// Returns negative values for error code and positive values for the size of
461917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// decrypted data.  In theory, the output size can be larger than the input
471917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker// size, but in practice this will never happen for AES-CTR.
481917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<void> CryptoPlugin::decrypt(
491917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        bool secure,
501917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const hidl_array<uint8_t, KEY_ID_SIZE>& keyId,
511917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const hidl_array<uint8_t, KEY_IV_SIZE>& iv,
521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        Mode mode,
531917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const Pattern& pattern,
541917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const hidl_vec<SubSample>& subSamples,
551917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const SharedBuffer& source,
561917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        uint64_t offset,
571917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const DestinationBuffer& destination,
581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        decrypt_cb _hidl_cb) {
591917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    UNUSED(pattern);
601917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
611917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (secure) {
621917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            "Secure decryption is not supported with ClearKey.");
641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
651917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
661917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
671917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (mSharedBufferMap.find(source.bufferId) == mSharedBufferMap.end()) {
681917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker      _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
691917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker               "source decrypt buffer base not set");
701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker      return Void();
711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
731917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (destination.type == BufferType::SHARED_MEMORY) {
741917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker      const SharedBuffer& dest = destination.nonsecureMemory;
751917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker      if (mSharedBufferMap.find(dest.bufferId) == mSharedBufferMap.end()) {
761917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
771917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                 "destination decrypt buffer base not set");
781917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
791917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker      }
801917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
811917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
821917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    sp<IMemory> sourceBase = mSharedBufferMap[source.bufferId];
831917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (sourceBase == nullptr) {
841917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "source is a nullptr");
851917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
861917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
871917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
881917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (source.offset + offset + source.size > sourceBase->getSize()) {
891917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
901917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
911917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
921917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
931917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    uint8_t *base = static_cast<uint8_t *>
941917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            (static_cast<void *>(sourceBase->getPointer()));
951917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    uint8_t* srcPtr = static_cast<uint8_t *>(base + source.offset + offset);
961917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    void* destPtr = NULL;
971917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (destination.type == BufferType::SHARED_MEMORY) {
981917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const SharedBuffer& destBuffer = destination.nonsecureMemory;
991917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        sp<IMemory> destBase = mSharedBufferMap[destBuffer.bufferId];
1001917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (destBase == nullptr) {
1011917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "destination is a nullptr");
1021917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Void();
1031917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1041917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1051917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
1061917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
1071917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Void();
1081917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1091917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
1101917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    } else if (destination.type == BufferType::NATIVE_HANDLE) {
1111917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        native_handle_t *handle = const_cast<native_handle_t *>(
1121917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        destination.secureMemory.getNativeHandle());
1131917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        destPtr = static_cast<void *>(handle);
1141917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
1151917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1161917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    // Calculate the output buffer size and determine if any subsamples are
1171917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    // encrypted.
1181917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    size_t destSize = 0;
1191917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    bool haveEncryptedSubsamples = false;
1201917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    for (size_t i = 0; i < subSamples.size(); i++) {
1211917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const SubSample &subSample = subSamples[i];
1221917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        destSize += subSample.numBytesOfClearData;
1231917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        destSize += subSample.numBytesOfEncryptedData;
1241917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (subSample.numBytesOfEncryptedData > 0) {
1251917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        haveEncryptedSubsamples = true;
1261917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1271917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
1281917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1291917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (mode == Mode::UNENCRYPTED) {
1301917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (haveEncryptedSubsamples) {
1311917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
1321917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                    "Encrypted subsamples found in allegedly unencrypted data.");
1331917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Void();
1341917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1351917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1361917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        size_t offset = 0;
1371917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        for (size_t i = 0; i < subSamples.size(); ++i) {
1381917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            const SubSample& subSample = subSamples[i];
1391917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            if (subSample.numBytesOfClearData != 0) {
1401917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                memcpy(reinterpret_cast<uint8_t*>(destPtr) + offset,
1411917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                       reinterpret_cast<const uint8_t*>(srcPtr) + offset,
1421917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                       subSample.numBytesOfClearData);
1431917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                offset += subSample.numBytesOfClearData;
1441917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            }
1451917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1461917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1471917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::OK, static_cast<ssize_t>(offset), "");
1481917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
1491917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    } else if (mode == Mode::AES_CTR) {
1501917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        size_t bytesDecrypted;
1511917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        Status res = mSession->decrypt(keyId.data(), iv.data(), srcPtr,
1521917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                static_cast<uint8_t*>(destPtr), toVector(subSamples), &bytesDecrypted);
1531917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (res == Status::OK) {
1541917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            _hidl_cb(Status::OK, static_cast<ssize_t>(bytesDecrypted), "");
1551917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Void();
1561917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        } else {
1571917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            _hidl_cb(Status::ERROR_DRM_DECRYPT, static_cast<ssize_t>(res),
1581917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                    "Decryption Error");
1591917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Void();
1601917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1611917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    } else {
1621917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0,
1631917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker                "Selected encryption mode is not supported by the ClearKey DRM Plugin.");
1641917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        return Void();
1651917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
1661917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker}
1671917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1681917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff TinkerReturn<Status> CryptoPlugin::setMediaDrmSession(
1691917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        const hidl_vec<uint8_t>& sessionId) {
1701917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    if (!sessionId.size()) {
1711917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        mSession = nullptr;
1721917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    } else {
1731917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        mSession = SessionLibrary::get()->findSession(sessionId);
1741917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        if (!mSession.get()) {
1751917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker            return Status::ERROR_DRM_SESSION_NOT_OPENED;
1761917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker        }
1771917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    }
1781917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker    return Status::OK;
1791917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker}
1801917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker
1811917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace clearkey
1821917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace V1_1
1831917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace drm
1841917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace hardware
1851917fac1e41f57e547df7dcdebf57dd8483e7f61Jeff Tinker} // namespace android
186