/* 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 OEMCRYPTO_TA_OEMCRYPTO_SERIALIZED_USAGE_TABLE_H_ #define OEMCRYPTO_TA_OEMCRYPTO_SERIALIZED_USAGE_TABLE_H_ #include "OEMCryptoCENC.h" #include "oemcrypto_config_macros.h" #include "oemcrypto_key_types.h" /* File types. */ #define USAGE_TABLE_HEADER 0x68656164 #define USAGE_TABLE_ENTRY 0x656e7472 #define SIGNED_USAGE_TABLE_HEADER 0x48454144 #define SIGNED_USAGE_TABLE_ENTRY 0x456e7472 #define MAX_PST_LENGTH 255 /* This can be changed to allow for newer code to load older files. */ #define CURRENT_FILE_FORMAT_VERSION 1 /* This is the usage header, as saved to the file system, before encryption. */ typedef struct SavedUsageHeader { uint32_t file_type; /* This should always be USAGE_TABLE_HEADER */ uint32_t format_version; /* For future backwards compatibility. */ uint64_t master_generation_number; uint32_t table_size; /* Number of entries in the table. */ /* These are the generation numbers of each entry. */ uint64_t generation_numbers[MAX_NUMBER_OF_USAGE_ENTRIES]; } SavedUsageHeader; /* This is all of the data we wish to save as part of a usage table entry, * before encryption. */ typedef struct SavedUsageEntry { uint32_t file_type; /* This should always be USAGE_TABLE_ENTRY. */ uint32_t format_version; /* For future backwards compatibility. */ uint32_t index; /* Index into usage header. */ uint64_t generation_number; /* Used to prevent rollback. */ int64_t time_of_license_received; /* Time in seconds on system clock. */ int64_t time_of_first_decrypt; /* Time in seconds on system clock. */ int64_t time_of_last_decrypt; /* Time in seconds on system clock.. */ /* Status of the entry or license, as documented in OEMCrypto spec. */ enum OEMCrypto_Usage_Entry_Status status; /* Server Mac key wrapped for this device. */ uint8_t mac_key_server[WRAPPED_MAC_KEY_SIZE]; /* Client Mac key wrapped for this device. */ uint8_t mac_key_client[WRAPPED_MAC_KEY_SIZE]; /* Provider session token for this license. */ uint8_t pst[MAX_PST_LENGTH + 1]; /* add 1 for padding. */ uint8_t pst_length; } SavedUsageEntry; /* TODO(b/158720996): This should be updated when we switch to using odkitee * serialization. */ /* In order to encrypt the data, we'll copy it to a slightly larger buffer * that is a whole multiple of an AES block. */ #define PADDED_HEADER_BUFFER_SIZE (16 * (1 + sizeof(SavedUsageHeader) / 16)) #define PADDED_ENTRY_BUFFER_SIZE (16 * (1 + sizeof(SavedUsageEntry) / 16)) /* This is the usage header, as saved to the file system, after encryption and * signing. */ typedef struct SignedSavedUsageHeader { uint32_t file_type; /* This should always be SIGNED_USAGE_TABLE_HEADER */ /* Used for future backwards compatibility. */ uint32_t format_version; /* The size of the saved buffer. At most PADDED_HEADER_BUFFER_SIZE. Must be * a multiple of 16, one AES block size. */ uint32_t buffer_size; /* Signature of the buffer using a device unique key. */ uint8_t signature[SHA256_DIGEST_LENGTH]; /* An encrypted SavedUsageHeader. */ uint8_t buffer[PADDED_HEADER_BUFFER_SIZE]; } SignedSavedUsageHeader; /* This is a usage table entry, as saved to the file system, after encryption * and signing. */ typedef struct SignedSavedUsageEntry { uint32_t file_type; /* This should always be SIGNED_USAGE_TABLE_ENTRY */ /* Used for future backwards compatibility. */ uint32_t format_version; /* The size of the saved buffer. At most PADDED_HEADER_BUFFER_SIZE. Must be * a multiple of 16, one AES block size. */ uint32_t buffer_size; uint8_t signature[SHA256_DIGEST_LENGTH]; /* Signature of the buffer using a device unique key. */ uint8_t buffer[PADDED_ENTRY_BUFFER_SIZE]; /* An encrypted SavedUsageEntry */ } SignedSavedUsageEntry; /* TODO(b/158720996): use serialization to turn these structures into messages * for saving. */ /* Size of a serialized SignedSavedUsageHeader with the specified table size. */ size_t SignedHeaderSize(int table_size); /* Size of a serialized SignedSavedUsageEntry. */ size_t SignedEntrySize(void); OEMCryptoResult PackSignedUsageHeader(uint8_t* buffer, size_t buffer_size, const SignedSavedUsageHeader* header); OEMCryptoResult PackUsageHeader(uint8_t* buffer, size_t buffer_size, const SavedUsageHeader* header); OEMCryptoResult PackSignedUsageEntry(uint8_t* buffer, size_t buffer_size, const SignedSavedUsageEntry* entry); OEMCryptoResult PackUsageEntry(uint8_t* buffer, size_t buffer_size, const SavedUsageEntry* entry); OEMCryptoResult UnpackSignedUsageHeader(const uint8_t* buffer, size_t buffer_size, SignedSavedUsageHeader* header); OEMCryptoResult UnpackUsageHeader(const uint8_t* buffer, size_t buffer_size, SavedUsageHeader* header); OEMCryptoResult UnpackSignedUsageEntry(const uint8_t* buffer, size_t buffer_size, SignedSavedUsageEntry* entry); OEMCryptoResult UnpackUsageEntry(const uint8_t* buffer, size_t buffer_size, SavedUsageEntry* entry); #endif // OEMCRYPTO_TA_OEMCRYPTO_SERIALIZED_USAGE_TABLE_H_