First Publicly Shared Version of ODKiTEE v15
This commit is contained in:
4334
serialization/OEMCryptoCENC.h
Normal file
4334
serialization/OEMCryptoCENC.h
Normal file
File diff suppressed because it is too large
Load Diff
123
serialization/api_support.c
Normal file
123
serialization/api_support.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Support functions for the OEMCrypto API functions, related to
|
||||
* message handling
|
||||
*/
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "api_support.h"
|
||||
#include "bump_allocator.h"
|
||||
#include "message.h"
|
||||
#include "shared_memory_allocator.h"
|
||||
#include "shared_memory_interface.h"
|
||||
#include "special_cases.h"
|
||||
#include "transport_interface.h"
|
||||
|
||||
/*
|
||||
* If true, the system has been invalidated due to a communications
|
||||
* breakdown with the TEE. This is a persistent condition and will
|
||||
* cause OEMCrypto_ERROR_SYSTEM_INVALIDATED to be returned from any
|
||||
* function that returns an OEMCryptoResult until the transport
|
||||
* interface is reinitialized.
|
||||
*/
|
||||
static bool system_invalidated;
|
||||
|
||||
/*
|
||||
* This is the result code to be returned from any function that
|
||||
* returns OEMCryptoResult code.
|
||||
*/
|
||||
OEMCryptoResult api_result;
|
||||
|
||||
/*
|
||||
* odkitee OEMCrypto API is single threaded
|
||||
*/
|
||||
pthread_mutex_t api_lock;
|
||||
|
||||
/*
|
||||
* Called at the beginning of every API function. Checks configuration
|
||||
* state and if it is okay allocates a request message. Sets
|
||||
* api_result based on the status of the operations, which will be
|
||||
* returned from any API function that returns an OEMCryptoResult
|
||||
* code. On exit, if api_result is not OEMCrypto_SUCCESS or NULL is
|
||||
* returned, then any allocated messages will have been deallocated
|
||||
* prior to returning.
|
||||
*/
|
||||
Message *API_InitializeRequest(void) {
|
||||
api_result = OEMCrypto_SUCCESS;
|
||||
|
||||
SharedMemory_Reset();
|
||||
BumpAllocator_Reset();
|
||||
Message* request = ODK_Transport_AllocateMessage();
|
||||
if (request == NULL) {
|
||||
api_result = OEMCrypto_ERROR_INSUFFICIENT_RESOURCES;
|
||||
} else if (GetStatus(request) != MESSAGE_STATUS_OK) {
|
||||
/* The transport allocator must return initialized messages */
|
||||
api_result = OEMCrypto_ERROR_SYSTEM_INVALIDATED;
|
||||
}
|
||||
if (api_result != OEMCrypto_SUCCESS) {
|
||||
if (request != NULL) {
|
||||
ODK_Transport_DeallocateMessage(request);
|
||||
request = NULL;
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to send the request message to the TEE and receive the
|
||||
* response. Sets api_result based on the status of the
|
||||
* operations. Returns either a valid response message or NULL. If
|
||||
* NULL is returned or api_result != OEMCrypto_SUCCESS then any
|
||||
* allocated messages will have been deallocated prior to returning.
|
||||
*/
|
||||
Message *API_Transact(Message* request) {
|
||||
if (api_result != OEMCrypto_SUCCESS || request == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ODK_Transport_Status transport_status = ODK_Transport_SendMessage(request);
|
||||
Message* response = NULL;
|
||||
if (transport_status == ODK_TRANSPORT_STATUS_IO_ERROR) {
|
||||
api_result = OEMCrypto_ERROR_SYSTEM_INVALIDATED;
|
||||
} else {
|
||||
transport_status = ODK_Transport_ReceiveMessage(&response);
|
||||
if (transport_status == ODK_TRANSPORT_STATUS_IO_ERROR || response == NULL) {
|
||||
api_result = OEMCrypto_ERROR_SYSTEM_INVALIDATED;
|
||||
} else if (GetStatus(response) != MESSAGE_STATUS_OK) {
|
||||
api_result = OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if (api_result != OEMCrypto_SUCCESS) {
|
||||
if (response) {
|
||||
ODK_Transport_DeallocateMessage(response);
|
||||
response = NULL;
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called at the end of every API function. Sets system_invalidated if
|
||||
* the local api_result indicates a failure in the current
|
||||
* function. Once system_invalidated is set, it will persist until
|
||||
* reset by the next OEMCrypto_Inititalize/OEMCrypto_Terminate.
|
||||
*/
|
||||
OEMCryptoResult API_CheckResult(OEMCryptoResult unpacked_result) {
|
||||
if (api_result == OEMCrypto_ERROR_SYSTEM_INVALIDATED) {
|
||||
system_invalidated = true;
|
||||
} else if (api_result == OEMCrypto_SUCCESS) {
|
||||
api_result = unpacked_result;
|
||||
}
|
||||
return api_result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by OEMCrypto_Terminate
|
||||
*/
|
||||
void API_Terminate(void) {
|
||||
system_invalidated = false;
|
||||
}
|
||||
45
serialization/api_support.h
Normal file
45
serialization/api_support.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Support functions for the OEMCrypto API functions, related to
|
||||
* message handling
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "bump_allocator.h"
|
||||
#include "deserializer.h"
|
||||
#include "marshaller_base.h"
|
||||
#include "serializer.h"
|
||||
#include "shared_memory_allocator.h"
|
||||
#include "shared_memory_interface.h"
|
||||
#include "special_cases.h"
|
||||
#include "transport_interface.h"
|
||||
|
||||
#ifndef ODKITEE_API_SUPPORT_H_
|
||||
#define ODKITEE_API_SUPPORT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OEMCRYPTO_API __attribute__((visibility("default")))
|
||||
|
||||
extern pthread_mutex_t api_lock;
|
||||
extern OEMCryptoResult api_result;
|
||||
|
||||
Message *API_InitializeRequest();
|
||||
Message *API_Transact(Message *request);
|
||||
OEMCryptoResult API_CheckResult(OEMCryptoResult unpacked_result);
|
||||
void API_Terminate();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ODKITEE_API_SUPOPRT_H_ */
|
||||
61
serialization/bump_allocator.c
Normal file
61
serialization/bump_allocator.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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 "bump_allocator.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define INITIAL_ALLOCATOR_BUFFER_SIZE (8 * 1024)
|
||||
|
||||
static uint8_t buffer[INITIAL_ALLOCATOR_BUFFER_SIZE];
|
||||
static uint8_t* ptr = buffer;
|
||||
static size_t buffer_size = sizeof(buffer);
|
||||
static size_t buffer_offset = 0;
|
||||
|
||||
uint8_t* BumpAllocate(size_t nbytes) {
|
||||
size_t new_offset = 0;
|
||||
if(__builtin_add_overflow(buffer_offset, nbytes, &new_offset) ||
|
||||
(new_offset > buffer_size)) {
|
||||
/*
|
||||
* The bump allocator buffer should be large enough that a malloc
|
||||
* is never required. But allow a malloc if the buffer overflows.
|
||||
*/
|
||||
fprintf(stderr, "Warning: bump allocator memory size exceeded,"
|
||||
" size=%zd, requested=%zd\n", buffer_size, new_offset);
|
||||
size_t new_size = 2 * buffer_size;
|
||||
uint8_t* new_ptr = malloc(new_size);
|
||||
if (new_ptr == NULL) {
|
||||
fprintf(stderr, "Fatal: bump allocator could not malloc %zd bytes\n",
|
||||
new_size);
|
||||
abort();
|
||||
}
|
||||
memcpy(new_ptr, ptr, buffer_size);
|
||||
memset(new_ptr + buffer_size, 0, buffer_size);
|
||||
buffer_size = new_size;
|
||||
if (ptr != buffer) {
|
||||
free(ptr);
|
||||
}
|
||||
ptr = new_ptr;
|
||||
}
|
||||
uint8_t* result = ptr + buffer_offset;
|
||||
memset(result, 0, nbytes);
|
||||
buffer_offset = new_offset;
|
||||
return result;
|
||||
}
|
||||
|
||||
void BumpAllocator_Reset(void) {
|
||||
buffer_offset = 0;
|
||||
if (ptr != buffer) {
|
||||
free(ptr);
|
||||
}
|
||||
ptr = buffer;
|
||||
buffer_size = sizeof(buffer);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
}
|
||||
|
||||
|
||||
29
serialization/bump_allocator.h
Normal file
29
serialization/bump_allocator.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_BUMP_ALLOCATOR_H_
|
||||
#define ODKITEE_BUMP_ALLOCATOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Simple bump allocator. Allocate memory chunks from a fixed region
|
||||
* at consecutively increasing offsets. The memory is all released
|
||||
* when BumpAllocator_Reset is called.
|
||||
*/
|
||||
uint8_t* BumpAllocate(size_t size);
|
||||
void BumpAllocator_Reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //ODKITEE_BUMP_ALLOCATOR_H_
|
||||
2116
serialization/generated_src/deserializer.c
Normal file
2116
serialization/generated_src/deserializer.c
Normal file
File diff suppressed because it is too large
Load Diff
383
serialization/generated_src/deserializer.h
Normal file
383
serialization/generated_src/deserializer.h
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is auto-generated, do not edit
|
||||
*/
|
||||
#ifndef ODKITEE_DESERIALIZER_H_
|
||||
#define ODKITEE_DESERIALIZER_H_
|
||||
|
||||
#include "deserializer.h"
|
||||
#include "serialization_base.h"
|
||||
#include "serializer.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool Is_Valid_OEMCryptoResult(uint32_t value);
|
||||
bool Is_Valid_OEMCryptoBufferType(uint32_t value);
|
||||
bool Is_Valid_OEMCryptoCipherMode(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_LicenseType(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_Algorithm(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_Usage_Entry_Status(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_Clock_Security_Level(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_HDCP_Capability(uint32_t value);
|
||||
bool Is_Valid_OEMCrypto_ProvisioningMethod(uint32_t value);
|
||||
void ODK_Unpack_OEMCrypto_Substring(Message* msg, OEMCrypto_Substring* obj);
|
||||
void ODK_Unpack_OEMCrypto_KeyObject(Message* msg, OEMCrypto_KeyObject* obj);
|
||||
void ODK_Unpack_OEMCrypto_EntitledContentKeyObject(
|
||||
Message* msg, OEMCrypto_EntitledContentKeyObject* obj);
|
||||
void ODK_Unpack_OEMCrypto_KeyRefreshObject(Message* msg,
|
||||
OEMCrypto_KeyRefreshObject* obj);
|
||||
void ODK_Unpack_OEMCrypto_CENCEncryptPatternDesc(
|
||||
Message* msg, OEMCrypto_CENCEncryptPatternDesc* obj);
|
||||
void ODK_Unpack_SecurityLevel_Request(Message* msg);
|
||||
void ODK_Unpack_SecurityLevel_Response(Message* msg, char** result);
|
||||
void ODK_Unpack_BuildInformation_Request(Message* msg);
|
||||
void ODK_Unpack_BuildInformation_Response(Message* msg, char** result);
|
||||
void ODK_Unpack_SetSandbox_Request(Message* msg, uint8_t** sandbox_id,
|
||||
size_t* sandbox_id_length);
|
||||
void ODK_Unpack_SetSandbox_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_Initialize_Request(Message* msg);
|
||||
void ODK_Unpack_Initialize_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_Terminate_Request(Message* msg);
|
||||
void ODK_Unpack_Terminate_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_OpenSession_Request(Message* msg, OEMCrypto_SESSION** session);
|
||||
void ODK_Unpack_OpenSession_Response(Message* msg, OEMCryptoResult* result,
|
||||
OEMCrypto_SESSION** session);
|
||||
void ODK_Unpack_CloseSession_Request(Message* msg, OEMCrypto_SESSION* session);
|
||||
void ODK_Unpack_CloseSession_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_GenerateDerivedKeys_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
SharedMemory** mac_key_context,
|
||||
uint32_t* mac_key_context_length,
|
||||
SharedMemory** enc_key_context,
|
||||
uint32_t* enc_key_context_length);
|
||||
void ODK_Unpack_GenerateDerivedKeys_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_DeriveKeysFromSessionKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, uint8_t** enc_session_key,
|
||||
size_t* enc_session_key_length, SharedMemory** mac_key_context,
|
||||
size_t* mac_key_context_length, SharedMemory** enc_key_context,
|
||||
size_t* enc_key_context_length);
|
||||
void ODK_Unpack_DeriveKeysFromSessionKey_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_GenerateNonce_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint32_t** nonce);
|
||||
void ODK_Unpack_GenerateNonce_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint32_t** nonce);
|
||||
void ODK_Unpack_GenerateSignature_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** message,
|
||||
size_t* message_length, uint8_t** signature, size_t** signature_length);
|
||||
void ODK_Unpack_GenerateSignature_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** signature,
|
||||
size_t** signature_length);
|
||||
void ODK_Unpack_LoadSRM_Request(Message* msg, uint8_t** buffer,
|
||||
size_t* buffer_length);
|
||||
void ODK_Unpack_LoadSRM_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_LoadKeys_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** message,
|
||||
size_t* message_length, SharedMemory** signature, size_t* signature_length,
|
||||
OEMCrypto_Substring* enc_mac_keys_iv, OEMCrypto_Substring* enc_mac_keys,
|
||||
size_t* key_array_length, OEMCrypto_KeyObject** key_array,
|
||||
OEMCrypto_Substring* pst, OEMCrypto_Substring* srm_restriction_data,
|
||||
OEMCrypto_LicenseType* license_type);
|
||||
void ODK_Unpack_LoadKeys_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_LoadEntitledContentKeys_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** message,
|
||||
size_t* message_length, size_t* key_array_length,
|
||||
OEMCrypto_EntitledContentKeyObject** key_array);
|
||||
void ODK_Unpack_LoadEntitledContentKeys_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_RefreshKeys_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** message,
|
||||
size_t* message_length, SharedMemory** signature, size_t* signature_length,
|
||||
size_t* key_array_length, OEMCrypto_KeyRefreshObject** key_array);
|
||||
void ODK_Unpack_RefreshKeys_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_QueryKeyControl_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint8_t** content_key_id,
|
||||
size_t* content_key_id_length,
|
||||
uint8_t** key_control_block,
|
||||
size_t** key_control_block_length);
|
||||
void ODK_Unpack_QueryKeyControl_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** key_control_block,
|
||||
size_t** key_control_block_length);
|
||||
void ODK_Unpack_SelectKey_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint8_t** content_key_id,
|
||||
size_t* content_key_id_length,
|
||||
OEMCryptoCipherMode* cipher_mode);
|
||||
void ODK_Unpack_SelectKey_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_DecryptCENC_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** data_addr,
|
||||
size_t* data_addr_length, bool* is_encrypted, uint8_t* iv,
|
||||
size_t* block_offset, OEMCrypto_DestBufferDesc** out_buffer,
|
||||
OEMCrypto_CENCEncryptPatternDesc** pattern, uint8_t* subsample_flags);
|
||||
void ODK_Unpack_DecryptCENC_Response(Message* msg, OEMCryptoResult* result,
|
||||
OEMCrypto_DestBufferDesc** out_buffer);
|
||||
void ODK_Unpack_CopyBuffer_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
SharedMemory** data_addr,
|
||||
size_t* data_addr_length,
|
||||
OEMCrypto_DestBufferDesc** out_buffer,
|
||||
uint8_t* subsample_flags);
|
||||
void ODK_Unpack_CopyBuffer_Response(Message* msg, OEMCryptoResult* result,
|
||||
OEMCrypto_DestBufferDesc** out_buffer);
|
||||
void ODK_Unpack_Generic_Encrypt_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
SharedMemory** in_buffer,
|
||||
size_t* in_buffer_length, uint8_t* iv,
|
||||
OEMCrypto_Algorithm* algorithm,
|
||||
uint8_t** out_buffer);
|
||||
void ODK_Unpack_Generic_Encrypt_Response(Message* msg, OEMCryptoResult* result,
|
||||
size_t* in_buffer_length,
|
||||
uint8_t** out_buffer);
|
||||
void ODK_Unpack_Generic_Decrypt_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
SharedMemory** in_buffer,
|
||||
size_t* in_buffer_length, uint8_t* iv,
|
||||
OEMCrypto_Algorithm* algorithm,
|
||||
uint8_t** out_buffer);
|
||||
void ODK_Unpack_Generic_Decrypt_Response(Message* msg, OEMCryptoResult* result,
|
||||
size_t* in_buffer_length,
|
||||
uint8_t** out_buffer);
|
||||
void ODK_Unpack_Generic_Sign_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
SharedMemory** buffer,
|
||||
size_t* buffer_length,
|
||||
OEMCrypto_Algorithm* algorithm,
|
||||
uint8_t** signature,
|
||||
size_t** signature_length);
|
||||
void ODK_Unpack_Generic_Sign_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** signature,
|
||||
size_t** signature_length);
|
||||
void ODK_Unpack_Generic_Verify_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
SharedMemory** buffer,
|
||||
size_t* buffer_length,
|
||||
OEMCrypto_Algorithm* algorithm,
|
||||
SharedMemory** signature,
|
||||
size_t* signature_length);
|
||||
void ODK_Unpack_Generic_Verify_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_UpdateUsageTable_Request(Message* msg);
|
||||
void ODK_Unpack_UpdateUsageTable_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_WrapKeyboxOrOEMCert_Request(Message* msg, uint8_t** rot,
|
||||
size_t* rotLength,
|
||||
uint8_t** wrappedRot,
|
||||
size_t** wrappedRotLength,
|
||||
uint8_t** transportKey,
|
||||
size_t* transportKeyLength);
|
||||
void ODK_Unpack_WrapKeyboxOrOEMCert_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** wrappedRot,
|
||||
size_t** wrappedRotLength);
|
||||
void ODK_Unpack_InstallKeyboxOrOEMCert_Request(Message* msg, uint8_t** rot,
|
||||
size_t* rotLength);
|
||||
void ODK_Unpack_InstallKeyboxOrOEMCert_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_GetProvisioningMethod_Request(Message* msg);
|
||||
void ODK_Unpack_GetProvisioningMethod_Response(
|
||||
Message* msg, OEMCrypto_ProvisioningMethod* result);
|
||||
void ODK_Unpack_IsKeyboxOrOEMCertValid_Request(Message* msg);
|
||||
void ODK_Unpack_IsKeyboxOrOEMCertValid_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_GetDeviceID_Request(Message* msg, uint8_t** device_id,
|
||||
size_t** device_id_length);
|
||||
void ODK_Unpack_GetDeviceID_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** device_id,
|
||||
size_t** device_id_length);
|
||||
void ODK_Unpack_GetKeyData_Request(Message* msg, uint8_t** keyData,
|
||||
size_t** keyDataLength);
|
||||
void ODK_Unpack_GetKeyData_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** keyData, size_t** keyDataLength);
|
||||
void ODK_Unpack_LoadTestKeybox_Request(Message* msg, uint8_t** buffer,
|
||||
size_t* buffer_length);
|
||||
void ODK_Unpack_LoadTestKeybox_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_GetOEMPublicCertificate_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint8_t** public_cert,
|
||||
size_t** public_cert_length);
|
||||
void ODK_Unpack_GetOEMPublicCertificate_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** public_cert,
|
||||
size_t** public_cert_length);
|
||||
void ODK_Unpack_GetRandom_Request(Message* msg, uint8_t** random_data,
|
||||
size_t* random_data_length);
|
||||
void ODK_Unpack_GetRandom_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** random_data,
|
||||
size_t* random_data_length);
|
||||
void ODK_Unpack_APIVersion_Request(Message* msg);
|
||||
void ODK_Unpack_APIVersion_Response(Message* msg, uint32_t* result);
|
||||
void ODK_Unpack_Security_Patch_Level_Request(Message* msg);
|
||||
void ODK_Unpack_Security_Patch_Level_Response(Message* msg, uint8_t* result);
|
||||
void ODK_Unpack_GetHDCPCapability_Request(Message* msg,
|
||||
OEMCrypto_HDCP_Capability** current,
|
||||
OEMCrypto_HDCP_Capability** maximum);
|
||||
void ODK_Unpack_GetHDCPCapability_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
OEMCrypto_HDCP_Capability** current,
|
||||
OEMCrypto_HDCP_Capability** maximum);
|
||||
void ODK_Unpack_SupportsUsageTable_Request(Message* msg);
|
||||
void ODK_Unpack_SupportsUsageTable_Response(Message* msg, bool* result);
|
||||
void ODK_Unpack_IsAntiRollbackHwPresent_Request(Message* msg);
|
||||
void ODK_Unpack_IsAntiRollbackHwPresent_Response(Message* msg, bool* result);
|
||||
void ODK_Unpack_GetNumberOfOpenSessions_Request(Message* msg, size_t** count);
|
||||
void ODK_Unpack_GetNumberOfOpenSessions_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
size_t** count);
|
||||
void ODK_Unpack_GetMaxNumberOfSessions_Request(Message* msg, size_t** max);
|
||||
void ODK_Unpack_GetMaxNumberOfSessions_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
size_t** max);
|
||||
void ODK_Unpack_SupportedCertificates_Request(Message* msg);
|
||||
void ODK_Unpack_SupportedCertificates_Response(Message* msg, uint32_t* result);
|
||||
void ODK_Unpack_IsSRMUpdateSupported_Request(Message* msg);
|
||||
void ODK_Unpack_IsSRMUpdateSupported_Response(Message* msg, bool* result);
|
||||
void ODK_Unpack_GetCurrentSRMVersion_Request(Message* msg, uint16_t** version);
|
||||
void ODK_Unpack_GetCurrentSRMVersion_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint16_t** version);
|
||||
void ODK_Unpack_GetAnalogOutputFlags_Request(Message* msg);
|
||||
void ODK_Unpack_GetAnalogOutputFlags_Response(Message* msg, uint32_t* result);
|
||||
void ODK_Unpack_ResourceRatingTier_Request(Message* msg);
|
||||
void ODK_Unpack_ResourceRatingTier_Response(Message* msg, uint32_t* result);
|
||||
void ODK_Unpack_RewrapDeviceRSAKey30_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, uint32_t** unaligned_nonce,
|
||||
SharedMemory** encrypted_message_key, size_t* encrypted_message_key_length,
|
||||
SharedMemory** enc_rsa_key, size_t* enc_rsa_key_length,
|
||||
uint8_t** enc_rsa_key_iv, uint8_t** wrapped_rsa_key,
|
||||
size_t** wrapped_rsa_key_length);
|
||||
void ODK_Unpack_RewrapDeviceRSAKey30_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** wrapped_rsa_key,
|
||||
size_t** wrapped_rsa_key_length);
|
||||
void ODK_Unpack_RewrapDeviceRSAKey_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** wrapped_rsa_key,
|
||||
size_t** wrapped_rsa_key_length);
|
||||
void ODK_Unpack_LoadDeviceRSAKey_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
SharedMemory** wrapped_rsa_key,
|
||||
size_t* wrapped_rsa_key_length);
|
||||
void ODK_Unpack_LoadDeviceRSAKey_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_LoadTestRSAKey_Request(Message* msg);
|
||||
void ODK_Unpack_LoadTestRSAKey_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_GenerateRSASignature_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, SharedMemory** message,
|
||||
size_t* message_length, uint8_t** signature, size_t** signature_length,
|
||||
RSA_Padding_Scheme* padding_scheme);
|
||||
void ODK_Unpack_GenerateRSASignature_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** signature,
|
||||
size_t** signature_length);
|
||||
void ODK_Unpack_CreateUsageTableHeader_Request(Message* msg,
|
||||
uint8_t** header_buffer,
|
||||
size_t** header_buffer_length);
|
||||
void ODK_Unpack_CreateUsageTableHeader_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** header_buffer,
|
||||
size_t** header_buffer_length);
|
||||
void ODK_Unpack_LoadUsageTableHeader_Request(Message* msg, uint8_t** buffer,
|
||||
size_t* buffer_length);
|
||||
void ODK_Unpack_LoadUsageTableHeader_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_CreateNewUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint32_t** usage_entry_number);
|
||||
void ODK_Unpack_CreateNewUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint32_t** usage_entry_number);
|
||||
void ODK_Unpack_LoadUsageEntry_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint32_t* usage_entry_number,
|
||||
uint8_t** buffer, size_t* buffer_length);
|
||||
void ODK_Unpack_LoadUsageEntry_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_UpdateUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
SharedMemory** header_buffer,
|
||||
size_t** header_buffer_length,
|
||||
SharedMemory** entry_buffer,
|
||||
size_t** entry_buffer_length);
|
||||
void ODK_Unpack_UpdateUsageEntry_Response(Message* msg, OEMCryptoResult* result,
|
||||
SharedMemory** header_buffer,
|
||||
size_t** header_buffer_length,
|
||||
SharedMemory** entry_buffer,
|
||||
size_t** entry_buffer_length);
|
||||
void ODK_Unpack_DeactivateUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint8_t** pst, size_t* pst_length);
|
||||
void ODK_Unpack_DeactivateUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_ReportUsage_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint8_t** pst, size_t* pst_length,
|
||||
uint8_t** buffer, size_t** buffer_length);
|
||||
void ODK_Unpack_ReportUsage_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint8_t** buffer, size_t** buffer_length);
|
||||
void ODK_Unpack_DeleteUsageEntry_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session, uint8_t** pst, size_t* pst_length,
|
||||
uint8_t** message, size_t* message_length, uint8_t** signature,
|
||||
size_t* signature_length);
|
||||
void ODK_Unpack_DeleteUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_ForceDeleteUsageEntry_Request(Message* msg, uint8_t** pst,
|
||||
size_t* pst_length);
|
||||
void ODK_Unpack_ForceDeleteUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_MoveEntry_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint32_t* new_index);
|
||||
void ODK_Unpack_MoveEntry_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_ShrinkUsageTableHeader_Request(Message* msg,
|
||||
uint32_t* new_entry_count,
|
||||
uint8_t** header_buffer,
|
||||
size_t** header_buffer_length);
|
||||
void ODK_Unpack_ShrinkUsageTableHeader_Response(Message* msg,
|
||||
OEMCryptoResult* result,
|
||||
uint8_t** header_buffer,
|
||||
size_t** header_buffer_length);
|
||||
void ODK_Unpack_CopyOldUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint8_t** pst, size_t* pst_length);
|
||||
void ODK_Unpack_CopyOldUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_DeleteOldUsageTable_Request(Message* msg);
|
||||
void ODK_Unpack_DeleteOldUsageTable_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_RemoveSRM_Request(Message* msg);
|
||||
void ODK_Unpack_RemoveSRM_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_CreateOldUsageEntry_Request(
|
||||
Message* msg, uint64_t* time_since_license_received,
|
||||
uint64_t* time_since_first_decrypt, uint64_t* time_since_last_decrypt,
|
||||
OEMCrypto_Usage_Entry_Status* status, uint8_t* server_mac_key,
|
||||
uint8_t* client_mac_key, uint8_t** pst, size_t* pst_length);
|
||||
void ODK_Unpack_CreateOldUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult* result);
|
||||
void ODK_Unpack_SupportsDecryptHash_Request(Message* msg);
|
||||
void ODK_Unpack_SupportsDecryptHash_Response(Message* msg, uint32_t* result);
|
||||
void ODK_Unpack_SetDecryptHash_Request(Message* msg, OEMCrypto_SESSION* session,
|
||||
uint32_t* frame_number, uint8_t** hash,
|
||||
size_t* hash_length);
|
||||
void ODK_Unpack_SetDecryptHash_Response(Message* msg, OEMCryptoResult* result);
|
||||
void ODK_Unpack_GetHashErrorCode_Request(Message* msg,
|
||||
OEMCrypto_SESSION* session,
|
||||
uint32_t** failed_frame_number);
|
||||
void ODK_Unpack_GetHashErrorCode_Response(Message* msg, OEMCryptoResult* result,
|
||||
uint32_t** failed_frame_number);
|
||||
void ODK_UnpackNullable_c_str(Message* msg, char** value);
|
||||
void ODK_UnpackAlloc_c_str(Message* msg, char** value);
|
||||
void ODK_UnpackNullable_uint32_t(Message* msg, OEMCrypto_SESSION** value);
|
||||
void ODK_UnpackAlloc_uint32_t(Message* msg, OEMCrypto_SESSION** value);
|
||||
void ODK_UnpackNullable_size_t(Message* msg, size_t** value);
|
||||
void ODK_UnpackNullable_OEMCrypto_DestBufferDesc(
|
||||
Message* msg, OEMCrypto_DestBufferDesc** value);
|
||||
void ODK_UnpackNullable_OEMCrypto_CENCEncryptPatternDesc(
|
||||
Message* msg, OEMCrypto_CENCEncryptPatternDesc** value);
|
||||
void ODK_UnpackAlloc_size_t(Message* msg, size_t** value);
|
||||
void ODK_UnpackNullable_uint16_t(Message* msg, uint16_t** value);
|
||||
void ODK_UnpackAlloc_uint16_t(Message* msg, uint16_t** value);
|
||||
void ODK_UnpackNullable_uint8_t(Message* msg, uint8_t** value);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif /* ODKITEE_DESERIALIZER_H_ */
|
||||
1499
serialization/generated_src/dispatcher.c
Normal file
1499
serialization/generated_src/dispatcher.c
Normal file
File diff suppressed because it is too large
Load Diff
2473
serialization/generated_src/oemcrypto_api.c
Normal file
2473
serialization/generated_src/oemcrypto_api.c
Normal file
File diff suppressed because it is too large
Load Diff
1495
serialization/generated_src/serializer.c
Normal file
1495
serialization/generated_src/serializer.c
Normal file
File diff suppressed because it is too large
Load Diff
369
serialization/generated_src/serializer.h
Normal file
369
serialization/generated_src/serializer.h
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is auto-generated, do not edit
|
||||
*/
|
||||
#ifndef ODKITEE_SERIALIZER_H_
|
||||
#define ODKITEE_SERIALIZER_H_
|
||||
|
||||
#include "deserializer.h"
|
||||
#include "serialization_base.h"
|
||||
#include "serializer.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool SuccessResult(OEMCryptoResult result);
|
||||
void ODK_Pack_OEMCrypto_Substring(Message* msg, OEMCrypto_Substring const* obj);
|
||||
void ODK_Pack_OEMCrypto_KeyObject(Message* msg, OEMCrypto_KeyObject const* obj);
|
||||
void ODK_Pack_OEMCrypto_EntitledContentKeyObject(
|
||||
Message* msg, OEMCrypto_EntitledContentKeyObject const* obj);
|
||||
void ODK_Pack_OEMCrypto_KeyRefreshObject(Message* msg,
|
||||
OEMCrypto_KeyRefreshObject const* obj);
|
||||
void ODK_Pack_OEMCrypto_CENCEncryptPatternDesc(
|
||||
Message* msg, OEMCrypto_CENCEncryptPatternDesc const* obj);
|
||||
void ODK_Pack_SecurityLevel_Request(Message* msg);
|
||||
void ODK_Pack_SecurityLevel_Response(Message* msg, const char* result);
|
||||
void ODK_Pack_BuildInformation_Request(Message* msg);
|
||||
void ODK_Pack_BuildInformation_Response(Message* msg, const char* result);
|
||||
void ODK_Pack_SetSandbox_Request(Message* msg, const uint8_t* sandbox_id,
|
||||
size_t sandbox_id_length);
|
||||
void ODK_Pack_SetSandbox_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_Initialize_Request(Message* msg);
|
||||
void ODK_Pack_Initialize_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_Terminate_Request(Message* msg);
|
||||
void ODK_Pack_Terminate_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_OpenSession_Request(Message* msg,
|
||||
const OEMCrypto_SESSION* session);
|
||||
void ODK_Pack_OpenSession_Response(Message* msg, OEMCryptoResult result,
|
||||
const OEMCrypto_SESSION* session);
|
||||
void ODK_Pack_CloseSession_Request(Message* msg, OEMCrypto_SESSION session);
|
||||
void ODK_Pack_CloseSession_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_GenerateDerivedKeys_Request(Message* msg,
|
||||
OEMCrypto_SESSION session,
|
||||
const SharedMemory* mac_key_context,
|
||||
uint32_t mac_key_context_length,
|
||||
const SharedMemory* enc_key_context,
|
||||
uint32_t enc_key_context_length);
|
||||
void ODK_Pack_GenerateDerivedKeys_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_DeriveKeysFromSessionKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const uint8_t* enc_session_key,
|
||||
size_t enc_session_key_length, const SharedMemory* mac_key_context,
|
||||
size_t mac_key_context_length, const SharedMemory* enc_key_context,
|
||||
size_t enc_key_context_length);
|
||||
void ODK_Pack_DeriveKeysFromSessionKey_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_GenerateNonce_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint32_t* nonce);
|
||||
void ODK_Pack_GenerateNonce_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint32_t* nonce);
|
||||
void ODK_Pack_GenerateSignature_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* message,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
const size_t* signature_length);
|
||||
void ODK_Pack_GenerateSignature_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* signature,
|
||||
const size_t* signature_length);
|
||||
void ODK_Pack_LoadSRM_Request(Message* msg, const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
void ODK_Pack_LoadSRM_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_LoadKeys_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const SharedMemory* message,
|
||||
size_t message_length, const SharedMemory* signature,
|
||||
size_t signature_length, OEMCrypto_Substring enc_mac_keys_iv,
|
||||
OEMCrypto_Substring enc_mac_keys, size_t key_array_length,
|
||||
const OEMCrypto_KeyObject* key_array, OEMCrypto_Substring pst,
|
||||
OEMCrypto_Substring srm_restriction_data,
|
||||
OEMCrypto_LicenseType license_type);
|
||||
void ODK_Pack_LoadKeys_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_LoadEntitledContentKeys_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const SharedMemory* message,
|
||||
size_t message_length, size_t key_array_length,
|
||||
const OEMCrypto_EntitledContentKeyObject* key_array);
|
||||
void ODK_Pack_LoadEntitledContentKeys_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_RefreshKeys_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* message,
|
||||
size_t message_length,
|
||||
const SharedMemory* signature,
|
||||
size_t signature_length,
|
||||
size_t key_array_length,
|
||||
const OEMCrypto_KeyRefreshObject* key_array);
|
||||
void ODK_Pack_RefreshKeys_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_QueryKeyControl_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* content_key_id,
|
||||
size_t content_key_id_length,
|
||||
const uint8_t* key_control_block,
|
||||
const size_t* key_control_block_length);
|
||||
void ODK_Pack_QueryKeyControl_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* key_control_block,
|
||||
const size_t* key_control_block_length);
|
||||
void ODK_Pack_SelectKey_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* content_key_id,
|
||||
size_t content_key_id_length,
|
||||
OEMCryptoCipherMode cipher_mode);
|
||||
void ODK_Pack_SelectKey_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_DecryptCENC_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const SharedMemory* data_addr,
|
||||
size_t data_addr_length, bool is_encrypted, const uint8_t* iv,
|
||||
size_t block_offset, const OEMCrypto_DestBufferDesc* out_buffer,
|
||||
const OEMCrypto_CENCEncryptPatternDesc* pattern, uint8_t subsample_flags);
|
||||
void ODK_Pack_DecryptCENC_Response(Message* msg, OEMCryptoResult result,
|
||||
const OEMCrypto_DestBufferDesc* out_buffer);
|
||||
void ODK_Pack_CopyBuffer_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* data_addr,
|
||||
size_t data_addr_length,
|
||||
const OEMCrypto_DestBufferDesc* out_buffer,
|
||||
uint8_t subsample_flags);
|
||||
void ODK_Pack_CopyBuffer_Response(Message* msg, OEMCryptoResult result,
|
||||
const OEMCrypto_DestBufferDesc* out_buffer);
|
||||
void ODK_Pack_Generic_Encrypt_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* in_buffer,
|
||||
size_t in_buffer_length,
|
||||
const uint8_t* iv,
|
||||
OEMCrypto_Algorithm algorithm,
|
||||
const uint8_t* out_buffer);
|
||||
void ODK_Pack_Generic_Encrypt_Response(Message* msg, OEMCryptoResult result,
|
||||
size_t in_buffer_length,
|
||||
const uint8_t* out_buffer);
|
||||
void ODK_Pack_Generic_Decrypt_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* in_buffer,
|
||||
size_t in_buffer_length,
|
||||
const uint8_t* iv,
|
||||
OEMCrypto_Algorithm algorithm,
|
||||
const uint8_t* out_buffer);
|
||||
void ODK_Pack_Generic_Decrypt_Response(Message* msg, OEMCryptoResult result,
|
||||
size_t in_buffer_length,
|
||||
const uint8_t* out_buffer);
|
||||
void ODK_Pack_Generic_Sign_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* buffer,
|
||||
size_t buffer_length,
|
||||
OEMCrypto_Algorithm algorithm,
|
||||
const uint8_t* signature,
|
||||
const size_t* signature_length);
|
||||
void ODK_Pack_Generic_Sign_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* signature,
|
||||
const size_t* signature_length);
|
||||
void ODK_Pack_Generic_Verify_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* buffer,
|
||||
size_t buffer_length,
|
||||
OEMCrypto_Algorithm algorithm,
|
||||
const SharedMemory* signature,
|
||||
size_t signature_length);
|
||||
void ODK_Pack_Generic_Verify_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_UpdateUsageTable_Request(Message* msg);
|
||||
void ODK_Pack_UpdateUsageTable_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_WrapKeyboxOrOEMCert_Request(Message* msg, const uint8_t* rot,
|
||||
size_t rotLength,
|
||||
const uint8_t* wrappedRot,
|
||||
const size_t* wrappedRotLength,
|
||||
const uint8_t* transportKey,
|
||||
size_t transportKeyLength);
|
||||
void ODK_Pack_WrapKeyboxOrOEMCert_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* wrappedRot,
|
||||
const size_t* wrappedRotLength);
|
||||
void ODK_Pack_InstallKeyboxOrOEMCert_Request(Message* msg, const uint8_t* rot,
|
||||
size_t rotLength);
|
||||
void ODK_Pack_InstallKeyboxOrOEMCert_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_GetProvisioningMethod_Request(Message* msg);
|
||||
void ODK_Pack_GetProvisioningMethod_Response(
|
||||
Message* msg, OEMCrypto_ProvisioningMethod result);
|
||||
void ODK_Pack_IsKeyboxOrOEMCertValid_Request(Message* msg);
|
||||
void ODK_Pack_IsKeyboxOrOEMCertValid_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_GetDeviceID_Request(Message* msg, const uint8_t* device_id,
|
||||
const size_t* device_id_length);
|
||||
void ODK_Pack_GetDeviceID_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* device_id,
|
||||
const size_t* device_id_length);
|
||||
void ODK_Pack_GetKeyData_Request(Message* msg, const uint8_t* keyData,
|
||||
const size_t* keyDataLength);
|
||||
void ODK_Pack_GetKeyData_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* keyData,
|
||||
const size_t* keyDataLength);
|
||||
void ODK_Pack_LoadTestKeybox_Request(Message* msg, const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
void ODK_Pack_LoadTestKeybox_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_GetOEMPublicCertificate_Request(Message* msg,
|
||||
OEMCrypto_SESSION session,
|
||||
const uint8_t* public_cert,
|
||||
const size_t* public_cert_length);
|
||||
void ODK_Pack_GetOEMPublicCertificate_Response(
|
||||
Message* msg, OEMCryptoResult result, const uint8_t* public_cert,
|
||||
const size_t* public_cert_length);
|
||||
void ODK_Pack_GetRandom_Request(Message* msg, const uint8_t* random_data,
|
||||
size_t random_data_length);
|
||||
void ODK_Pack_GetRandom_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* random_data,
|
||||
size_t random_data_length);
|
||||
void ODK_Pack_APIVersion_Request(Message* msg);
|
||||
void ODK_Pack_APIVersion_Response(Message* msg, uint32_t result);
|
||||
void ODK_Pack_Security_Patch_Level_Request(Message* msg);
|
||||
void ODK_Pack_Security_Patch_Level_Response(Message* msg, uint8_t result);
|
||||
void ODK_Pack_GetHDCPCapability_Request(
|
||||
Message* msg, const OEMCrypto_HDCP_Capability* current,
|
||||
const OEMCrypto_HDCP_Capability* maximum);
|
||||
void ODK_Pack_GetHDCPCapability_Response(
|
||||
Message* msg, OEMCryptoResult result,
|
||||
const OEMCrypto_HDCP_Capability* current,
|
||||
const OEMCrypto_HDCP_Capability* maximum);
|
||||
void ODK_Pack_SupportsUsageTable_Request(Message* msg);
|
||||
void ODK_Pack_SupportsUsageTable_Response(Message* msg, bool result);
|
||||
void ODK_Pack_IsAntiRollbackHwPresent_Request(Message* msg);
|
||||
void ODK_Pack_IsAntiRollbackHwPresent_Response(Message* msg, bool result);
|
||||
void ODK_Pack_GetNumberOfOpenSessions_Request(Message* msg,
|
||||
const size_t* count);
|
||||
void ODK_Pack_GetNumberOfOpenSessions_Response(Message* msg,
|
||||
OEMCryptoResult result,
|
||||
const size_t* count);
|
||||
void ODK_Pack_GetMaxNumberOfSessions_Request(Message* msg, const size_t* max);
|
||||
void ODK_Pack_GetMaxNumberOfSessions_Response(Message* msg,
|
||||
OEMCryptoResult result,
|
||||
const size_t* max);
|
||||
void ODK_Pack_SupportedCertificates_Request(Message* msg);
|
||||
void ODK_Pack_SupportedCertificates_Response(Message* msg, uint32_t result);
|
||||
void ODK_Pack_IsSRMUpdateSupported_Request(Message* msg);
|
||||
void ODK_Pack_IsSRMUpdateSupported_Response(Message* msg, bool result);
|
||||
void ODK_Pack_GetCurrentSRMVersion_Request(Message* msg,
|
||||
const uint16_t* version);
|
||||
void ODK_Pack_GetCurrentSRMVersion_Response(Message* msg,
|
||||
OEMCryptoResult result,
|
||||
const uint16_t* version);
|
||||
void ODK_Pack_GetAnalogOutputFlags_Request(Message* msg);
|
||||
void ODK_Pack_GetAnalogOutputFlags_Response(Message* msg, uint32_t result);
|
||||
void ODK_Pack_ResourceRatingTier_Request(Message* msg);
|
||||
void ODK_Pack_ResourceRatingTier_Response(Message* msg, uint32_t result);
|
||||
void ODK_Pack_RewrapDeviceRSAKey30_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const uint32_t* unaligned_nonce,
|
||||
const SharedMemory* encrypted_message_key,
|
||||
size_t encrypted_message_key_length, const SharedMemory* enc_rsa_key,
|
||||
size_t enc_rsa_key_length, const uint8_t* enc_rsa_key_iv,
|
||||
const uint8_t* wrapped_rsa_key, const size_t* wrapped_rsa_key_length);
|
||||
void ODK_Pack_RewrapDeviceRSAKey30_Response(
|
||||
Message* msg, OEMCryptoResult result, const uint8_t* wrapped_rsa_key,
|
||||
const size_t* wrapped_rsa_key_length);
|
||||
void ODK_Pack_RewrapDeviceRSAKey_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* wrapped_rsa_key,
|
||||
const size_t* wrapped_rsa_key_length);
|
||||
void ODK_Pack_LoadDeviceRSAKey_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* wrapped_rsa_key,
|
||||
size_t wrapped_rsa_key_length);
|
||||
void ODK_Pack_LoadDeviceRSAKey_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_LoadTestRSAKey_Request(Message* msg);
|
||||
void ODK_Pack_LoadTestRSAKey_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_GenerateRSASignature_Request(
|
||||
Message* msg, OEMCrypto_SESSION session, const SharedMemory* message,
|
||||
size_t message_length, const uint8_t* signature,
|
||||
const size_t* signature_length, RSA_Padding_Scheme padding_scheme);
|
||||
void ODK_Pack_GenerateRSASignature_Response(Message* msg,
|
||||
OEMCryptoResult result,
|
||||
const uint8_t* signature,
|
||||
const size_t* signature_length);
|
||||
void ODK_Pack_CreateUsageTableHeader_Request(
|
||||
Message* msg, const uint8_t* header_buffer,
|
||||
const size_t* header_buffer_length);
|
||||
void ODK_Pack_CreateUsageTableHeader_Response(
|
||||
Message* msg, OEMCryptoResult result, const uint8_t* header_buffer,
|
||||
const size_t* header_buffer_length);
|
||||
void ODK_Pack_LoadUsageTableHeader_Request(Message* msg, const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
void ODK_Pack_LoadUsageTableHeader_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_CreateNewUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION session,
|
||||
const uint32_t* usage_entry_number);
|
||||
void ODK_Pack_CreateNewUsageEntry_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint32_t* usage_entry_number);
|
||||
void ODK_Pack_LoadUsageEntry_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
uint32_t usage_entry_number,
|
||||
const uint8_t* buffer,
|
||||
size_t buffer_length);
|
||||
void ODK_Pack_LoadUsageEntry_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_UpdateUsageEntry_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const SharedMemory* header_buffer,
|
||||
const size_t* header_buffer_length,
|
||||
const SharedMemory* entry_buffer,
|
||||
const size_t* entry_buffer_length);
|
||||
void ODK_Pack_UpdateUsageEntry_Response(Message* msg, OEMCryptoResult result,
|
||||
const SharedMemory* header_buffer,
|
||||
const size_t* header_buffer_length,
|
||||
const SharedMemory* entry_buffer,
|
||||
const size_t* entry_buffer_length);
|
||||
void ODK_Pack_DeactivateUsageEntry_Request(Message* msg,
|
||||
OEMCrypto_SESSION session,
|
||||
const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
void ODK_Pack_DeactivateUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_ReportUsage_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* pst, size_t pst_length,
|
||||
const uint8_t* buffer,
|
||||
const size_t* buffer_length);
|
||||
void ODK_Pack_ReportUsage_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint8_t* buffer,
|
||||
const size_t* buffer_length);
|
||||
void ODK_Pack_DeleteUsageEntry_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* pst, size_t pst_length,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length);
|
||||
void ODK_Pack_DeleteUsageEntry_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_ForceDeleteUsageEntry_Request(Message* msg, const uint8_t* pst,
|
||||
size_t pst_length);
|
||||
void ODK_Pack_ForceDeleteUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_MoveEntry_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
uint32_t new_index);
|
||||
void ODK_Pack_MoveEntry_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_ShrinkUsageTableHeader_Request(
|
||||
Message* msg, uint32_t new_entry_count, const uint8_t* header_buffer,
|
||||
const size_t* header_buffer_length);
|
||||
void ODK_Pack_ShrinkUsageTableHeader_Response(
|
||||
Message* msg, OEMCryptoResult result, const uint8_t* header_buffer,
|
||||
const size_t* header_buffer_length);
|
||||
void ODK_Pack_CopyOldUsageEntry_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* pst, size_t pst_length);
|
||||
void ODK_Pack_CopyOldUsageEntry_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_DeleteOldUsageTable_Request(Message* msg);
|
||||
void ODK_Pack_DeleteOldUsageTable_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_RemoveSRM_Request(Message* msg);
|
||||
void ODK_Pack_RemoveSRM_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_CreateOldUsageEntry_Request(
|
||||
Message* msg, uint64_t time_since_license_received,
|
||||
uint64_t time_since_first_decrypt, uint64_t time_since_last_decrypt,
|
||||
OEMCrypto_Usage_Entry_Status status, const uint8_t* server_mac_key,
|
||||
const uint8_t* client_mac_key, const uint8_t* pst, size_t pst_length);
|
||||
void ODK_Pack_CreateOldUsageEntry_Response(Message* msg,
|
||||
OEMCryptoResult result);
|
||||
void ODK_Pack_SupportsDecryptHash_Request(Message* msg);
|
||||
void ODK_Pack_SupportsDecryptHash_Response(Message* msg, uint32_t result);
|
||||
void ODK_Pack_SetDecryptHash_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
uint32_t frame_number, const uint8_t* hash,
|
||||
size_t hash_length);
|
||||
void ODK_Pack_SetDecryptHash_Response(Message* msg, OEMCryptoResult result);
|
||||
void ODK_Pack_GetHashErrorCode_Request(Message* msg, OEMCrypto_SESSION session,
|
||||
const uint32_t* failed_frame_number);
|
||||
void ODK_Pack_GetHashErrorCode_Response(Message* msg, OEMCryptoResult result,
|
||||
const uint32_t* failed_frame_number);
|
||||
void ODK_PackNullable_c_str(Message* msg, const char* value);
|
||||
void ODK_PackNullable_uint32_t(Message* msg, const OEMCrypto_SESSION* value);
|
||||
void ODK_PackNullable_size_t(Message* msg, const size_t* value);
|
||||
void ODK_PackNullable_OEMCrypto_DestBufferDesc(
|
||||
Message* msg, const OEMCrypto_DestBufferDesc* value);
|
||||
void ODK_PackNullable_OEMCrypto_CENCEncryptPatternDesc(
|
||||
Message* msg, const OEMCrypto_CENCEncryptPatternDesc* value);
|
||||
void ODK_PackNullable_uint16_t(Message* msg, const uint16_t* value);
|
||||
void ODK_PackNullable_uint8_t(Message* msg, const uint8_t* value);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif /* ODKITEE_SERIALIZER_H_ */
|
||||
95
serialization/marshaller_base.c
Normal file
95
serialization/marshaller_base.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 "bump_allocator.h"
|
||||
#include "marshaller_base.h"
|
||||
|
||||
static void InitBytes(uint8_t* ptr, size_t count) {
|
||||
if (ptr && count) {
|
||||
memset(ptr, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The functions here are declared weak so they can
|
||||
* be overriden by test functions that inject
|
||||
* various initialized values for testing
|
||||
*/
|
||||
|
||||
__attribute__((weak)) void Init_bool(bool* value) {
|
||||
if (value) {
|
||||
*value = false;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_size_t(size_t* value) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_c_str(char** value) {
|
||||
if (value) {
|
||||
*value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_uint8_t(uint8_t* value) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_uint16_t(uint16_t* value) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_uint32_t(uint32_t* value) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void Init_uint64_t(uint64_t* value) {
|
||||
if (value) {
|
||||
*value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void InitMemory(uint8_t* address, size_t length)
|
||||
{
|
||||
if (address && length) {
|
||||
InitBytes(address, length);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((weak)) void InitPointer(uint8_t** ptr) {
|
||||
if (ptr) {
|
||||
*ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate memory for a variable from the bump allocator, used for
|
||||
* DeclarePackVar, DeclareUnpackVar, for some pointer types
|
||||
*/
|
||||
__attribute__((weak)) uint8_t* VarAlloc(size_t size) {
|
||||
return BumpAllocate(size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Special cases due to union & shared memory
|
||||
*/
|
||||
__attribute__((weak)) void Init_OEMCrypto_DestBufferDesc(OEMCrypto_DestBufferDesc* d) {
|
||||
if (d) {
|
||||
d->type = OEMCrypto_BufferType_Clear;
|
||||
d->buffer.clear.address = NULL;
|
||||
d->buffer.clear.max_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
55
serialization/marshaller_base.h
Normal file
55
serialization/marshaller_base.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_MARSHALLER_BASE_H_
|
||||
#define ODKITEE_MARSHALLER_BASE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "serialization_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _Message Message;
|
||||
|
||||
/*
|
||||
* When packing a pointer to size_t, and the pointer is null, pass
|
||||
* this special value of size_t instead
|
||||
*/
|
||||
#define SZ_NULL (size_t)~0
|
||||
|
||||
void Init_bool(bool* value);
|
||||
void Init_size_t(size_t* value);
|
||||
void Init_c_str(char** value);
|
||||
void Init_uint8_t(uint8_t* value);
|
||||
void Init_uint16_t(uint16_t* value);
|
||||
void Init_uint32_t(uint32_t* value);
|
||||
void Init_uint64_t(uint64_t* value);
|
||||
void InitMemory(uint8_t* addr, size_t length);
|
||||
void InitPointer(uint8_t** addr);
|
||||
|
||||
/*
|
||||
* Allocate memory for a variable from the bump allocator, used for
|
||||
* DeclarePackVar, DeclareUnpackVar, for some pointer types
|
||||
*/
|
||||
uint8_t* VarAlloc(size_t size);
|
||||
|
||||
/*
|
||||
* Special cases due to union & shared memory
|
||||
*/
|
||||
void Init_OEMCrypto_DestBufferDesc(OEMCrypto_DestBufferDesc* desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ODKITEE_MARSHALLER_BASE_H_
|
||||
101
serialization/message.c
Normal file
101
serialization/message.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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 "message.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Round up address to the nearest 8 byte boundary */
|
||||
#define align_8(addr) (((uintptr_t)(addr) + 7) & ~(uintptr_t)7)
|
||||
|
||||
struct _Message {
|
||||
uint8_t* base;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
size_t read_offset;
|
||||
MessageStatus status;
|
||||
};
|
||||
|
||||
/*
|
||||
* The message structure, which is separate from the buffer,
|
||||
* is initialized to reference the buffer
|
||||
*/
|
||||
void InitMessage(Message* message, uint8_t* buffer, size_t capacity) {
|
||||
assert(message != NULL);
|
||||
assert(buffer != NULL);
|
||||
message->base = buffer;
|
||||
message->capacity = capacity;
|
||||
message->size = 0;
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cast pointer of Message from the input buffer. Since Message* is 8-byte
|
||||
* aligned on a 64-bit system, or 4-byte aligned on a 32-bit system, the input
|
||||
* buffer needs to be adjusted to 8-byte alignment before pointer casting, in
|
||||
* order to avoid misaligned pointer
|
||||
*/
|
||||
Message* CreateMessage(uint8_t* buffer, size_t buffer_size) {
|
||||
assert(buffer != NULL);
|
||||
uint8_t* const buffer_aligned = (uint8_t* const)align_8(buffer);
|
||||
assert(buffer_size >= sizeof(Message) + (size_t)(buffer_aligned - buffer));
|
||||
Message* const message = (Message* const)buffer_aligned;
|
||||
message->base = buffer_aligned + sizeof(Message);
|
||||
message->capacity =
|
||||
buffer_size - sizeof(Message) - (size_t)(buffer_aligned - buffer);
|
||||
message->size = 0;
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
return message;
|
||||
}
|
||||
|
||||
void ClearMessage(Message* message) {
|
||||
assert(message != NULL);
|
||||
message->size = 0;
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
void ResetMessage(Message* message) {
|
||||
assert(message != NULL);
|
||||
message->read_offset = 0;
|
||||
message->status = MESSAGE_STATUS_OK;
|
||||
}
|
||||
|
||||
uint8_t* GetBase(Message* message) {
|
||||
assert(message != NULL);
|
||||
return message->base;
|
||||
}
|
||||
|
||||
size_t GetCapacity(Message* message) {
|
||||
assert(message != NULL);
|
||||
return message->capacity;
|
||||
}
|
||||
|
||||
size_t GetSize(Message* message) {
|
||||
assert(message != NULL);
|
||||
return message->size;
|
||||
}
|
||||
|
||||
MessageStatus GetStatus(Message* message) {
|
||||
assert(message != NULL);
|
||||
return message->status;
|
||||
}
|
||||
|
||||
void SetStatus(Message* message, MessageStatus status) {
|
||||
assert(message != NULL);
|
||||
message->status = status;
|
||||
}
|
||||
|
||||
void SetSize(Message* message, size_t size) {
|
||||
assert(message != NULL);
|
||||
message->size = size;
|
||||
}
|
||||
103
serialization/message.h
Normal file
103
serialization/message.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_MESSAGE_H_
|
||||
#define ODKITEE_MESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _Message Message;
|
||||
|
||||
/*
|
||||
* TODO: there is a dangerous duplication of the MessageStatus
|
||||
* enum with odk/src/serialization_base.h. The two need to
|
||||
* be converged. Removing the random enum values here, since
|
||||
* a proper fix is outside the scope of the current CL. Opened
|
||||
* b/158603784.
|
||||
*/
|
||||
typedef enum {
|
||||
MESSAGE_STATUS_OK,
|
||||
MESSAGE_STATUS_UNKNOWN_ERROR,
|
||||
MESSAGE_STATUS_OVERFLOW_ERROR,
|
||||
MESSAGE_STATUS_UNDERFLOW_ERROR,
|
||||
MESSAGE_STATUS_PARSE_ERROR,
|
||||
MESSAGE_STATUS_NULL_POINTER_ERROR,
|
||||
MESSAGE_STATUS_API_VALUE_ERROR,
|
||||
MESSAGE_STATUS_INVALID_TAG_ERROR,
|
||||
MESSAGE_STATUS_END_OF_MESSAGE_ERROR,
|
||||
MESSAGE_STATUS_INVALID_ENUM_VALUE
|
||||
} MessageStatus;
|
||||
|
||||
/*
|
||||
* Create a message from a buffer. The message structure consumes the first
|
||||
* sizeof(Message) bytes of the buffer. The caller is responsible for ensuring
|
||||
* that the buffer remains allocated for the lifetime of the message.
|
||||
*/
|
||||
Message* CreateMessage(uint8_t* buffer, size_t buffer_size);
|
||||
|
||||
/*
|
||||
* Initialize a message structure to reference a separate buffer. The caller
|
||||
* is responsible for ensuring that the buffer remains allocated for the
|
||||
* lifetime of the message.
|
||||
*/
|
||||
void InitMessage(Message* message, uint8_t* buffer, size_t capacity);
|
||||
|
||||
/*
|
||||
* Erase the contents of the message, set it
|
||||
* to an empty state.
|
||||
*/
|
||||
void ClearMessage(Message* message);
|
||||
|
||||
/*
|
||||
* Reset read pointer to the beginning of the
|
||||
* message and clear status
|
||||
*/
|
||||
void ResetMessage(Message* message);
|
||||
|
||||
/*
|
||||
* The message base is the start of the payload
|
||||
*/
|
||||
uint8_t* GetBase(Message* message);
|
||||
|
||||
/*
|
||||
* Get the maximum number of bytes the message
|
||||
* can hold.
|
||||
*/
|
||||
size_t GetCapacity(Message* message);
|
||||
|
||||
/*
|
||||
* Get the number of bytes currently in the
|
||||
* message
|
||||
*/
|
||||
size_t GetSize(Message* message);
|
||||
|
||||
/*
|
||||
* Return the status of the message
|
||||
*/
|
||||
MessageStatus GetStatus(Message* message);
|
||||
|
||||
/*
|
||||
* Set the message status to a specific value
|
||||
*/
|
||||
void SetStatus(Message* message, MessageStatus status);
|
||||
|
||||
/*
|
||||
* Set the size of the message to a value. This
|
||||
* may be needed after writing data into the payload.
|
||||
*/
|
||||
void SetSize(Message*message, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ODKITEE_MESSAGE_H_
|
||||
|
||||
642
serialization/serialization_base.c
Normal file
642
serialization/serialization_base.c
Normal file
@@ -0,0 +1,642 @@
|
||||
/*
|
||||
* 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 "serialization_base.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "bump_allocator.h"
|
||||
#include "marshaller_base.h"
|
||||
#include "shared_memory_allocator.h"
|
||||
#include "shared_memory_interface.h"
|
||||
|
||||
struct _Message {
|
||||
uint8_t* base;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
size_t read_offset;
|
||||
MessageStatus status;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TAG_INVALID,
|
||||
TAG_BOOL,
|
||||
TAG_SIZE_T,
|
||||
TAG_UINT8,
|
||||
TAG_UINT16,
|
||||
TAG_UINT32,
|
||||
TAG_UINT64,
|
||||
TAG_MEMORY,
|
||||
TAG_SHARED_MEMORY,
|
||||
TAG_EOM
|
||||
} TagType;
|
||||
|
||||
static bool ValidMessage(Message* message) {
|
||||
if (message == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (message->status != MESSAGE_STATUS_OK) {
|
||||
return false;
|
||||
}
|
||||
if (message->base == NULL) {
|
||||
message->status = MESSAGE_STATUS_NULL_POINTER_ERROR;
|
||||
return false;
|
||||
}
|
||||
if (message->read_offset > message->capacity ||
|
||||
message->size > message->capacity ||
|
||||
message->read_offset > message->size) {
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool NullCheck(Message* message, const void* ptr) {
|
||||
if (!ptr) {
|
||||
message->status = MESSAGE_STATUS_NULL_POINTER_ERROR;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Callers are expected to have validated the message already */
|
||||
static void PackBytes(Message* message, const uint8_t* ptr, size_t count) {
|
||||
if (!NullCheck(message, ptr)) {
|
||||
if (count <= message->capacity - message->size) {
|
||||
memcpy(message->base + message->size, ptr, count);
|
||||
message->size += count;
|
||||
} else {
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PackTag(Message* message, TagType tag) {
|
||||
if (!ValidMessage(message)) return;
|
||||
uint8_t byte = (uint8_t)tag;
|
||||
PackBytes(message, &byte, sizeof(byte));
|
||||
}
|
||||
|
||||
LengthType LengthFromUint32T(uint32_t length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_UINT32_T,
|
||||
.type.uint32_t_value = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
LengthType LengthFromSizeT(size_t length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_SIZE_T,
|
||||
.type.size_t_value = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
LengthType LengthFromUint32TPointer(const uint32_t* length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_UINT32_T_POINTER,
|
||||
.type.uint32_t_pointer = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
LengthType LengthFromSizeTPointer(const size_t* length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_SIZE_T_POINTER,
|
||||
.type.size_t_pointer = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
LengthType LengthFromUint32TDoublePointer(uint32_t** length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_UINT32_T_DOUBLE_POINTER,
|
||||
.type.uint32_t_double_pointer = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
LengthType LengthFromSizeTDoublePointer(size_t** length) {
|
||||
LengthType length_type = {.tag = LENGTH_TYPE_SIZE_T_DOUBLE_POINTER,
|
||||
.type.size_t_double_pointer = length};
|
||||
return length_type;
|
||||
}
|
||||
|
||||
size_t LengthAsSizeT(LengthType length) {
|
||||
size_t result = 0;
|
||||
switch(length.tag) {
|
||||
case LENGTH_TYPE_SIZE_T:
|
||||
result = length.type.size_t_value;
|
||||
break;
|
||||
case LENGTH_TYPE_UINT32_T:
|
||||
result = (size_t)length.type.uint32_t_value;
|
||||
break;
|
||||
case LENGTH_TYPE_SIZE_T_POINTER:
|
||||
if (length.type.size_t_pointer) {
|
||||
result = *length.type.size_t_pointer;
|
||||
}
|
||||
break;
|
||||
case LENGTH_TYPE_UINT32_T_POINTER:
|
||||
if (length.type.uint32_t_pointer) {
|
||||
result = (size_t)*length.type.uint32_t_pointer;
|
||||
}
|
||||
break;
|
||||
case LENGTH_TYPE_SIZE_T_DOUBLE_POINTER:
|
||||
if (length.type.size_t_double_pointer && *length.type.size_t_double_pointer) {
|
||||
result = **length.type.size_t_double_pointer;
|
||||
}
|
||||
break;
|
||||
case LENGTH_TYPE_UINT32_T_DOUBLE_POINTER:
|
||||
if (length.type.uint32_t_double_pointer && *length.type.uint32_t_double_pointer) {
|
||||
result = (size_t)**length.type.uint32_t_double_pointer;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool LengthIsNull(LengthType length) {
|
||||
switch(length.tag) {
|
||||
case LENGTH_TYPE_SIZE_T:
|
||||
case LENGTH_TYPE_UINT32_T:
|
||||
return false;
|
||||
case LENGTH_TYPE_SIZE_T_POINTER:
|
||||
return length.type.size_t_pointer == NULL;
|
||||
case LENGTH_TYPE_UINT32_T_POINTER:
|
||||
return length.type.uint32_t_pointer == NULL;
|
||||
case LENGTH_TYPE_SIZE_T_DOUBLE_POINTER:
|
||||
return length.type.size_t_double_pointer == NULL ||
|
||||
*length.type.size_t_double_pointer == NULL;
|
||||
case LENGTH_TYPE_UINT32_T_DOUBLE_POINTER:
|
||||
return length.type.uint32_t_double_pointer == NULL ||
|
||||
*length.type.uint32_t_double_pointer == NULL;
|
||||
}
|
||||
assert(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ODK_Pack_bool(Message* message, const bool* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_BOOL);
|
||||
uint8_t b = (*value) ? 1 : 0;
|
||||
PackBytes(message, &b, sizeof(b));
|
||||
}
|
||||
|
||||
void ODK_Pack_size_t(Message* message, const size_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_SIZE_T);
|
||||
uint64_t u64 = *value;
|
||||
uint8_t buf[sizeof(uint64_t)];
|
||||
buf[0] = (uint8_t)u64;
|
||||
buf[1] = (uint8_t)(u64 >> 8);
|
||||
buf[2] = (uint8_t)(u64 >> 16);
|
||||
buf[3] = (uint8_t)(u64 >> 24);
|
||||
buf[4] = (uint8_t)(u64 >> 32);
|
||||
buf[5] = (uint8_t)(u64 >> 40);
|
||||
buf[6] = (uint8_t)(u64 >> 48);
|
||||
buf[7] = (uint8_t)(u64 >> 56);
|
||||
|
||||
PackBytes(message, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void ODK_Pack_c_str(Message* message, const char* value) {
|
||||
if (!ValidMessage(message) || NullCheck(message, value)) return;
|
||||
size_t length = strlen(value) + 1;
|
||||
ODK_PackMemory(message, (const uint8_t*)value, LengthFromSizeT(length));
|
||||
}
|
||||
|
||||
void ODK_Pack_uint8_t(Message* message, const uint8_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_UINT8);
|
||||
PackBytes(message, (const uint8_t*)value, sizeof(*value));
|
||||
}
|
||||
|
||||
void ODK_Pack_uint16_t(Message* message, const uint16_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_UINT16);
|
||||
uint8_t buf[sizeof(uint16_t)];
|
||||
buf[0] = (uint8_t)(*value);
|
||||
buf[1] = (uint8_t)(*value >> 8);
|
||||
|
||||
PackBytes(message, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void ODK_Pack_uint32_t(Message* message, const uint32_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_UINT32);
|
||||
uint8_t buf[sizeof(uint32_t)];
|
||||
buf[0] = (uint8_t)(*value);
|
||||
buf[1] = (uint8_t)(*value >> 8);
|
||||
buf[2] = (uint8_t)(*value >> 16);
|
||||
buf[3] = (uint8_t)(*value >> 24);
|
||||
|
||||
PackBytes(message, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void ODK_Pack_uint64_t(Message* message, const uint64_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_UINT64);
|
||||
uint8_t buf[sizeof(uint64_t)];
|
||||
buf[0] = (uint8_t)(*value);
|
||||
buf[1] = (uint8_t)(*value >> 8);
|
||||
buf[2] = (uint8_t)(*value >> 16);
|
||||
buf[3] = (uint8_t)(*value >> 24);
|
||||
buf[4] = (uint8_t)(*value >> 32);
|
||||
buf[5] = (uint8_t)(*value >> 40);
|
||||
buf[6] = (uint8_t)(*value >> 48);
|
||||
buf[7] = (uint8_t)(*value >> 56);
|
||||
|
||||
PackBytes(message, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience function used by the serializer to
|
||||
* pack a bool without having to allocate a local
|
||||
* variable.
|
||||
*/
|
||||
bool ODK_PackBoolValue(Message* message, bool value) {
|
||||
ODK_Pack_bool(message, (const bool*)&value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack a boolean indicating if the pointer value is NULL
|
||||
*/
|
||||
bool ODK_PackIsNull(Message* message, const void* pointer) {
|
||||
return ODK_PackBoolValue(message, pointer == NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack a boolean indicating if the address value is NULL. It's
|
||||
* effectivey the same as PackIsNull but provided for symmetry with
|
||||
* UnpackAlloc.
|
||||
*/
|
||||
void ODK_PackAlloc(Message* message, const void* addr) {
|
||||
ODK_PackIsNull(message, addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack a range of memory given by address and length. First pack a
|
||||
* bool indicating if the address is NULL. If the address is non-null
|
||||
* and length is non-null then pack the length and |length| bytes from
|
||||
* memory beginning at |address|.
|
||||
*/
|
||||
void ODK_PackMemory(Message* message, const uint8_t* address,
|
||||
LengthType length) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_MEMORY);
|
||||
ODK_PackBoolValue(message, address == NULL || LengthIsNull(length));
|
||||
if (address && !LengthIsNull(length)) {
|
||||
size_t count = LengthAsSizeT(length);
|
||||
ODK_Pack_size_t(message, &count);
|
||||
if (LengthAsSizeT(length) > 0) {
|
||||
PackBytes(message, address, LengthAsSizeT(length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack memory representing an array of fundamental types, given by
|
||||
* address and length.
|
||||
*/
|
||||
void ODK_PackArray(Message* message, const uint8_t* address, size_t length) {
|
||||
ODK_PackMemory(message, address, LengthFromSizeT(length));
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack a variable length array of objects at the base address given
|
||||
* by |address|, with |length| elements of size |size|. The ObjPacker is
|
||||
* a pack function able to pack elements of the array.
|
||||
*/
|
||||
void ODK_PackObjArray(Message* message, const uint8_t* objs, LengthType length,
|
||||
size_t size, ObjPacker packer) {
|
||||
bool is_null = objs == NULL || LengthIsNull(length);
|
||||
if (!ODK_PackBoolValue(message, is_null)) {
|
||||
for (size_t i = 0; i < LengthAsSizeT(length); i++) {
|
||||
(*packer)(message, objs + i * size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* On the REE side, if address and length are not null, map the shared
|
||||
* memory segment specified by index into our address space using the
|
||||
* shared memory bump allocator and pack fields into the message so
|
||||
* that the receiver can map the corresponding segment if needed. Copy
|
||||
* the input data into the shared segment.
|
||||
*
|
||||
* Parameters:
|
||||
* message - The message to pack into
|
||||
* index - the index that identifies which segment to map
|
||||
* address - base address of the local memory buffer. If address is
|
||||
* null, shared memory will not be allocated, which is indicated
|
||||
* by a packed bool value so the receiver will also know not to
|
||||
* allocate the segment.
|
||||
* length - the length of the segment. A segment of this size will
|
||||
* be mapped if length is non-null and *length is non-zero.
|
||||
* otherwise the segment will not be mapped.
|
||||
*/
|
||||
void ODK_PackSharedInputBuffer(Message* message, uint16_t index,
|
||||
const uint8_t* address, LengthType length) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_SHARED_MEMORY);
|
||||
ODK_PackBoolValue(message, address == NULL || LengthIsNull(length));
|
||||
if (address && !LengthIsNull(length)) {
|
||||
uint8_t* shared_address = SharedMemory_Allocate(index, LengthAsSizeT(length));
|
||||
if (shared_address) {
|
||||
memcpy(shared_address, address, LengthAsSizeT(length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass information to the receiver indicating whether shared memory
|
||||
* needs to be allocated for the buffer indicated by |address| and |length|.
|
||||
*
|
||||
* Parameters:
|
||||
* message - The message to pack into
|
||||
* address - base address of the local memory buffer. If null, a shared
|
||||
* memory segment will not need to be mapped by the receiver.
|
||||
* length - the length of the segment. If null, or if the length is 0,
|
||||
* a shared memory segment will not need to be mapped by the receiver.
|
||||
*
|
||||
* Returns:
|
||||
* void
|
||||
*/
|
||||
void ODK_PackSharedOutputBuffer(Message* message, const uint8_t* address,
|
||||
LengthType length) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_SHARED_MEMORY);
|
||||
ODK_PackBoolValue(message, address == NULL || LengthIsNull(length));
|
||||
}
|
||||
|
||||
void ODK_PackEOM(Message* message) {
|
||||
if (!ValidMessage(message)) return;
|
||||
PackTag(message, TAG_EOM);
|
||||
}
|
||||
|
||||
/**************************** Unpack Functions *******************************/
|
||||
|
||||
static void UnpackBytes(Message* message, uint8_t* ptr, size_t count) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (count <= message->size - message->read_offset) {
|
||||
if (ptr) {
|
||||
memcpy(ptr, message->base + message->read_offset, count);
|
||||
}
|
||||
message->read_offset += count;
|
||||
} else {
|
||||
message->status = MESSAGE_STATUS_UNDERFLOW_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckTag(Message* message, TagType tag) {
|
||||
uint8_t byte = TAG_INVALID;
|
||||
UnpackBytes(message, &byte, sizeof(byte));
|
||||
if (tag != (TagType)byte) {
|
||||
message->status = MESSAGE_STATUS_INVALID_TAG_ERROR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ODK_Unpack_bool(Message* message, bool* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_BOOL)) return;
|
||||
uint8_t b = 0;
|
||||
UnpackBytes(message, &b, sizeof(b));
|
||||
*value = b ? true : false;
|
||||
}
|
||||
|
||||
void ODK_Unpack_size_t(Message* message, size_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_SIZE_T)) return;
|
||||
uint8_t buf[sizeof(uint64_t)];
|
||||
UnpackBytes(message, buf, sizeof(buf));
|
||||
uint64_t u64 = *value;
|
||||
u64 = buf[0];
|
||||
u64 |= (uint64_t)buf[1] << 8;
|
||||
u64 |= (uint64_t)buf[2] << 16;
|
||||
u64 |= (uint64_t)buf[3] << 24;
|
||||
u64 |= (uint64_t)buf[4] << 32;
|
||||
u64 |= (uint64_t)buf[5] << 40;
|
||||
u64 |= (uint64_t)buf[6] << 48;
|
||||
u64 |= (uint64_t)buf[7] << 56;
|
||||
*value = u64;
|
||||
}
|
||||
|
||||
void ODK_Unpack_c_str(Message* message, char** value) {
|
||||
if (!ValidMessage(message) || NullCheck(message, value)) return;
|
||||
*value = NULL;
|
||||
uint8_t* ptr = NULL;
|
||||
ODK_UnpackPointerToMemory(message, &ptr);
|
||||
if (ptr) {
|
||||
/* calculate length, be careful to stay within length of message */
|
||||
size_t length = 0;
|
||||
uint8_t* p = ptr;
|
||||
while (*p && p < message->base + message->size) {
|
||||
length++;
|
||||
p++;
|
||||
}
|
||||
void* buffer = BumpAllocate(length + 1);
|
||||
if (buffer) {
|
||||
memcpy(buffer, ptr, length);
|
||||
*value = buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ODK_Unpack_uint8_t(Message* message, uint8_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_UINT8)) return;
|
||||
UnpackBytes(message, (uint8_t*)value, sizeof(*value));
|
||||
}
|
||||
|
||||
void ODK_Unpack_uint16_t(Message* message, uint16_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_UINT16)) return;
|
||||
uint8_t buf[sizeof(uint16_t)];
|
||||
UnpackBytes(message, buf, sizeof(buf));
|
||||
*value = buf[0];
|
||||
*value |= (uint16_t)buf[1] << 8;
|
||||
}
|
||||
|
||||
void ODK_Unpack_uint32_t(Message* message, uint32_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_UINT32)) return;
|
||||
uint8_t buf[sizeof(uint32_t)];
|
||||
UnpackBytes(message, buf, sizeof(buf));
|
||||
*value = buf[0];
|
||||
*value |= (uint32_t)buf[1] << 8;
|
||||
*value |= (uint32_t)buf[2] << 16;
|
||||
*value |= (uint32_t)buf[3] << 24;
|
||||
}
|
||||
|
||||
void ODK_Unpack_uint64_t(Message* message, uint64_t* value) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_UINT64)) return;
|
||||
uint8_t buf[sizeof(uint64_t)];
|
||||
UnpackBytes(message, buf, sizeof(buf));
|
||||
*value = buf[0];
|
||||
*value |= (uint64_t)buf[1] << 8;
|
||||
*value |= (uint64_t)buf[2] << 16;
|
||||
*value |= (uint64_t)buf[3] << 24;
|
||||
*value |= (uint64_t)buf[4] << 32;
|
||||
*value |= (uint64_t)buf[5] << 40;
|
||||
*value |= (uint64_t)buf[6] << 48;
|
||||
*value |= (uint64_t)buf[7] << 56;
|
||||
}
|
||||
|
||||
bool ODK_UnpackBoolValue(Message* message) {
|
||||
bool value = false;
|
||||
ODK_Unpack_bool(message, &value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Return true if the pointer was packed as NULL */
|
||||
bool ODK_UnpackIsNull(Message* message) { return ODK_UnpackBoolValue(message); }
|
||||
|
||||
/*
|
||||
* If the pointer was packed as NULL, return NULL. Otherwise
|
||||
* return the number of bytes of memory from the bump allocator
|
||||
* requested by |size|
|
||||
*/
|
||||
uint8_t* ODK_UnpackAlloc(Message* message, size_t size) {
|
||||
return ODK_UnpackIsNull(message) ? NULL : BumpAllocate(size);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pointer was packed as NULL, return NULL. Otherwise
|
||||
* return the number of bytes of memory from the bump allocator
|
||||
* requested by |size|
|
||||
*/
|
||||
uint8_t* ODK_UnpackAllocBuffer(Message* message, LengthType length, size_t size) {
|
||||
uint8_t* buffer = NULL;
|
||||
if (!ODK_UnpackIsNull(message) && !LengthIsNull(length)) {
|
||||
buffer = BumpAllocate(LengthAsSizeT(length) * size);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the pointer was packed as NULL, return NULL. Otherwise unpack
|
||||
* the array of objects into memory allocated from the bump allocator.
|
||||
*/
|
||||
void ODK_UnpackObjArray(Message* message, uint8_t** address, LengthType count,
|
||||
size_t size, ObjUnpacker unpacker) {
|
||||
if (address) {
|
||||
*address = NULL;
|
||||
}
|
||||
if (!ODK_UnpackIsNull(message)) {
|
||||
if (address && !LengthIsNull(count)) {
|
||||
*address = BumpAllocate(LengthAsSizeT(count) * size);
|
||||
if (*address) {
|
||||
for (size_t i = 0; i < LengthAsSizeT(count); i++) {
|
||||
(*unpacker)(message, (*address) + size * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unpack a range of memory representing an array of fundamental types
|
||||
* given a pointer to a buffer and a length. The caller is responsible
|
||||
* for ensuring that the buffer is large enough to handle the number
|
||||
* of bytes specified by |length|. First unpack a bool that indicates
|
||||
* if the pointer to the memory is NULL and if not unpack the
|
||||
* requested number of bytes into the address specified by |address|.
|
||||
*/
|
||||
void ODK_UnpackArray(Message* message, uint8_t* address, size_t length) {
|
||||
if (!ValidMessage(message) || NullCheck(message, address)) return;
|
||||
uint8_t* array = NULL;
|
||||
ODK_UnpackPointerToMemory(message, &array);
|
||||
if (array) {
|
||||
memcpy(address, array, length);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unpack a pointer to memory within the received message and return
|
||||
* it. First unpack a bool that indicates if the address was passed in
|
||||
* as NULL. If so set *address to NULL and return. Otherwise set
|
||||
* *|address| to the current message read offset and unpack the length
|
||||
* of the memory range. Then increment the message read offset by that
|
||||
* amount.
|
||||
*/
|
||||
void ODK_UnpackPointerToMemory(Message* message, uint8_t** address) {
|
||||
if (!ValidMessage(message) || NullCheck(message, address)) return;
|
||||
if (!CheckTag(message, TAG_MEMORY)) return;
|
||||
bool is_null = true;
|
||||
ODK_Unpack_bool(message, &is_null);
|
||||
if (is_null) {
|
||||
*address = NULL;
|
||||
return;
|
||||
} else {
|
||||
size_t length;
|
||||
ODK_Unpack_size_t(message, &length);
|
||||
size_t new_offset;
|
||||
if (__builtin_add_overflow(message->read_offset, length, &new_offset) ||
|
||||
new_offset > message->size) {
|
||||
message->status = MESSAGE_STATUS_OVERFLOW_ERROR;
|
||||
} else {
|
||||
*address = message->base + message->read_offset;
|
||||
message->read_offset = new_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unpack fields from |message| and use them to map a shared memory
|
||||
* segment using the shared memory bump allocator. If the packed bool
|
||||
* indicates that the output buffer is non-null, allocate a shared
|
||||
* memory segment identified by |index| of the size indicated by
|
||||
* |length|.
|
||||
*
|
||||
* Parameters:
|
||||
* message - the message to unpack from
|
||||
* index - the index that identifies which segment to map
|
||||
* length - the length of the segment
|
||||
* Returns:
|
||||
* The address of the mapped segment
|
||||
*/
|
||||
uint8_t* ODK_UnpackSharedBuffer(Message* message, uint16_t index,
|
||||
LengthType length) {
|
||||
if (!ValidMessage(message)) return NULL;
|
||||
if (!CheckTag(message, TAG_SHARED_MEMORY)) return NULL;
|
||||
if (!ODK_UnpackIsNull(message)) {
|
||||
return SharedMemory_Allocate(index, LengthAsSizeT(length));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the REE, unpack fields from |message| and use them to map a
|
||||
* shared memory segment using the shared memory bump allocator. If
|
||||
* the packed bool indicates that the output buffer is non-null,
|
||||
* allocate a shared memory segment identified by |index| of the size
|
||||
* indicated by |length|. Copy the buffer from shared memory to
|
||||
* the OEMCrypto API parameter.
|
||||
*
|
||||
* Parameters:
|
||||
* message - the message to unpack from
|
||||
* address - the OEMCrypto API parameter for the output buffer
|
||||
* index - the index that identifies which segment to map
|
||||
* length - the length of the segment
|
||||
*/
|
||||
void ODK_UnpackSharedOutputBuffer(Message* message, uint16_t index,
|
||||
uint8_t** address, LengthType length) {
|
||||
if (address && !LengthIsNull(length)) {
|
||||
uint8_t* shared_address = ODK_UnpackSharedBuffer(message, index, length);
|
||||
if (*address && LengthAsSizeT(length) > 0) {
|
||||
memcpy(*address, shared_address, LengthAsSizeT(length));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* end of message */
|
||||
void ODK_UnpackEOM(Message* message) {
|
||||
if (!ValidMessage(message)) return;
|
||||
if (!CheckTag(message, TAG_EOM)) return;
|
||||
if (message->read_offset != message->size) {
|
||||
message->status = MESSAGE_STATUS_END_OF_MESSAGE_ERROR;
|
||||
}
|
||||
}
|
||||
118
serialization/serialization_base.h
Normal file
118
serialization/serialization_base.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_SERIALIZATION_BASE_H_
|
||||
#define ODKITEE_SERIALIZATION_BASE_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "message.h"
|
||||
#include "shared_memory_interface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef char* c_str;
|
||||
|
||||
/*
|
||||
* In the OEMCrypto API, the lengths of variable length buffers can be
|
||||
* of various types: base types of size_t or uint32_t and [in] values
|
||||
* or [in/out] pointers. The LengthType struct is used to pass
|
||||
* lengths in a consistent way to the primitives that take lengths as
|
||||
* arguments.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
LENGTH_TYPE_SIZE_T,
|
||||
LENGTH_TYPE_UINT32_T,
|
||||
LENGTH_TYPE_SIZE_T_POINTER,
|
||||
LENGTH_TYPE_UINT32_T_POINTER,
|
||||
LENGTH_TYPE_SIZE_T_DOUBLE_POINTER,
|
||||
LENGTH_TYPE_UINT32_T_DOUBLE_POINTER
|
||||
} LengthTypeTag;
|
||||
|
||||
typedef struct {
|
||||
LengthTypeTag tag;
|
||||
union {
|
||||
size_t size_t_value;
|
||||
uint32_t uint32_t_value;
|
||||
const size_t* size_t_pointer;
|
||||
const uint32_t* uint32_t_pointer;
|
||||
size_t** size_t_double_pointer;
|
||||
uint32_t** uint32_t_double_pointer;
|
||||
} type;
|
||||
} LengthType;
|
||||
|
||||
LengthType LengthFromSizeT(size_t length);
|
||||
LengthType LengthFromUint32T(uint32_t length);
|
||||
LengthType LengthFromSizeTPointer(const size_t* length);
|
||||
LengthType LengthFromUint32TPointer(const uint32_t* length);
|
||||
LengthType LengthFromSizeTDoublePointer(size_t** length);
|
||||
LengthType LengthFromUint32TDoublePointer(uint32_t** length);
|
||||
|
||||
size_t LengthAsSizeT(LengthType length_type);
|
||||
bool LengthIsNull(LengthType length_type);
|
||||
|
||||
void ODK_Pack_bool(Message* message, const bool* value);
|
||||
void ODK_Pack_size_t(Message* message, const size_t* value);
|
||||
void ODK_Pack_c_str(Message* message, const char* value);
|
||||
void ODK_Pack_uint8_t(Message* message, const uint8_t* value);
|
||||
void ODK_Pack_uint16_t(Message* message, const uint16_t* value);
|
||||
void ODK_Pack_uint32_t(Message* message, const uint32_t* value);
|
||||
void ODK_Pack_uint64_t(Message* message, const uint64_t* value);
|
||||
bool ODK_PackBoolValue(Message* message, bool value);
|
||||
bool ODK_PackIsNull(Message* message, const void* value);
|
||||
void ODK_PackAlloc(Message* message, const void* address);
|
||||
void ODK_PackMemory(Message* message, const uint8_t* addr,
|
||||
LengthType length);
|
||||
void ODK_PackArray(Message* message, const uint8_t* addr, size_t length);
|
||||
|
||||
typedef void (*ObjPacker)(Message* message, const uint8_t* obj);
|
||||
void ODK_PackObjArray(Message* message, const uint8_t* address,
|
||||
LengthType length, size_t size, ObjPacker packer);
|
||||
void ODK_PackEOM(Message* message); /* end of message */
|
||||
|
||||
|
||||
void ODK_PackSharedInputBuffer(Message* message, uint16_t index,
|
||||
const uint8_t* address, const LengthType);
|
||||
void ODK_PackSharedOutputBuffer(Message* message, const uint8_t* address,
|
||||
LengthType length);
|
||||
|
||||
void ODK_Unpack_bool(Message* message, bool* value);
|
||||
void ODK_Unpack_size_t(Message* message, size_t* value);
|
||||
void ODK_Unpack_c_str(Message* message, char** value);
|
||||
void ODK_Unpack_uint8_t(Message* message, uint8_t* value);
|
||||
void ODK_Unpack_uint16_t(Message* message, uint16_t* value);
|
||||
void ODK_Unpack_uint32_t(Message* message, uint32_t* value);
|
||||
void ODK_Unpack_uint64_t(Message* message, uint64_t* value);
|
||||
bool ODK_UnpackBoolValue(Message* message);
|
||||
bool ODK_UnpackIsNull(Message* message);
|
||||
uint8_t* ODK_UnpackAlloc(Message* message, size_t size);
|
||||
uint8_t* ODK_UnpackAllocBuffer(Message* message, LengthType length,
|
||||
size_t size);
|
||||
void ODK_UnpackArray(Message* message, uint8_t* addr, size_t length);
|
||||
|
||||
typedef void (*ObjUnpacker)(Message* message, uint8_t* obj);
|
||||
void ODK_UnpackObjArray(Message* message, uint8_t** address,
|
||||
LengthType length, size_t size,
|
||||
ObjUnpacker unpacker);
|
||||
void ODK_UnpackPointerToMemory(Message* message, uint8_t** addr);
|
||||
uint8_t* ODK_UnpackSharedBuffer(Message* message, uint16_t index,
|
||||
LengthType length);
|
||||
void ODK_UnpackSharedInputBuffer(Message* message, uint16_t index,
|
||||
uint8_t** address, LengthType length);
|
||||
void ODK_UnpackSharedOutputBuffer(Message* message, uint16_t index,
|
||||
uint8_t** address, LengthType length);
|
||||
void ODK_UnpackEOM(Message* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ODKITEE_SERIALIZATION_BASE_H_
|
||||
260
serialization/shared_memory_allocator.c
Normal file
260
serialization/shared_memory_allocator.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "shared_memory_allocator.h"
|
||||
#include "shared_memory_interface.h"
|
||||
#include "oemcrypto_overflow.h"
|
||||
|
||||
/*
|
||||
* This file implements the allocator for shared memory. Shared memory
|
||||
* is managed using two different schemes. There is a memory region,
|
||||
* called the "pool" that is allocated once at initialization and kept
|
||||
* open for the lifetime of OEMCrypto, and discrete allocations that
|
||||
* are made on each OEMCrypto call where additional shared memory is
|
||||
* required.
|
||||
*
|
||||
* Every shared memory allocation is identified by an index number,
|
||||
* which is provided by the caller. Allowing the caller to specify the
|
||||
* index allows the code generator to refer to specific regions
|
||||
* explicitly, which is needed to correlate segments across
|
||||
* serialization endpoints. The index numbers start from 0. Given an
|
||||
* index number, the address and size of the allocation can be
|
||||
* returned. The code generator requires that the allocation algorithm
|
||||
* be deterministic and repeatable, i.e. that a specific sequence of
|
||||
* allocations when replayed after a reset will result in the same
|
||||
* shared memory regions being mapped to the same indexes.
|
||||
*
|
||||
* The memory pool is managed with a bump allocator. The pool is
|
||||
* allocated from the porting layer's ODK_SharedMemory interface. The
|
||||
* pool is divided into "segments" which are allocated consecutively
|
||||
* from the pool by AllocateSegment. The allocator is reset before
|
||||
* each api call, which removes all segments.
|
||||
*
|
||||
* Shared memory allocations that are too large to put in the pool are
|
||||
* allocated directly from ODK_SharedMemory and are released at the
|
||||
* end of each OEMCrypto call. A threshold is defined (e.g. pool
|
||||
* size/4) that determines whether allocations are from the pool or
|
||||
* from the discrete regions.
|
||||
*/
|
||||
|
||||
/* Region ID for the shared memory pool */
|
||||
#define SHARED_MEMORY_POOL_REGION_ID 0
|
||||
|
||||
/* The ID of the next discrete region to allocate */
|
||||
static size_t next_discrete_region_id_ = SHARED_MEMORY_POOL_REGION_ID + 1;
|
||||
|
||||
/*
|
||||
* Descriptor for a segment allocated from the pool.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
} Segment;
|
||||
|
||||
/*
|
||||
* Descriptor for an allocation, which may be either from the pool
|
||||
* or from a discrete region.
|
||||
*/
|
||||
typedef enum {FREE, POOL_SEGMENT, DISCRETE_REGION} AllocationType;
|
||||
typedef struct {
|
||||
AllocationType type;
|
||||
union {
|
||||
Segment segment;
|
||||
ODK_SharedHandle* handle;
|
||||
} u;
|
||||
} Allocation;
|
||||
|
||||
/*
|
||||
* Maximum number of allocations allowed. Indexes go from 0 to
|
||||
* MAX_ALLOCATIONS - 1
|
||||
*/
|
||||
#define MAX_ALLOCATIONS 16
|
||||
static Allocation allocations_[MAX_ALLOCATIONS];
|
||||
|
||||
/*
|
||||
* Shared memory handle for the bump allocator pool
|
||||
*/
|
||||
static ODK_SharedHandle *pool_handle_;
|
||||
|
||||
/*
|
||||
* The offset from pool_address of the next segment that will be
|
||||
* allocated.
|
||||
*/
|
||||
static size_t next_segment_offset_ = 0;
|
||||
|
||||
/*
|
||||
* Initial size of the memory pool
|
||||
*/
|
||||
static size_t pool_size_ = 0;
|
||||
|
||||
/*
|
||||
* Initialize shared memory state variables. Set the initial pool size
|
||||
* to the specified value.
|
||||
*/
|
||||
void SharedMemory_Initialize(size_t pool_size) {
|
||||
ODK_SharedMemory_Initialize();
|
||||
memset(&allocations_[0], 0, sizeof(allocations_));
|
||||
pool_size_ = pool_size;
|
||||
pool_handle_ = NULL;
|
||||
next_discrete_region_id_ = SHARED_MEMORY_POOL_REGION_ID + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release all shared memory resources from the current process.
|
||||
*/
|
||||
void SharedMemory_Terminate(void) {
|
||||
SharedMemory_Reset();
|
||||
ODK_SharedMemory_Free(pool_handle_);
|
||||
pool_handle_ = NULL;
|
||||
ODK_SharedMemory_Terminate();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate shared memory as a discrete region
|
||||
*/
|
||||
static uint8_t* AllocateAsRegion(uint16_t index, size_t size) {
|
||||
ODK_SharedHandle* handle =
|
||||
ODK_SharedMemory_Allocate(next_discrete_region_id_, size);
|
||||
if (handle) {
|
||||
Allocation* alloc = &allocations_[index];
|
||||
alloc->type = DISCRETE_REGION;
|
||||
alloc->u.handle = handle;
|
||||
next_discrete_region_id_++;
|
||||
}
|
||||
return ODK_SharedMemory_GetAddress(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a segment of shared memory from the pool
|
||||
*/
|
||||
static uint8_t* AllocateFromPool(uint16_t index, size_t size) {
|
||||
if (!pool_handle_) {
|
||||
pool_handle_ = ODK_SharedMemory_Allocate(SHARED_MEMORY_POOL_REGION_ID,
|
||||
pool_size_);
|
||||
if (!pool_handle_) {
|
||||
return NULL;
|
||||
}
|
||||
next_segment_offset_ = 0;
|
||||
}
|
||||
size_t new_offset = 0;
|
||||
if (AddOverflowUX(next_segment_offset_, size, &new_offset)) {
|
||||
return NULL;
|
||||
}
|
||||
if (new_offset > ODK_SharedMemory_GetSize(pool_handle_)) {
|
||||
return AllocateAsRegion(index, size);
|
||||
}
|
||||
uint8_t* segment_address =
|
||||
ODK_SharedMemory_GetAddress(pool_handle_) + next_segment_offset_;
|
||||
|
||||
Allocation* alloc = &allocations_[index];
|
||||
alloc->type = POOL_SEGMENT;
|
||||
Segment* segment = &alloc->u.segment;
|
||||
segment->size = size;
|
||||
segment->offset = next_segment_offset_;
|
||||
next_segment_offset_ = new_offset;
|
||||
return segment_address;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate shared memory from either the pool or a discrete region.
|
||||
* If the requested memory size is larger than 1/4 of the pool size, or
|
||||
* if the pool is full, allocate as a discrete region.
|
||||
*
|
||||
* Parameters:
|
||||
* index - the index number of the allocation, assigned by the caller.
|
||||
* indexes start at 0. The index cannot exceed MAX_ALLOCATIONS.
|
||||
*
|
||||
* Returns:
|
||||
* The address of the allocation or NULL if the index has already
|
||||
* been allocated or allocation fails.
|
||||
*/
|
||||
uint8_t* SharedMemory_Allocate(uint16_t index, size_t size) {
|
||||
if (index >= MAX_ALLOCATIONS || allocations_[index].type != FREE) {
|
||||
return NULL;
|
||||
}
|
||||
if (size <= pool_size_ / 4) {
|
||||
return AllocateFromPool(index, size);
|
||||
} else {
|
||||
return AllocateAsRegion(index, size);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the size of a shared memory segment.
|
||||
*
|
||||
* Parameters:
|
||||
* index - identifies the allocation. Valid values are
|
||||
* 0..MAX_ALLOCATIONS-1
|
||||
*
|
||||
* Returns:
|
||||
* The size of the allocation indicated by |index| or 0 if the
|
||||
* index is invalid or no matching allocation was found
|
||||
*/
|
||||
size_t SharedMemory_GetSize(uint16_t index) {
|
||||
if (index >= MAX_ALLOCATIONS) {
|
||||
return 0;
|
||||
}
|
||||
Allocation* alloc = &allocations_[index];
|
||||
switch (alloc->type) {
|
||||
case DISCRETE_REGION:
|
||||
return ODK_SharedMemory_GetSize(alloc->u.handle);
|
||||
case POOL_SEGMENT:
|
||||
return alloc->u.segment.size;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the address of a shared memory segment.
|
||||
*
|
||||
* Parameters:
|
||||
* index - identifies the allocation. Valid values are
|
||||
* 0..MAX_ALLOCATIONS-1
|
||||
*
|
||||
* Returns:
|
||||
* The address of the allocation indicated by |index| or NULL if the
|
||||
* index is invalid or no matching allocation was found
|
||||
*/
|
||||
uint8_t* SharedMemory_GetAddress(uint16_t index) {
|
||||
if (index >= MAX_ALLOCATIONS) {
|
||||
return NULL;
|
||||
}
|
||||
Allocation* alloc = &allocations_[index];
|
||||
switch (alloc->type) {
|
||||
case DISCRETE_REGION:
|
||||
return ODK_SharedMemory_GetAddress(alloc->u.handle);
|
||||
case POOL_SEGMENT:
|
||||
if (!pool_handle_) {
|
||||
return NULL;
|
||||
}
|
||||
return ODK_SharedMemory_GetAddress(pool_handle_) +
|
||||
alloc->u.segment.offset;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the allocator to its initial state, where there are no segments
|
||||
* allocated from the pool and there are no discrete allocations.
|
||||
*/
|
||||
void SharedMemory_Reset(void) {
|
||||
next_segment_offset_ = 0;
|
||||
for (size_t i = 0; i < MAX_ALLOCATIONS; i++) {
|
||||
Allocation* alloc = &allocations_[i];
|
||||
if (alloc->type == DISCRETE_REGION) {
|
||||
ODK_SharedMemory_Free(alloc->u.handle);
|
||||
}
|
||||
}
|
||||
memset(&allocations_[0], 0, sizeof(allocations_));
|
||||
next_discrete_region_id_ = SHARED_MEMORY_POOL_REGION_ID + 1;
|
||||
}
|
||||
31
serialization/shared_memory_allocator.h
Normal file
31
serialization/shared_memory_allocator.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_SHARED_MEMORY_ALLOCATOR_H_
|
||||
#define ODKITEE_SHARED_MEMORY_ALLOCATOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* An allocator for shared memory
|
||||
*/
|
||||
void SharedMemory_Initialize(size_t initial_pool_size);
|
||||
uint8_t* SharedMemory_Allocate(uint16_t index, size_t size);
|
||||
size_t SharedMemory_GetSize(uint16_t index);
|
||||
uint8_t* SharedMemory_GetAddress(uint16_t index);
|
||||
void SharedMemory_Reset(void);
|
||||
void SharedMemory_Terminate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //ODKITEE_SHARED_MEMORY_ALLOCATOR_H_
|
||||
117
serialization/shared_memory_interface.h
Normal file
117
serialization/shared_memory_interface.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2020 Google LLC. All Rights Reserved. This file and proprietary
|
||||
* source code may only be used and distributed under the Widevine Master
|
||||
* License Agreement.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_SHARED_MEMORY_INTERFACE_H_
|
||||
#define ODKITEE_SHARED_MEMORY_INTERFACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* This is the interface to shared memory that must be implemented in
|
||||
* a port for a specific trusted OS. The interface defines functions
|
||||
* to allocate, access and free regions of shared memory.
|
||||
*
|
||||
* Shared memory regions are defined by an address and a size. Regions
|
||||
* are allocated by specifying an integer |region_id| that is used to
|
||||
* correlate remote and local mappings. When a region is created, the
|
||||
* implementation returns an ODK_SharedHandle which is used by callers
|
||||
* when accessing the region.
|
||||
*
|
||||
* Each shared memory implementation defines its own _ODK_SharedHandle
|
||||
* struct to hold the data needed to represent a shared memory region.
|
||||
*/
|
||||
typedef struct _ODK_SharedHandle ODK_SharedHandle;
|
||||
|
||||
/*
|
||||
* Shared memory regions are identified with an id that correlates the
|
||||
* remote and local mappings.
|
||||
*/
|
||||
typedef uint16_t ODK_SharedRegionId;
|
||||
|
||||
/*
|
||||
* Note that the shared memory implementation must be initialized
|
||||
* prior to calling any OEMCrypto API functions because it needs to be
|
||||
* available when communicating with the TEE. Typically it would be
|
||||
* initialized on service startup.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize the shared memory implementation, must be called prior
|
||||
* to using any other ODK_SharedMemory functions. This function will
|
||||
* be called by the dispatcher on the TEE side at startup. On the REE
|
||||
* side it must be called by the service that is calling OEMCrypto
|
||||
* because the communication with the TEE needs to be established
|
||||
* before any OEMCrypto calls are made.
|
||||
*/
|
||||
void ODK_SharedMemory_Initialize(void);
|
||||
|
||||
/*
|
||||
* Terminate the shared memory implementation, releasing any resources
|
||||
* in use.
|
||||
*/
|
||||
void ODK_SharedMemory_Terminate(void);
|
||||
|
||||
/*
|
||||
* Allocate a region of shared memory of |size| bytes. Regions are
|
||||
* allocated based on a specified id that is used to correlate remote
|
||||
* and local mappings. The shared memory region must remain mapped
|
||||
* until released by ODK_SharedMemory_Free.
|
||||
*
|
||||
* Parameters:
|
||||
* region_id - identifies the region to allocate
|
||||
* size - the size of the memory region to allocate
|
||||
*
|
||||
* Returns:
|
||||
* A pointer to an ODK_SharedHandle which refers to the allocated
|
||||
* shared memory, or NULL if allocation fails. The memory for the
|
||||
* handle is owned by the implementation. The handle must remain
|
||||
* valid for as long as the shared memory region is allocated.
|
||||
*/
|
||||
ODK_SharedHandle* ODK_SharedMemory_Allocate(ODK_SharedRegionId region_id,
|
||||
size_t size);
|
||||
|
||||
/*
|
||||
* Return the address that a shared memory handle is mapped to.
|
||||
*
|
||||
* Parameters:
|
||||
* handle - the shared handle for which an address is requested
|
||||
*
|
||||
* Returns:
|
||||
* The address of the shared memory region refered by |handle|
|
||||
*/
|
||||
uint8_t* ODK_SharedMemory_GetAddress(ODK_SharedHandle* handle);
|
||||
|
||||
/*
|
||||
* Return the size of a shared memory region
|
||||
*
|
||||
* Parameters:
|
||||
* handle - the shared handle for which the region size is requested
|
||||
*
|
||||
* Returns:
|
||||
* The size of the shared memory region refered by |handle|
|
||||
*/
|
||||
size_t ODK_SharedMemory_GetSize(ODK_SharedHandle* handle);
|
||||
|
||||
/*
|
||||
* Release a handle for a previously allocated region of shared memory.
|
||||
* The memory is unmapped and any associated resources are released.
|
||||
*
|
||||
* Parameters:
|
||||
* address - the address of the shared memory region to release
|
||||
*/
|
||||
void ODK_SharedMemory_Free(ODK_SharedHandle* handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //ODKITEE_SHARED_MEMORY_INTERFACE_H_
|
||||
131
serialization/special_case_apis.c
Normal file
131
serialization/special_case_apis.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
202
serialization/special_cases.c
Normal file
202
serialization/special_cases.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.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 cases due to union & shared memory
|
||||
*/
|
||||
|
||||
/*
|
||||
* Pack the destination buffer parameter to OEMCrypto_DecryptCENC and
|
||||
* OEMCrypto_CopyBuffer
|
||||
*/
|
||||
void ODK_Pack_OEMCrypto_DestBufferDesc(Message* message,
|
||||
const OEMCrypto_DestBufferDesc* obj) {
|
||||
if (obj == NULL) {
|
||||
SetStatus(message, MESSAGE_STATUS_NULL_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
ODK_Pack_uint32_t(message, (uint32_t*)&obj->type);
|
||||
switch (obj->type) {
|
||||
case OEMCrypto_BufferType_Clear: {
|
||||
ODK_Pack_size_t(message, &obj->buffer.clear.max_length);
|
||||
ODK_PackSharedOutputBuffer(message, obj->buffer.clear.address,
|
||||
LengthFromSizeT(obj->buffer.clear.max_length));
|
||||
break;
|
||||
}
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
/* secure memory - pass handle, length, offset */
|
||||
ODK_Pack_uint64_t(message, (uint64_t*)&obj->buffer.secure.handle);
|
||||
ODK_Pack_size_t(message, &obj->buffer.secure.max_length);
|
||||
ODK_Pack_size_t(message, &obj->buffer.secure.offset);
|
||||
break;
|
||||
case OEMCrypto_BufferType_Direct:
|
||||
ODK_Pack_bool(message, &obj->buffer.direct.is_video);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unpack the destination buffer parameter to OEMCrypto_DecryptCENC and
|
||||
* OEMCrypto_CopyBuffer
|
||||
*/
|
||||
void ODK_Unpack_OEMCrypto_DestBufferDesc(Message* message,
|
||||
OEMCrypto_DestBufferDesc* obj) {
|
||||
if (obj == NULL) {
|
||||
SetStatus(message, MESSAGE_STATUS_NULL_POINTER_ERROR);
|
||||
return;
|
||||
}
|
||||
ODK_Unpack_uint32_t(message, (uint32_t*)&obj->type);
|
||||
switch (obj->type) {
|
||||
case OEMCrypto_BufferType_Clear: {
|
||||
ODK_Unpack_size_t(message, &obj->buffer.clear.max_length);
|
||||
uint8_t* shared_address =
|
||||
ODK_UnpackSharedBuffer(message, DEST_BUFFER_INDEX,
|
||||
LengthFromSizeT(obj->buffer.clear.max_length));
|
||||
if (!obj->buffer.clear.address) {
|
||||
// unpacking request in TEE - set the address to shared memory
|
||||
obj->buffer.clear.address = shared_address;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
/* secure memory handle - deal with later */
|
||||
ODK_Unpack_uint64_t(message, (uint64_t*)&obj->buffer.secure.handle);
|
||||
ODK_Unpack_size_t(message, &obj->buffer.secure.max_length);
|
||||
ODK_Unpack_size_t(message, &obj->buffer.secure.offset);
|
||||
break;
|
||||
case OEMCrypto_BufferType_Direct:
|
||||
ODK_Unpack_bool(message, &obj->buffer.direct.is_video);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special serialization cases due to some parameters being defined as
|
||||
* pointers into other parameters.
|
||||
*/
|
||||
|
||||
void ODK_Pack_RewrapDeviceRSAKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length,
|
||||
const uint32_t* unaligned_nonce,
|
||||
const uint8_t* enc_rsa_key,
|
||||
size_t enc_rsa_key_length,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
const uint8_t* wrapped_rsa_key,
|
||||
const size_t* wrapped_rsa_key_length) {
|
||||
uint32_t api_value = 18; /* from _oecc18 */
|
||||
ODK_Pack_uint32_t(msg, &api_value);
|
||||
ODK_Pack_size_t(msg, &message_length);
|
||||
ODK_Pack_size_t(msg, &signature_length);
|
||||
ODK_Pack_size_t(msg, &enc_rsa_key_length);
|
||||
ODK_PackNullable_size_t(msg, wrapped_rsa_key_length);
|
||||
ODK_Pack_uint32_t(msg, &session);
|
||||
ODK_PackSharedInputBuffer(msg, 0, message, LengthFromSizeT(message_length));
|
||||
ODK_PackSharedInputBuffer(msg, 1, signature, LengthFromSizeT(signature_length));
|
||||
|
||||
size_t unaligned_nonce_offset = 0;
|
||||
if (__builtin_sub_overflow((uintptr_t)unaligned_nonce, (uintptr_t)message,
|
||||
&unaligned_nonce_offset)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
ODK_Pack_size_t(msg, &unaligned_nonce_offset);
|
||||
|
||||
size_t enc_rsa_key_offset = 0;
|
||||
if (__builtin_sub_overflow((uintptr_t)enc_rsa_key, (uintptr_t)message,
|
||||
&enc_rsa_key_offset)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
ODK_Pack_size_t(msg, &enc_rsa_key_offset);
|
||||
|
||||
size_t enc_rsa_key_iv_offset = 0;
|
||||
if (__builtin_sub_overflow((uintptr_t)enc_rsa_key_iv, (uintptr_t)message,
|
||||
&enc_rsa_key_iv_offset)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
ODK_Pack_size_t(msg, &enc_rsa_key_iv_offset);
|
||||
ODK_PackAlloc(msg, wrapped_rsa_key);
|
||||
ODK_PackEOM(msg);
|
||||
}
|
||||
|
||||
void ODK_Unpack_RewrapDeviceRSAKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session,
|
||||
SharedMemory** message,
|
||||
size_t* message_length,
|
||||
SharedMemory** signature,
|
||||
size_t* signature_length,
|
||||
uint32_t** unaligned_nonce,
|
||||
uint8_t** enc_rsa_key,
|
||||
size_t* enc_rsa_key_length,
|
||||
uint8_t** enc_rsa_key_iv,
|
||||
uint8_t** wrapped_rsa_key,
|
||||
size_t** wrapped_rsa_key_length) {
|
||||
uint32_t api_value = ~(uint32_t)0;
|
||||
ODK_Unpack_uint32_t(msg, &api_value);
|
||||
if (api_value != 18) SetStatus(msg, MESSAGE_STATUS_API_VALUE_ERROR);
|
||||
ODK_Unpack_size_t(msg, message_length);
|
||||
ODK_Unpack_size_t(msg, signature_length);
|
||||
ODK_Unpack_size_t(msg, enc_rsa_key_length);
|
||||
ODK_UnpackNullable_size_t(msg, wrapped_rsa_key_length);
|
||||
ODK_Unpack_uint32_t(msg, session);
|
||||
ODK_UnpackSharedBuffer(msg, 0, LengthFromSizeTPointer(message_length));
|
||||
ODK_UnpackSharedBuffer(msg, 1, LengthFromSizeTPointer(signature_length));
|
||||
*message = SharedMemory_GetAddress(0);
|
||||
*signature = SharedMemory_GetAddress(1);
|
||||
|
||||
size_t unaligned_nonce_offset = 0;
|
||||
uintptr_t unaligned_nonce_ptr = 0;
|
||||
ODK_Unpack_size_t(msg, &unaligned_nonce_offset);
|
||||
if (__builtin_add_overflow((uintptr_t)*message, unaligned_nonce_offset,
|
||||
&unaligned_nonce_ptr)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
*unaligned_nonce = (uint32_t*)unaligned_nonce_ptr;
|
||||
|
||||
size_t enc_rsa_key_offset = 0;
|
||||
uintptr_t enc_rsa_key_ptr = 0;
|
||||
ODK_Unpack_size_t(msg, &enc_rsa_key_offset);
|
||||
if (__builtin_add_overflow((uintptr_t)*message, enc_rsa_key_offset,
|
||||
&enc_rsa_key_ptr)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
*enc_rsa_key = (uint8_t*)enc_rsa_key_ptr;
|
||||
|
||||
size_t enc_rsa_key_iv_offset = 0;
|
||||
uintptr_t enc_rsa_key_iv_ptr = 0;
|
||||
ODK_Unpack_size_t(msg, &enc_rsa_key_iv_offset);
|
||||
if (__builtin_add_overflow((uintptr_t)*message, enc_rsa_key_iv_offset,
|
||||
&enc_rsa_key_iv_ptr)) {
|
||||
SetStatus(msg, MESSAGE_STATUS_PARSE_ERROR);
|
||||
return;
|
||||
}
|
||||
*enc_rsa_key_iv = (uint8_t*)enc_rsa_key_iv_ptr;
|
||||
*wrapped_rsa_key = (uint8_t*)ODK_UnpackAllocBuffer(
|
||||
msg, LengthFromSizeTDoublePointer(wrapped_rsa_key_length),
|
||||
sizeof(uint8_t));
|
||||
ODK_UnpackEOM(msg);
|
||||
}
|
||||
64
serialization/special_cases.h
Normal file
64
serialization/special_cases.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_SPECIAL_CASES_H_
|
||||
#define ODKITEE_SPECIAL_CASES_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "message.h"
|
||||
|
||||
/* shared memory index used for destination buffers */
|
||||
#define DEST_BUFFER_INDEX 3
|
||||
|
||||
/*
|
||||
* Special cases due to union & shared memory
|
||||
*/
|
||||
void ODK_Pack_OEMCrypto_DestBufferDesc(Message* msg,
|
||||
const OEMCrypto_DestBufferDesc* obj);
|
||||
void ODK_Unpack_OEMCrypto_DestBufferDesc(Message* msg,
|
||||
OEMCrypto_DestBufferDesc* obj);
|
||||
|
||||
/*
|
||||
* Special cases due to parameters defined as having pointers into other parameters
|
||||
*/
|
||||
void ODK_Pack_RewrapDeviceRSAKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION session,
|
||||
const uint8_t* message,
|
||||
size_t message_length,
|
||||
const uint8_t* signature,
|
||||
size_t signature_length,
|
||||
const uint32_t* unaligned_nonce,
|
||||
const uint8_t* enc_rsa_key,
|
||||
size_t enc_rsa_key_length,
|
||||
const uint8_t* enc_rsa_key_iv,
|
||||
const uint8_t* wrapped_rsa_key,
|
||||
const size_t* wrapped_rsa_key_length);
|
||||
|
||||
void ODK_Unpack_RewrapDeviceRSAKey_Request(
|
||||
Message* msg, OEMCrypto_SESSION* session,
|
||||
SharedMemory** message,
|
||||
size_t* message_length,
|
||||
SharedMemory** signature,
|
||||
size_t* signature_length,
|
||||
uint32_t** unaligned_nonce,
|
||||
uint8_t** enc_rsa_key,
|
||||
size_t* enc_rsa_key_length,
|
||||
uint8_t** enc_rsa_key_iv,
|
||||
uint8_t** wrapped_rsa_key,
|
||||
size_t** wrapped_rsa_key_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // ODKITEE_SPECIAL_CASES_H_
|
||||
116
serialization/transport_interface.h
Normal file
116
serialization/transport_interface.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ODKITEE_TRANSPORT_INTERFACE_H_
|
||||
#define ODKITEE_TRANSPORT_INTERFACE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The Transport Interface is used by the oemcrypto library running
|
||||
* on the REE side/HLOS. It connects liboemcrypto to the trusted
|
||||
* OS's method of transporting data between the REE and the TEE.
|
||||
*
|
||||
* The trusted OS must provide primitives to transport data segments
|
||||
* between the REE and TEE. The maximum size of the data segments may
|
||||
* be fixed and predetermined by the trusted OS. However, the
|
||||
* transport implementation must be able to append data segments
|
||||
* sequentially to transport arbitrarily sized messages. For example
|
||||
* if the maximum block size is 2 KiB and a message is serialized that
|
||||
* requires 6 KiB, the transport layer must be able to extend the
|
||||
* messsage to three logically consecutive 2 KiB segments during
|
||||
* serialization to contain the message. Messages may be initially
|
||||
* allocated at any block size. The serialization layer will call back
|
||||
* into the transport layer to request that additional blocks be added
|
||||
* to the message as needed. The serialization layer will attempt to
|
||||
* minimize the actual size of messages by passing larger parameters
|
||||
* in shared memory, if supported by the trusted OS.
|
||||
*
|
||||
* Functions need to be provided to allocate, extend and deallocate
|
||||
* messages, and send and receive messages between the REE and the
|
||||
* TEE.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/*
|
||||
* ODK_TRANSPORT_STATUS_OK must be returned from transport functions
|
||||
* if the requested operation completed succesfully.
|
||||
*/
|
||||
ODK_TRANSPORT_STATUS_OK,
|
||||
|
||||
/*
|
||||
* ODK_TRANSPORT_STATUS_ALLOC_FAILED must be returned from
|
||||
* ODK_Transport_ExtendMessage if there is insufficient memory. This
|
||||
* is a fatal failure that will cause OEMCrypto to return
|
||||
* OEMCrypto_ERROR_INSUFFICIENT_RESOURCES.
|
||||
*/
|
||||
ODK_TRANSPORT_STATUS_ALLOC_FAILED,
|
||||
|
||||
/*
|
||||
* ODK_TRANSPORT_STATUS_IO_ERROR must be returned from
|
||||
* ODK_Transport_SendMessage or ODK_Transport_ReceiveMessage if the
|
||||
* transport interface was unable to deliver or receive a message
|
||||
* for any reason. The transport implementation should be designed
|
||||
* to be robust against communication failures, e.g. by providing
|
||||
* logic to retry delivery or other techniques if possible. The
|
||||
* odkitee library does not make any attempts to improve
|
||||
* communcation reliability using these techniques.
|
||||
*
|
||||
* This return code indicates a fatal failure of the current command
|
||||
* which will result in OEMCrypto returning
|
||||
* OEMCrypto_ERROR_SYSTEM_INVALIDATED. This will cause the app to be
|
||||
* notified that the drm system must be reinitialized.
|
||||
*/
|
||||
ODK_TRANSPORT_STATUS_IO_ERROR,
|
||||
} ODK_Transport_Status;
|
||||
|
||||
/*
|
||||
* Allocate a new message of a size that is determined by the
|
||||
* transport implementation, which is most likely the maximum data
|
||||
* segment transport size of the trusted OS. The message will be
|
||||
* subsequently extended if it is too small for the message currently
|
||||
* being serialized. Must return NULL if the transport implementation
|
||||
* is unable to allocate a message of any size. Only two messages will
|
||||
* be simultaneously allocated at any time.
|
||||
*/
|
||||
Message* ODK_Transport_AllocateMessage(void);
|
||||
|
||||
/*
|
||||
* Extend an existing message to a new size. The new size is the total
|
||||
* required size of the message including the currently allocation
|
||||
* portion. Return ODK_TRANSPORT_STATUS_ALLOC_FAILED if the transport
|
||||
* interface is unable to extend the message to the new size.
|
||||
*/
|
||||
ODK_Transport_Status ODK_Transport_ExtendMessage(Message* message, size_t new_size);
|
||||
|
||||
/*
|
||||
* Request that a message be delivered from the REE to the TEE. If the
|
||||
* delivery is successful ODK_TRANSPORT_STATUS_OK must be returned.
|
||||
* Otherwise return ODK_TRANSPORT_STATUS_IO_ERROR.
|
||||
*/
|
||||
ODK_Transport_Status ODK_Transport_SendMessage(Message* message);
|
||||
|
||||
/*
|
||||
* Request that a message be received by the REE from the TEE. If
|
||||
* the receipt is successful ODK_TRANSPORT_STATUS_OK must be returned.
|
||||
* Otherwise return ODK_TRANSPORT_STATUS_IO_ERROR.
|
||||
*/
|
||||
ODK_Transport_Status ODK_Transport_ReceiveMessage(Message** message);
|
||||
|
||||
/*
|
||||
* Return a message that is not longer in use to the transport
|
||||
* interface.
|
||||
*/
|
||||
void ODK_Transport_DeallocateMessage(Message* message);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* ODKITEE_TRANSPORT_INTERFACE_H_ */
|
||||
Reference in New Issue
Block a user