1 /* 2 * Copyright (C) 2017 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 "ecm_generator" 19 #include "ecm_generator.h" 20 21 #include <string.h> 22 #include <algorithm> 23 #include <endian.h> 24 25 #include "protos/license_protos.pb.h" 26 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/MediaErrors.h> 29 #include <openssl/aes.h> 30 #include <utils/Log.h> 31 32 namespace android { 33 namespace clearkeycas { 34 35 // These constants are internal to this module. 36 const uint16_t kEcmClearFieldsSize = 16; 37 const uint32_t kContentKeyByteSize = 16; 38 const uint16_t kTotalEcmSize = 39 kEcmClearFieldsSize + kContentKeyByteSize; // clear fields + clear key 40 41 const uint32_t kKeyLength = 16; 42 43 #define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32_t *>(_p)) 44 45 static uint32_t Load32(const void *p) { 46 return ntohl(UNALIGNED_LOAD32(p)); 47 } 48 49 static uint32_t LoadNext32(const uint8_t** pptr) { 50 CHECK(pptr); 51 CHECK(*pptr); 52 const uint8_t* p = *pptr; 53 *pptr += sizeof(uint32_t); 54 return Load32(p); 55 } 56 57 namespace ecm_generator { 58 59 status_t DecodeECM(const sp<ABuffer>& ecm, Asset* asset, 60 sp<ABuffer> *content_key, DefaultEcmFields* default_fields) { 61 CHECK(asset); 62 CHECK(content_key); 63 CHECK(default_fields); 64 65 status_t status = DecodeECMClearFields(ecm, asset, default_fields); 66 if (status != OK) { 67 return status; 68 } 69 70 const uint8_t* ptr = ecm->data() + kEcmClearFieldsSize; 71 *content_key = new ABuffer(kContentKeyByteSize); 72 memcpy((*content_key)->data(), ptr, kContentKeyByteSize); 73 74 return OK; 75 } 76 77 status_t DecodeECMClearFields(const sp<ABuffer>& ecm, Asset* asset, 78 DefaultEcmFields* default_fields) { 79 CHECK(asset); 80 CHECK(default_fields); 81 82 if (ecm->size() < kTotalEcmSize) { 83 ALOGE("Short ECM: expected_length=%d, actual_length=%zu", 84 kTotalEcmSize, ecm->size()); 85 return BAD_VALUE; 86 } 87 const uint8_t* ptr = ecm->data(); 88 default_fields->old_version = LoadNext32(&ptr); 89 default_fields->clear_lead = LoadNext32(&ptr); 90 default_fields->system_id = LoadNext32(&ptr); 91 // The real ecm version is hidden in the system id. 92 default_fields->ecm_version = (default_fields->system_id >> 24) & 0xFF; 93 default_fields->system_id &= 0x00FFFFFF; 94 if (default_fields->system_id == 0) { 95 ALOGE("Ecm has invalid system_id 0"); 96 return CLEARKEY_STATUS_INVALIDSYSTEMID; 97 } 98 asset->set_id(LoadNext32(&ptr)); 99 if (asset->id() == 0) { 100 ALOGE("Ecm has invalid asset_id 0"); 101 return CLEARKEY_STATUS_INVALIDASSETID; 102 } 103 return OK; 104 } 105 106 } // namespace ecm_generator 107 } // namespace clearkeycas 108 } // namespace android 109