Files
android/libwvdrmengine/oemcrypto/odk/src/odk_message.c
Fred Gylys-Colwell e51c9fbbb8 Update license comment
Merge from Widevine repo of http://go/wvgerrit/121950

Remove term "Master" from "Widevine Master License Agreement".

Bug: 168562298
Change-Id: I655babf1bc447f4872f6a0f849107262be42df7a
2021-04-12 14:10:08 -07:00

172 lines
5.7 KiB
C

/*
* Copyright 2019 Google LLC. All Rights Reserved. This file and proprietary
* source code may only be used and distributed under the Widevine
* License Agreement.
*/
#include "odk_message.h"
#include "odk_message_priv.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
/*
* C11 defines static_assert in assert.h. If it is available, force a compile
* time error if the abstract ODK_Message struct size does not match its
* implementation. If static_assert is not available, the runtime assert in
* InitMessage will catch the mismatch at the time a message is initialized.
*/
#ifdef static_assert
static_assert(
sizeof(ODK_Message) >= sizeof(ODK_Message_Impl),
"sizeof(ODK_Message) is too small. You can increase "
"SIZE_OF_ODK_MESSAGE_IMPL in odk_message.h to make it large enough.");
#endif
/*
* Create a message structure that references a separate data buffer. An
* initialized message is returned. The caller is responsible for ensuring that
* the buffer remains allocated for the lifetime of the message. |buffer| may be
* NULL. Serialization into a message with a NULL buffer will cause the message
* size to be incremented, but no data will be written into the message
* buffer. This is useful for calculating the amount of space a message will
* need, prior to doing the actual serialization. The buffer contents are
* unchanged by this function.
*/
ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity) {
assert(sizeof(ODK_Message) >= sizeof(ODK_Message_Impl));
ODK_Message message;
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)&message;
message_impl->base = buffer;
message_impl->capacity = capacity;
message_impl->size = 0;
message_impl->read_offset = 0;
message_impl->status = MESSAGE_STATUS_OK;
return message;
}
/*
* Erase the contents of the message, set it to an empty state by setting the
* message size and read offset to 0, effectively erasing the contents of the
* message. The message data buffer pointer remains unchanged, i.e. the message
* retains ownership of the buffer. The message buffer is zero-filled. The
* message status is reset to MESSAGE_STATUS_OK.
*/
void ODK_Message_Clear(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
message_impl->read_offset = 0;
message_impl->size = 0;
message_impl->status = MESSAGE_STATUS_OK;
if (message_impl->base) {
memset(message_impl->base, 0, message_impl->capacity);
}
}
/*
* Reset read pointer to the beginning of the message and clear status
* so that parsing of the message will restart at the beginning of the
* message. The message status is reset to MESSAGE_STATUS_OK.
*/
void ODK_Message_Reset(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
message_impl->read_offset = 0;
message_impl->status = MESSAGE_STATUS_OK;
}
/*
* Return a pointer to the message data buffer, i.e. the message payload.
* This is the buffer address that was passed into ODK_Message_Create.
*/
uint8_t* ODK_Message_GetBase(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
return message_impl->base;
}
/*
* Get the maximum number of bytes the message can hold.
*/
size_t ODK_Message_GetCapacity(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
return message_impl->capacity;
}
/*
* Get the number of bytes currently in the message
*/
size_t ODK_Message_GetSize(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
return message_impl->size;
}
/*
* Get the offset of where the next bytes will be read from the message data
* buffer.
*/
size_t ODK_Message_GetOffset(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
return message_impl->read_offset;
}
/*
* Return the status of the message
*/
ODK_MessageStatus ODK_Message_GetStatus(ODK_Message* message) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
return message_impl->status;
}
/*
* Set the message status to a specific value
*/
void ODK_Message_SetStatus(ODK_Message* message, ODK_MessageStatus status) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
/* preserve the first error */
if (message_impl->status == MESSAGE_STATUS_OK) {
message_impl->status = status;
}
}
/*
* Set the size of the message to a value. This may be needed after writing data
* into the message data buffer.
*/
void ODK_Message_SetSize(ODK_Message* message, size_t size) {
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
assert(message_impl != NULL);
assert(size <= message_impl->capacity);
message_impl->size = size;
}
/*
* Test if the integrity of a message. This means that the status must be
* MESSAGE_STATUS_OK and that the base, read_offset, size and capacity of the
* message are within the range of valid values. The message's base pointer
* may be NULL if the buffer has not been assigned yet, that is not invalid.
*/
bool ODK_Message_IsValid(ODK_Message* message) {
assert(message);
ODK_Message_Impl* message_impl = (ODK_Message_Impl*)message;
if (message_impl == NULL) {
return false;
}
if (message_impl->status != MESSAGE_STATUS_OK) {
return false;
}
if (message_impl->read_offset > message_impl->capacity ||
message_impl->size > message_impl->capacity ||
message_impl->read_offset > message_impl->size) {
message_impl->status = MESSAGE_STATUS_OVERFLOW_ERROR;
return false;
}
return true;
}