Files
odkitee/serialization/special_cases.c
2020-07-24 12:03:58 -07:00

203 lines
6.9 KiB
C

/*
* 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);
}