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 "CryptoHal" 19 #include <utils/Log.h> 20 21 #include <android/hardware/drm/1.0/types.h> 22 #include <android/hidl/manager/1.0/IServiceManager.h> 23 24 #include <binder/IMemory.h> 25 #include <hidlmemory/FrameworkUtils.h> 26 #include <media/hardware/CryptoAPI.h> 27 #include <media/stagefright/foundation/ADebug.h> 28 #include <media/stagefright/foundation/AString.h> 29 #include <media/stagefright/foundation/hexdump.h> 30 #include <media/stagefright/MediaErrors.h> 31 #include <mediadrm/CryptoHal.h> 32 33 using drm::V1_0::BufferType; 34 using drm::V1_0::DestinationBuffer; 35 using drm::V1_0::ICryptoFactory; 36 using drm::V1_0::ICryptoPlugin; 37 using drm::V1_0::Mode; 38 using drm::V1_0::Pattern; 39 using drm::V1_0::SharedBuffer; 40 using drm::V1_0::Status; 41 using drm::V1_0::SubSample; 42 43 using ::android::hardware::hidl_array; 44 using ::android::hardware::hidl_handle; 45 using ::android::hardware::hidl_memory; 46 using ::android::hardware::hidl_string; 47 using ::android::hardware::hidl_vec; 48 using ::android::hardware::Return; 49 using ::android::hardware::Void; 50 using ::android::hidl::manager::V1_0::IServiceManager; 51 using ::android::sp; 52 53 typedef drm::V1_2::Status Status_V1_2; 54 55 namespace android { 56 57 static status_t toStatusT(Status status) { 58 switch (status) { 59 case Status::OK: 60 return OK; 61 case Status::ERROR_DRM_NO_LICENSE: 62 return ERROR_DRM_NO_LICENSE; 63 case Status::ERROR_DRM_LICENSE_EXPIRED: 64 return ERROR_DRM_LICENSE_EXPIRED; 65 case Status::ERROR_DRM_RESOURCE_BUSY: 66 return ERROR_DRM_RESOURCE_BUSY; 67 case Status::ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION: 68 return ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION; 69 case Status::ERROR_DRM_SESSION_NOT_OPENED: 70 return ERROR_DRM_SESSION_NOT_OPENED; 71 case Status::ERROR_DRM_CANNOT_HANDLE: 72 return ERROR_DRM_CANNOT_HANDLE; 73 case Status::ERROR_DRM_DECRYPT: 74 return ERROR_DRM_DECRYPT; 75 default: 76 return UNKNOWN_ERROR; 77 } 78 } 79 80 static status_t toStatusT_1_2(Status_V1_2 status) { 81 switch (status) { 82 case Status_V1_2::ERROR_DRM_SESSION_LOST_STATE: 83 return ERROR_DRM_SESSION_LOST_STATE;; 84 case Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE: 85 return ERROR_DRM_FRAME_TOO_LARGE; 86 case Status_V1_2::ERROR_DRM_INSUFFICIENT_SECURITY: 87 return ERROR_DRM_INSUFFICIENT_SECURITY; 88 default: 89 return toStatusT(static_cast<Status>(status)); 90 } 91 } 92 93 static hidl_vec<uint8_t> toHidlVec(const Vector<uint8_t> &vector) { 94 hidl_vec<uint8_t> vec; 95 vec.setToExternal(const_cast<uint8_t *>(vector.array()), vector.size()); 96 return vec; 97 } 98 99 static hidl_vec<uint8_t> toHidlVec(const void *ptr, size_t size) { 100 hidl_vec<uint8_t> vec; 101 vec.resize(size); 102 memcpy(vec.data(), ptr, size); 103 return vec; 104 } 105 106 static hidl_array<uint8_t, 16> toHidlArray16(const uint8_t *ptr) { 107 if (!ptr) { 108 return hidl_array<uint8_t, 16>(); 109 } 110 return hidl_array<uint8_t, 16>(ptr); 111 } 112 113 114 static String8 toString8(hidl_string hString) { 115 return String8(hString.c_str()); 116 } 117 118 119 CryptoHal::CryptoHal() 120 : mFactories(makeCryptoFactories()), 121 mInitCheck((mFactories.size() == 0) ? ERROR_UNSUPPORTED : NO_INIT), 122 mNextBufferId(0), 123 mHeapSeqNum(0) { 124 } 125 126 CryptoHal::~CryptoHal() { 127 } 128 129 Vector<sp<ICryptoFactory>> CryptoHal::makeCryptoFactories() { 130 Vector<sp<ICryptoFactory>> factories; 131 132 auto manager = ::IServiceManager::getService(); 133 if (manager != NULL) { 134 manager->listByInterface(drm::V1_0::ICryptoFactory::descriptor, 135 [&factories](const hidl_vec<hidl_string> ®istered) { 136 for (const auto &instance : registered) { 137 auto factory = drm::V1_0::ICryptoFactory::getService(instance); 138 if (factory != NULL) { 139 ALOGD("found drm (at) 1.0 ICryptoFactory %s", instance.c_str()); 140 factories.push_back(factory); 141 } 142 } 143 } 144 ); 145 manager->listByInterface(drm::V1_1::ICryptoFactory::descriptor, 146 [&factories](const hidl_vec<hidl_string> ®istered) { 147 for (const auto &instance : registered) { 148 auto factory = drm::V1_1::ICryptoFactory::getService(instance); 149 if (factory != NULL) { 150 ALOGD("found drm (at) 1.1 ICryptoFactory %s", instance.c_str()); 151 factories.push_back(factory); 152 } 153 } 154 } 155 ); 156 } 157 158 if (factories.size() == 0) { 159 // must be in passthrough mode, load the default passthrough service 160 auto passthrough = ICryptoFactory::getService(); 161 if (passthrough != NULL) { 162 ALOGI("makeCryptoFactories: using default passthrough crypto instance"); 163 factories.push_back(passthrough); 164 } else { 165 ALOGE("Failed to find any crypto factories"); 166 } 167 } 168 return factories; 169 } 170 171 sp<ICryptoPlugin> CryptoHal::makeCryptoPlugin(const sp<ICryptoFactory>& factory, 172 const uint8_t uuid[16], const void *initData, size_t initDataSize) { 173 174 sp<ICryptoPlugin> plugin; 175 Return<void> hResult = factory->createPlugin(toHidlArray16(uuid), 176 toHidlVec(initData, initDataSize), 177 [&](Status status, const sp<ICryptoPlugin>& hPlugin) { 178 if (status != Status::OK) { 179 ALOGE("Failed to make crypto plugin"); 180 return; 181 } 182 plugin = hPlugin; 183 } 184 ); 185 return plugin; 186 } 187 188 189 status_t CryptoHal::initCheck() const { 190 return mInitCheck; 191 } 192 193 194 bool CryptoHal::isCryptoSchemeSupported(const uint8_t uuid[16]) { 195 Mutex::Autolock autoLock(mLock); 196 197 for (size_t i = 0; i < mFactories.size(); i++) { 198 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 199 return true; 200 } 201 } 202 return false; 203 } 204 205 status_t CryptoHal::createPlugin(const uint8_t uuid[16], const void *data, 206 size_t size) { 207 Mutex::Autolock autoLock(mLock); 208 209 for (size_t i = 0; i < mFactories.size(); i++) { 210 if (mFactories[i]->isCryptoSchemeSupported(uuid)) { 211 mPlugin = makeCryptoPlugin(mFactories[i], uuid, data, size); 212 if (mPlugin != NULL) { 213 mPluginV1_2 = drm::V1_2::ICryptoPlugin::castFrom(mPlugin); 214 } 215 } 216 } 217 218 if (mPlugin == NULL) { 219 mInitCheck = ERROR_UNSUPPORTED; 220 } else { 221 mInitCheck = OK; 222 } 223 224 return mInitCheck; 225 } 226 227 status_t CryptoHal::destroyPlugin() { 228 Mutex::Autolock autoLock(mLock); 229 230 if (mInitCheck != OK) { 231 return mInitCheck; 232 } 233 234 mPlugin.clear(); 235 mPluginV1_2.clear(); 236 return OK; 237 } 238 239 bool CryptoHal::requiresSecureDecoderComponent(const char *mime) const { 240 Mutex::Autolock autoLock(mLock); 241 242 if (mInitCheck != OK) { 243 return false; 244 } 245 246 Return<bool> hResult = mPlugin->requiresSecureDecoderComponent(hidl_string(mime)); 247 if (!hResult.isOk()) { 248 return false; 249 } 250 return hResult; 251 } 252 253 254 /** 255 * If the heap base isn't set, get the heap base from the IMemory 256 * and send it to the HAL so it can map a remote heap of the same 257 * size. Once the heap base is established, shared memory buffers 258 * are sent by providing an offset into the heap and a buffer size. 259 */ 260 int32_t CryptoHal::setHeapBase(const sp<IMemoryHeap>& heap) { 261 using ::android::hardware::fromHeap; 262 using ::android::hardware::HidlMemory; 263 264 if (heap == NULL) { 265 ALOGE("setHeapBase(): heap is NULL"); 266 return -1; 267 } 268 269 Mutex::Autolock autoLock(mLock); 270 271 int32_t seqNum = mHeapSeqNum++; 272 sp<HidlMemory> hidlMemory = fromHeap(heap); 273 mHeapBases.add(seqNum, HeapBase(mNextBufferId, heap->getSize())); 274 Return<void> hResult = mPlugin->setSharedBufferBase(*hidlMemory, mNextBufferId++); 275 ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); 276 return seqNum; 277 } 278 279 void CryptoHal::clearHeapBase(int32_t seqNum) { 280 Mutex::Autolock autoLock(mLock); 281 282 /* 283 * Clear the remote shared memory mapping by setting the shared 284 * buffer base to a null hidl_memory. 285 * 286 * TODO: Add a releaseSharedBuffer method in a future DRM HAL 287 * API version to make this explicit. 288 */ 289 ssize_t index = mHeapBases.indexOfKey(seqNum); 290 if (index >= 0) { 291 if (mPlugin != NULL) { 292 uint32_t bufferId = mHeapBases[index].getBufferId(); 293 Return<void> hResult = mPlugin->setSharedBufferBase(hidl_memory(), bufferId); 294 ALOGE_IF(!hResult.isOk(), "setSharedBufferBase(): remote call failed"); 295 } 296 mHeapBases.removeItem(seqNum); 297 } 298 } 299 300 status_t CryptoHal::toSharedBuffer(const sp<IMemory>& memory, int32_t seqNum, ::SharedBuffer* buffer) { 301 ssize_t offset; 302 size_t size; 303 304 if (memory == NULL || buffer == NULL) { 305 return UNEXPECTED_NULL; 306 } 307 308 sp<IMemoryHeap> heap = memory->getMemory(&offset, &size); 309 if (heap == NULL) { 310 return UNEXPECTED_NULL; 311 } 312 313 // memory must be in one of the heaps that have been set 314 if (mHeapBases.indexOfKey(seqNum) < 0) { 315 return UNKNOWN_ERROR; 316 } 317 318 // heap must be the same size as the one that was set in setHeapBase 319 if (mHeapBases.valueFor(seqNum).getSize() != heap->getSize()) { 320 android_errorWriteLog(0x534e4554, "76221123"); 321 return UNKNOWN_ERROR; 322 } 323 324 // memory must be within the address space of the heap 325 if (memory->pointer() != static_cast<uint8_t *>(heap->getBase()) + memory->offset() || 326 heap->getSize() < memory->offset() + memory->size() || 327 SIZE_MAX - memory->offset() < memory->size()) { 328 android_errorWriteLog(0x534e4554, "76221123"); 329 return UNKNOWN_ERROR; 330 } 331 332 buffer->bufferId = mHeapBases.valueFor(seqNum).getBufferId(); 333 buffer->offset = offset >= 0 ? offset : 0; 334 buffer->size = size; 335 return OK; 336 } 337 338 ssize_t CryptoHal::decrypt(const uint8_t keyId[16], const uint8_t iv[16], 339 CryptoPlugin::Mode mode, const CryptoPlugin::Pattern &pattern, 340 const ICrypto::SourceBuffer &source, size_t offset, 341 const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 342 const ICrypto::DestinationBuffer &destination, AString *errorDetailMsg) { 343 Mutex::Autolock autoLock(mLock); 344 345 if (mInitCheck != OK) { 346 return mInitCheck; 347 } 348 349 Mode hMode; 350 switch(mode) { 351 case CryptoPlugin::kMode_Unencrypted: 352 hMode = Mode::UNENCRYPTED ; 353 break; 354 case CryptoPlugin::kMode_AES_CTR: 355 hMode = Mode::AES_CTR; 356 break; 357 case CryptoPlugin::kMode_AES_WV: 358 hMode = Mode::AES_CBC_CTS; 359 break; 360 case CryptoPlugin::kMode_AES_CBC: 361 hMode = Mode::AES_CBC; 362 break; 363 default: 364 return UNKNOWN_ERROR; 365 } 366 367 Pattern hPattern; 368 hPattern.encryptBlocks = pattern.mEncryptBlocks; 369 hPattern.skipBlocks = pattern.mSkipBlocks; 370 371 std::vector<SubSample> stdSubSamples; 372 for (size_t i = 0; i < numSubSamples; i++) { 373 SubSample subSample; 374 subSample.numBytesOfClearData = subSamples[i].mNumBytesOfClearData; 375 subSample.numBytesOfEncryptedData = subSamples[i].mNumBytesOfEncryptedData; 376 stdSubSamples.push_back(subSample); 377 } 378 auto hSubSamples = hidl_vec<SubSample>(stdSubSamples); 379 380 int32_t heapSeqNum = source.mHeapSeqNum; 381 bool secure; 382 ::DestinationBuffer hDestination; 383 if (destination.mType == kDestinationTypeSharedMemory) { 384 hDestination.type = BufferType::SHARED_MEMORY; 385 status_t status = toSharedBuffer(destination.mSharedMemory, heapSeqNum, 386 &hDestination.nonsecureMemory); 387 if (status != OK) { 388 return status; 389 } 390 secure = false; 391 } else if (destination.mType == kDestinationTypeNativeHandle) { 392 hDestination.type = BufferType::NATIVE_HANDLE; 393 hDestination.secureMemory = hidl_handle(destination.mHandle); 394 secure = true; 395 } else { 396 android_errorWriteLog(0x534e4554, "70526702"); 397 return UNKNOWN_ERROR; 398 } 399 400 ::SharedBuffer hSource; 401 status_t status = toSharedBuffer(source.mSharedMemory, heapSeqNum, &hSource); 402 if (status != OK) { 403 return status; 404 } 405 406 status_t err = UNKNOWN_ERROR; 407 uint32_t bytesWritten = 0; 408 409 Return<void> hResult; 410 411 if (mPluginV1_2 != NULL) { 412 hResult = mPluginV1_2->decrypt_1_2(secure, toHidlArray16(keyId), toHidlArray16(iv), 413 hMode, hPattern, hSubSamples, hSource, offset, hDestination, 414 [&](Status_V1_2 status, uint32_t hBytesWritten, hidl_string hDetailedError) { 415 if (status == Status_V1_2::OK) { 416 bytesWritten = hBytesWritten; 417 *errorDetailMsg = toString8(hDetailedError); 418 } 419 err = toStatusT_1_2(status); 420 } 421 ); 422 } else { 423 hResult = mPlugin->decrypt(secure, toHidlArray16(keyId), toHidlArray16(iv), 424 hMode, hPattern, hSubSamples, hSource, offset, hDestination, 425 [&](Status status, uint32_t hBytesWritten, hidl_string hDetailedError) { 426 if (status == Status::OK) { 427 bytesWritten = hBytesWritten; 428 *errorDetailMsg = toString8(hDetailedError); 429 } 430 err = toStatusT(status); 431 } 432 ); 433 } 434 435 err = hResult.isOk() ? err : DEAD_OBJECT; 436 if (err == OK) { 437 return bytesWritten; 438 } 439 return err; 440 } 441 442 void CryptoHal::notifyResolution(uint32_t width, uint32_t height) { 443 Mutex::Autolock autoLock(mLock); 444 445 if (mInitCheck != OK) { 446 return; 447 } 448 449 mPlugin->notifyResolution(width, height); 450 } 451 452 status_t CryptoHal::setMediaDrmSession(const Vector<uint8_t> &sessionId) { 453 Mutex::Autolock autoLock(mLock); 454 455 if (mInitCheck != OK) { 456 return mInitCheck; 457 } 458 459 return toStatusT(mPlugin->setMediaDrmSession(toHidlVec(sessionId))); 460 } 461 462 } // namespace android 463