1 /* 2 * Copyright (C) 2014 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ClearKeyCryptoPlugin" 19 #include <utils/Log.h> 20 21 #include <openssl/aes.h> 22 23 #include "AesCtrDecryptor.h" 24 25 namespace clearkeydrm { 26 27 static const size_t kBlockBitCount = kBlockSize * 8; 28 29 android::status_t AesCtrDecryptor::decrypt(const android::Vector<uint8_t>& key, 30 const Iv iv, const uint8_t* source, 31 uint8_t* destination, 32 const SubSample* subSamples, 33 size_t numSubSamples, 34 size_t* bytesDecryptedOut) { 35 uint32_t blockOffset = 0; 36 uint8_t previousEncryptedCounter[kBlockSize]; 37 memset(previousEncryptedCounter, 0, kBlockSize); 38 39 if (key.size() != kBlockSize || (sizeof(Iv) / sizeof(uint8_t)) != kBlockSize) { 40 android_errorWriteLog(0x534e4554, "63982768"); 41 return android::ERROR_DRM_DECRYPT; 42 } 43 44 size_t offset = 0; 45 AES_KEY opensslKey; 46 AES_set_encrypt_key(key.array(), kBlockBitCount, &opensslKey); 47 Iv opensslIv; 48 memcpy(opensslIv, iv, sizeof(opensslIv)); 49 50 for (size_t i = 0; i < numSubSamples; ++i) { 51 const SubSample& subSample = subSamples[i]; 52 53 if (subSample.mNumBytesOfClearData > 0) { 54 memcpy(destination + offset, source + offset, 55 subSample.mNumBytesOfClearData); 56 offset += subSample.mNumBytesOfClearData; 57 } 58 59 if (subSample.mNumBytesOfEncryptedData > 0) { 60 AES_ctr128_encrypt(source + offset, destination + offset, 61 subSample.mNumBytesOfEncryptedData, &opensslKey, 62 opensslIv, previousEncryptedCounter, 63 &blockOffset); 64 offset += subSample.mNumBytesOfEncryptedData; 65 } 66 } 67 68 *bytesDecryptedOut = offset; 69 return android::OK; 70 } 71 72 } // namespace clearkeydrm 73