/* * Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary * source code may only be used and distributed under the Widevine Master * License Agreement. */ #include "special_cases.h" #include #include #include #include #include "api_support.h" #include "deserializer.h" #include "OEMCryptoCENC.h" #include "serialization_base.h" #include "shared_memory_allocator.h" #include "shared_memory_interface.h" #include "serializer.h" /* * Special case API functions. DecryptCENC and CopyBuffer have the * |out_buffer| parameter of type OEMCrypt_DestBufferDesc. If the * destination is to non-secure memory, the output data needs to be * copied out from shared memory to the provided destination buffer. * The length of the data is given by the seemingly unrelated input * parameter data_addr_length so it's difficult to auto-generate these * functions. * * To update these functions when the api generator changes, remove them * from special_case_config.cpp, build, then copy the generated code * from oemcrypto_api.c and apply the manual edits. */ OEMCRYPTO_API OEMCryptoResult OEMCrypto_DecryptCENC( OEMCrypto_SESSION session, const SharedMemory *data_addr, size_t data_addr_length, bool is_encrypted, const uint8_t *iv, size_t block_offset, OEMCrypto_DestBufferDesc *out_buffer, const OEMCrypto_CENCEncryptPatternDesc *pattern, uint8_t subsample_flags) { OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; pthread_mutex_lock(&api_lock); Message *request = API_InitializeRequest(); Message *response = NULL; if (!request) { goto cleanup_and_return; } ODK_Pack_DecryptCENC_Request(request, session, data_addr, data_addr_length, is_encrypted, iv, block_offset, out_buffer, pattern, subsample_flags); if (GetStatus(request) != MESSAGE_STATUS_OK) { api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; goto cleanup_and_return; } response = API_Transact(request); if (!response) { goto cleanup_and_return; } ODK_Unpack_DecryptCENC_Response(response, &result, &out_buffer); /* Only this block is hand coded */ if (result == OEMCrypto_SUCCESS) { if (out_buffer->type == OEMCrypto_BufferType_Clear) { uint8_t* shared_address = SharedMemory_GetAddress(DEST_BUFFER_INDEX); if (data_addr_length <= SharedMemory_GetSize(DEST_BUFFER_INDEX)) { memcpy(out_buffer->buffer.clear.address, shared_address, data_addr_length); } else { result = OEMCrypto_ERROR_UNKNOWN_FAILURE; goto cleanup_and_return; } } } if (GetStatus(response) != MESSAGE_STATUS_OK) { api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; goto cleanup_and_return; } cleanup_and_return: if (request) { ODK_Transport_DeallocateMessage(request); } if (response) { ODK_Transport_DeallocateMessage(response); } pthread_mutex_unlock(&api_lock); return API_CheckResult(result); } OEMCRYPTO_API OEMCryptoResult OEMCrypto_CopyBuffer( OEMCrypto_SESSION session, const SharedMemory *data_addr, size_t data_addr_length, OEMCrypto_DestBufferDesc *out_buffer, uint8_t subsample_flags) { OEMCryptoResult result = OEMCrypto_ERROR_UNKNOWN_FAILURE; pthread_mutex_lock(&api_lock); Message *request = API_InitializeRequest(); Message *response = NULL; if (!request) { goto cleanup_and_return; } ODK_Pack_CopyBuffer_Request(request, session, data_addr, data_addr_length, out_buffer, subsample_flags); if (GetStatus(request) != MESSAGE_STATUS_OK) { api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; goto cleanup_and_return; } response = API_Transact(request); if (!response) { goto cleanup_and_return; } ODK_Unpack_CopyBuffer_Response(response, &result, &out_buffer); if (GetStatus(response) != MESSAGE_STATUS_OK) { api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE; goto cleanup_and_return; } /* Only this block is hand coded */ if (result == OEMCrypto_SUCCESS) { if (out_buffer->type == OEMCrypto_BufferType_Clear) { uint8_t* shared_address = SharedMemory_GetAddress(DEST_BUFFER_INDEX); memcpy(out_buffer->buffer.clear.address, shared_address, data_addr_length); } } cleanup_and_return: if (request) { ODK_Transport_DeallocateMessage(request); } if (response) { ODK_Transport_DeallocateMessage(response); } pthread_mutex_unlock(&api_lock); return API_CheckResult(result); }