79 lines
2.7 KiB
C
79 lines
2.7 KiB
C
/* Copyright 2021 Google LLC. All Rights Reserved. This file and proprietary
|
|
source code may only be used and distributed under the Widevine License
|
|
Agreement. */
|
|
|
|
#include "oemcrypto_output.h"
|
|
|
|
#include "oemcrypto_check_macros.h"
|
|
#include "oemcrypto_overflow.h"
|
|
#include "wtpi_config_interface.h"
|
|
#include "wtpi_logging_interface.h"
|
|
|
|
OEMCryptoResult OPK_ParseDestBufferDesc(
|
|
const OEMCrypto_DestBufferDesc* incoming, OPK_OutputBuffer* outgoing,
|
|
size_t* offset) {
|
|
ABORT_IF_NULL(incoming);
|
|
ABORT_IF_NULL(outgoing);
|
|
ABORT_IF_NULL(offset);
|
|
|
|
switch (incoming->type) {
|
|
case OEMCrypto_BufferType_Clear:
|
|
if (incoming->buffer.clear.clear_buffer == NULL ||
|
|
incoming->buffer.clear.clear_buffer_length == 0) {
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
|
|
outgoing->type = OPK_CLEAR_INSECURE_OUTPUT_BUFFER;
|
|
outgoing->buffer.clear_insecure = incoming->buffer.clear.clear_buffer;
|
|
outgoing->size = incoming->buffer.clear.clear_buffer_length;
|
|
*offset = 0;
|
|
return OEMCrypto_SUCCESS;
|
|
case OEMCrypto_BufferType_Secure:
|
|
if (incoming->buffer.secure.secure_buffer_length == 0 ||
|
|
incoming->buffer.secure.offset >=
|
|
incoming->buffer.secure.secure_buffer_length) {
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
|
|
outgoing->type = OPK_SECURE_OUTPUT_BUFFER;
|
|
outgoing->buffer.secure = incoming->buffer.secure.secure_buffer;
|
|
outgoing->size = incoming->buffer.secure.secure_buffer_length;
|
|
*offset = incoming->buffer.secure.offset;
|
|
return OEMCrypto_SUCCESS;
|
|
case OEMCrypto_BufferType_Direct:
|
|
return OEMCrypto_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
|
|
OEMCryptoResult OPK_CheckOutputBounds(const OPK_OutputBuffer* output_buffer,
|
|
size_t offset, size_t size) {
|
|
ABORT_IF_NULL(output_buffer);
|
|
ABORT_IF_ZERO(size);
|
|
ABORT_IF(!OPK_IsOutputBufferValid(output_buffer), "Invalid output buffer.");
|
|
|
|
const size_t max_allowed = WTPI_MaxOutputSizeForDecrypt();
|
|
if (max_allowed != 0 && size > max_allowed) {
|
|
return OEMCrypto_ERROR_OUTPUT_TOO_LARGE;
|
|
}
|
|
|
|
size_t total_size;
|
|
if (OPK_AddOverflowUX(size, offset, &total_size)) {
|
|
return OEMCrypto_ERROR_INVALID_CONTEXT;
|
|
}
|
|
if (total_size > output_buffer->size) {
|
|
return OEMCrypto_ERROR_SHORT_BUFFER;
|
|
}
|
|
|
|
return OEMCrypto_SUCCESS;
|
|
}
|
|
|
|
bool OPK_IsOutputBufferValid(const OPK_OutputBuffer* output_buffer) {
|
|
ABORT_IF_NULL(output_buffer);
|
|
return output_buffer->size > 0 &&
|
|
(output_buffer->type == OPK_SECURE_OUTPUT_BUFFER ||
|
|
(output_buffer->type == OPK_CLEAR_INSECURE_OUTPUT_BUFFER &&
|
|
output_buffer->buffer.clear_insecure != NULL));
|
|
}
|