| /** |
| * 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 and |
| * limitations under the License. |
| */ |
| #include <binder/IMemory.h> |
| #include <binder/IServiceManager.h> |
| #include <binder/MemoryBase.h> |
| #include <binder/MemoryHeapBase.h> |
| #include <media/ICrypto.h> |
| #include <media/IMediaDrmService.h> |
| #include <media/hardware/CryptoAPI.h> |
| #include <sys/types.h> |
| #include <sys/wait.h> |
| #include <utils/StrongPointer.h> |
| |
| #include <stdio.h> |
| #include <unistd.h> |
| |
| using namespace android; |
| |
| int main() |
| { |
| sp<IServiceManager> sm = defaultServiceManager(); |
| sp<IBinder> binder = sm->getService(String16("media.drm")); |
| sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder); |
| if (service == NULL) { |
| printf("Failed to retrieve 'media.drm' service.\n"); |
| return 1; |
| } |
| sp<ICrypto> crypto = service->makeCrypto(); |
| if (crypto == NULL) { |
| printf("makeCrypto failed.\n"); |
| return 1; |
| } |
| |
| const uint8_t clearkey_uuid[16] = { |
| 0x10, 0x77, 0xEF, 0xEC, 0xC0, 0xB2, 0x4D, 0x02, |
| 0xAC, 0xE3, 0x3C, 0x1E, 0x52, 0xE2, 0xFB, 0x4B |
| }; |
| if (crypto->createPlugin(clearkey_uuid, NULL, 0) != OK) { |
| printf("createPlugin failed.\n"); |
| return 1; |
| } |
| |
| sp<MemoryHeapBase> heap = new MemoryHeapBase(0x2000); |
| memset(heap->getBase(), 'A', 0x2000); |
| sp<MemoryBase> sourceMemory = new MemoryBase(heap, 0, 0x2000); |
| sp<MemoryBase> destMemory = new MemoryBase(heap, 0x1fff, 1); |
| int heapSeqNum = crypto->setHeap(heap); |
| if (heapSeqNum < 0) { |
| printf("setHeap failed.\n"); |
| return 1; |
| } |
| |
| CryptoPlugin::Pattern pattern = { .mEncryptBlocks = 0, .mSkipBlocks = 1 }; |
| ICrypto::SourceBuffer source = { .mSharedMemory = sourceMemory, |
| .mHeapSeqNum = heapSeqNum }; |
| CryptoPlugin::SubSample subSamples[1] = { { .mNumBytesOfClearData = 0x2000, |
| .mNumBytesOfEncryptedData = 0 } }; |
| ICrypto::DestinationBuffer destination = { |
| .mType = ICrypto::kDestinationTypeSharedMemory, .mHandle = NULL, .mSharedMemory = destMemory |
| }; |
| |
| int val = crypto->decrypt(NULL, NULL, |
| CryptoPlugin::kMode_Unencrypted, pattern, source, 0, subSamples, 1, |
| destination, NULL); |
| |
| if (val != BAD_VALUE) { |
| printf("OVERFLOW DETECTED\n"); |
| } |
| |
| return 0; |
| } |