blob: 073f0307916f8869eb9d6703a62ff612b657f989 [file] [log] [blame]
Jeff Tinkerb075caa2016-12-06 23:15:20 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "CryptoPlugin.h"
18#include "TypeConvert.h"
19
Jeff Tinkerb075caa2016-12-06 23:15:20 -080020#include <android/hidl/memory/1.0/IMemory.h>
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080021#include <hidlmemory/mapping.h>
22#include <media/stagefright/foundation/AString.h>
Jeff Tinkerd59d3622016-12-16 01:34:52 -080023#include <utils/Log.h>
Jeff Tinkerb075caa2016-12-06 23:15:20 -080024
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080025using android::hardware::hidl_memory;
Jeff Tinkerb075caa2016-12-06 23:15:20 -080026using android::hidl::memory::V1_0::IMemory;
27
Jeff Tinkerb075caa2016-12-06 23:15:20 -080028namespace android {
29namespace hardware {
30namespace drm {
Jeff Tinkerb075caa2016-12-06 23:15:20 -080031namespace V1_0 {
32namespace implementation {
33
Jeff Tinkerda002fe2017-01-19 14:41:11 -080034 // Methods from ::android::hardware::drm::V1_0::ICryptoPlugin follow
Jeff Tinkerb075caa2016-12-06 23:15:20 -080035 Return<bool> CryptoPlugin::requiresSecureDecoderComponent(
36 const hidl_string& mime) {
37 return mLegacyPlugin->requiresSecureDecoderComponent(mime);
38 }
39
40 Return<void> CryptoPlugin::notifyResolution(uint32_t width,
41 uint32_t height) {
42 mLegacyPlugin->notifyResolution(width, height);
43 return Void();
44 }
45
46 Return<Status> CryptoPlugin::setMediaDrmSession(
47 const hidl_vec<uint8_t>& sessionId) {
48 return toStatus(mLegacyPlugin->setMediaDrmSession(toVector(sessionId)));
49 }
50
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080051 Return<void> CryptoPlugin::setSharedBufferBase(const hidl_memory& base) {
52 mSharedBufferBase = mapMemory(base);
53 return Void();
54 }
55
Jeff Tinkerb075caa2016-12-06 23:15:20 -080056 Return<void> CryptoPlugin::decrypt(bool secure,
57 const hidl_array<uint8_t, 16>& keyId,
58 const hidl_array<uint8_t, 16>& iv, Mode mode,
59 const Pattern& pattern, const hidl_vec<SubSample>& subSamples,
Jeff Tinkerda002fe2017-01-19 14:41:11 -080060 const SharedBuffer& source, uint64_t offset,
Jeff Tinker6fdbe862017-01-11 19:45:23 -080061 const DestinationBuffer& destination,
Jeff Tinkerb075caa2016-12-06 23:15:20 -080062 decrypt_cb _hidl_cb) {
63
64 android::CryptoPlugin::Mode legacyMode;
65 switch(mode) {
66 case Mode::UNENCRYPTED:
67 legacyMode = android::CryptoPlugin::kMode_Unencrypted;
68 break;
69 case Mode::AES_CTR:
70 legacyMode = android::CryptoPlugin::kMode_AES_CTR;
71 break;
72 case Mode::AES_CBC_CTS:
73 legacyMode = android::CryptoPlugin::kMode_AES_WV;
74 break;
75 case Mode::AES_CBC:
76 legacyMode = android::CryptoPlugin::kMode_AES_CBC;
77 break;
78 }
79 android::CryptoPlugin::Pattern legacyPattern;
80 legacyPattern.mEncryptBlocks = pattern.encryptBlocks;
81 legacyPattern.mSkipBlocks = pattern.skipBlocks;
82
83 android::CryptoPlugin::SubSample *legacySubSamples =
84 new android::CryptoPlugin::SubSample[subSamples.size()];
85
86 for (size_t i = 0; i < subSamples.size(); i++) {
87 legacySubSamples[i].mNumBytesOfClearData
88 = subSamples[i].numBytesOfClearData;
89 legacySubSamples[i].mNumBytesOfEncryptedData
90 = subSamples[i].numBytesOfEncryptedData;
91 }
92
93 AString detailMessage;
94
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -080095 if (source.offset + offset + source.size > mSharedBufferBase->getSize()) {
96 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
97 return Void();
98 }
Jeff Tinker6fdbe862017-01-11 19:45:23 -080099
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800100 uint8_t *base = static_cast<uint8_t *>
101 (static_cast<void *>(mSharedBufferBase->getPointer()));
102 void *srcPtr = static_cast<void *>(base + source.offset + offset);
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800103
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800104 void *destPtr = NULL;
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800105 if (destination.type == BufferType::SHARED_MEMORY) {
Jeff Tinkerf21cdaf2017-01-18 11:49:27 -0800106 const SharedBuffer& destBuffer = destination.nonsecureMemory;
107 if (destBuffer.offset + destBuffer.size > mSharedBufferBase->getSize()) {
108 _hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
109 return Void();
110 }
111 destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800112 } else if (destination.type == BufferType::NATIVE_HANDLE) {
113 native_handle_t *handle = const_cast<native_handle_t *>(
114 destination.secureMemory.getNativeHandle());
115 destPtr = static_cast<void *>(handle);
116 }
117 ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
Jeff Tinker6fdbe862017-01-11 19:45:23 -0800118 legacyMode, legacyPattern, srcPtr, legacySubSamples,
119 subSamples.size(), destPtr, &detailMessage);
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800120
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800121 delete[] legacySubSamples;
122
123 uint32_t status;
124 uint32_t bytesWritten;
125
126 if (result >= 0) {
127 status = android::OK;
128 bytesWritten = result;
129 } else {
130 status = -result;
131 bytesWritten = 0;
132 }
133
Jeff Tinker01f0a5a2017-01-12 09:22:18 -0800134 _hidl_cb(toStatus(status), bytesWritten, detailMessage.c_str());
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800135 return Void();
136 }
137
138} // namespace implementation
139} // namespace V1_0
Jeff Tinkerb075caa2016-12-06 23:15:20 -0800140} // namespace drm
141} // namespace hardware
142} // namespace android