Update ODK library for OPK compatibility
This is a merge from http://go/wvgerrit of several changes to the ODK library that allow it to be used in the same compilation unit as the OPK serialization/deserialization code. Merge of: http://go/wvgerrit/104403 http://go/wvgerrit/105663 http://go/wvgerrit/106004 http://go/wvgerrit/107903 http://go/wvgerrit/107985 http://go/wvgerrit/110167 http://go/wvgerrit/110403 http://go/wvgerrit/110423 http://go/wvgerrit/110663 http://go/wvgerrit/110703 http://go/wvgerrit/110985 http://go/wvgerrit/111703 http://go/wvgerrit/112563 http://go/wvgerrit/113243 http://go/wvgerrit/115204 http://go/wvgerrit/117803 http://go/wvgerrit/121949 bug: 174518179 bug: 175920940 bug: 175126254 Change-Id: I433459182043ca43a040cdbc16d04f2b8215067a
This commit is contained in:
171
libwvdrmengine/oemcrypto/odk/src/odk_message.c
Normal file
171
libwvdrmengine/oemcrypto/odk/src/odk_message.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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 "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;
|
||||
}
|
||||
Reference in New Issue
Block a user