Source release 17.1.1
This commit is contained in:
245
oemcrypto/odk/include/OEMCryptoCENCCommon.h
Normal file
245
oemcrypto/odk/include/OEMCryptoCENCCommon.h
Normal file
@@ -0,0 +1,245 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
* OEMCryptoCENCCommon.h
|
||||
*
|
||||
* Common structures and error codes between WV servers and OEMCrypto.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @addtogroup common_types
|
||||
/// @{
|
||||
|
||||
/* clang-format off */
|
||||
/** Error and result codes returned by OEMCrypto functions. */
|
||||
typedef enum OEMCryptoResult {
|
||||
OEMCrypto_SUCCESS = 0,
|
||||
OEMCrypto_ERROR_INIT_FAILED = 1,
|
||||
OEMCrypto_ERROR_TERMINATE_FAILED = 2,
|
||||
OEMCrypto_ERROR_OPEN_FAILURE = 3,
|
||||
OEMCrypto_ERROR_CLOSE_FAILURE = 4,
|
||||
OEMCrypto_ERROR_ENTER_SECURE_PLAYBACK_FAILED = 5, /* deprecated */
|
||||
OEMCrypto_ERROR_EXIT_SECURE_PLAYBACK_FAILED = 6, /* deprecated */
|
||||
OEMCrypto_ERROR_SHORT_BUFFER = 7,
|
||||
OEMCrypto_ERROR_NO_DEVICE_KEY = 8, /* no keybox device key. */
|
||||
OEMCrypto_ERROR_NO_ASSET_KEY = 9,
|
||||
OEMCrypto_ERROR_KEYBOX_INVALID = 10,
|
||||
OEMCrypto_ERROR_NO_KEYDATA = 11,
|
||||
OEMCrypto_ERROR_NO_CW = 12,
|
||||
OEMCrypto_ERROR_DECRYPT_FAILED = 13,
|
||||
OEMCrypto_ERROR_WRITE_KEYBOX = 14,
|
||||
OEMCrypto_ERROR_WRAP_KEYBOX = 15,
|
||||
OEMCrypto_ERROR_BAD_MAGIC = 16,
|
||||
OEMCrypto_ERROR_BAD_CRC = 17,
|
||||
OEMCrypto_ERROR_NO_DEVICEID = 18,
|
||||
OEMCrypto_ERROR_RNG_FAILED = 19,
|
||||
OEMCrypto_ERROR_RNG_NOT_SUPPORTED = 20,
|
||||
OEMCrypto_ERROR_SETUP = 21,
|
||||
OEMCrypto_ERROR_OPEN_SESSION_FAILED = 22,
|
||||
OEMCrypto_ERROR_CLOSE_SESSION_FAILED = 23,
|
||||
OEMCrypto_ERROR_INVALID_SESSION = 24,
|
||||
OEMCrypto_ERROR_NOT_IMPLEMENTED = 25,
|
||||
OEMCrypto_ERROR_NO_CONTENT_KEY = 26,
|
||||
OEMCrypto_ERROR_CONTROL_INVALID = 27,
|
||||
OEMCrypto_ERROR_UNKNOWN_FAILURE = 28,
|
||||
OEMCrypto_ERROR_INVALID_CONTEXT = 29,
|
||||
OEMCrypto_ERROR_SIGNATURE_FAILURE = 30,
|
||||
OEMCrypto_ERROR_TOO_MANY_SESSIONS = 31,
|
||||
OEMCrypto_ERROR_INVALID_NONCE = 32,
|
||||
OEMCrypto_ERROR_TOO_MANY_KEYS = 33,
|
||||
OEMCrypto_ERROR_DEVICE_NOT_RSA_PROVISIONED = 34,
|
||||
OEMCrypto_ERROR_INVALID_RSA_KEY = 35, /* deprecated */
|
||||
OEMCrypto_ERROR_KEY_EXPIRED = 36,
|
||||
OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37,
|
||||
OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38,
|
||||
OEMCrypto_ERROR_BUFFER_TOO_LARGE = 39,
|
||||
OEMCrypto_WARNING_GENERATION_SKEW = 40, /* Warning, not error. */
|
||||
OEMCrypto_ERROR_GENERATION_SKEW = 41,
|
||||
OEMCrypto_LOCAL_DISPLAY_ONLY = 42, /* Info, not an error. */
|
||||
OEMCrypto_ERROR_ANALOG_OUTPUT = 43,
|
||||
OEMCrypto_ERROR_WRONG_PST = 44,
|
||||
OEMCrypto_ERROR_WRONG_KEYS = 45,
|
||||
OEMCrypto_ERROR_MISSING_MASTER = 46,
|
||||
OEMCrypto_ERROR_LICENSE_INACTIVE = 47,
|
||||
OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE = 48,
|
||||
OEMCrypto_ERROR_ENTRY_IN_USE = 49,
|
||||
OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE = 50, /* Obsolete. Don't use. */
|
||||
/* Use OEMCrypto_ERROR_NO_CONTENT_KEY instead of KEY_NOT_LOADED. */
|
||||
OEMCrypto_KEY_NOT_LOADED = 51, /* Obsolete. */
|
||||
OEMCrypto_KEY_NOT_ENTITLED = 52,
|
||||
OEMCrypto_ERROR_BAD_HASH = 53,
|
||||
OEMCrypto_ERROR_OUTPUT_TOO_LARGE = 54,
|
||||
OEMCrypto_ERROR_SESSION_LOST_STATE = 55,
|
||||
OEMCrypto_ERROR_SYSTEM_INVALIDATED = 56,
|
||||
OEMCrypto_ERROR_LICENSE_RELOAD = 57,
|
||||
OEMCrypto_ERROR_MULTIPLE_USAGE_ENTRIES = 58,
|
||||
OEMCrypto_WARNING_MIXED_OUTPUT_PROTECTION = 59,
|
||||
OEMCrypto_ERROR_INVALID_ENTITLED_KEY_SESSION = 60,
|
||||
OEMCrypto_ERROR_NEEDS_KEYBOX_PROVISIONING = 61,
|
||||
OEMCrypto_ERROR_UNSUPPORTED_CIPHER = 62,
|
||||
OEMCrypto_ERROR_DVR_FORBIDDEN = 63,
|
||||
OEMCrypto_ERROR_INSUFFICIENT_PRIVILEGE = 64,
|
||||
OEMCrypto_ERROR_INVALID_KEY = 65,
|
||||
/* ODK return values */
|
||||
ODK_ERROR_BASE = 1000,
|
||||
ODK_ERROR_CORE_MESSAGE = ODK_ERROR_BASE,
|
||||
ODK_SET_TIMER = ODK_ERROR_BASE + 1,
|
||||
ODK_DISABLE_TIMER = ODK_ERROR_BASE + 2,
|
||||
ODK_TIMER_EXPIRED = ODK_ERROR_BASE + 3,
|
||||
ODK_UNSUPPORTED_API = ODK_ERROR_BASE + 4,
|
||||
ODK_STALE_RENEWAL = ODK_ERROR_BASE + 5,
|
||||
/* OPK return values */
|
||||
OPK_ERROR_BASE = 2000,
|
||||
OPK_ERROR_REMOTE_CALL = OPK_ERROR_BASE,
|
||||
OPK_ERROR_INCOMPATIBLE_VERSION = OPK_ERROR_BASE + 1,
|
||||
OPK_ERROR_NO_PERSISTENT_DATA = OPK_ERROR_BASE + 2,
|
||||
} OEMCryptoResult;
|
||||
/* clang-format on */
|
||||
|
||||
/**
|
||||
* Valid values for status in the usage table.
|
||||
*/
|
||||
typedef enum OEMCrypto_Usage_Entry_Status {
|
||||
kUnused = 0,
|
||||
kActive = 1,
|
||||
kInactive = 2, /* Deprecated. Use kInactiveUsed or kInactiveUnused. */
|
||||
kInactiveUsed = 3,
|
||||
kInactiveUnused = 4,
|
||||
} OEMCrypto_Usage_Entry_Status;
|
||||
|
||||
typedef enum OEMCrypto_ProvisioningRenewalType {
|
||||
OEMCrypto_NoRenewal = 0,
|
||||
OEMCrypto_RenewalACert = 1,
|
||||
} OEMCrypto_ProvisioningRenewalType;
|
||||
|
||||
/**
|
||||
* OEMCrypto_LicenseType is used in the license message to indicate if the key
|
||||
* objects are for content keys, or for entitlement keys.
|
||||
*/
|
||||
typedef enum OEMCrypto_LicenseType {
|
||||
OEMCrypto_ContentLicense = 0,
|
||||
OEMCrypto_EntitlementLicense = 1,
|
||||
OEMCrypto_LicenseType_MaxValue = OEMCrypto_EntitlementLicense,
|
||||
} OEMCrypto_LicenseType;
|
||||
|
||||
/* Private key type used in the provisioning response. */
|
||||
typedef enum OEMCrypto_PrivateKeyType {
|
||||
OEMCrypto_RSA_Private_Key = 0,
|
||||
OEMCrypto_ECC_Private_Key = 1,
|
||||
} OEMCrypto_PrivateKeyType;
|
||||
|
||||
/**
|
||||
* Used to indicate a substring of a signed message in OEMCrypto_LoadKeys and
|
||||
* other functions which must verify that a parameter is contained within a
|
||||
* signed message.
|
||||
*/
|
||||
typedef struct {
|
||||
size_t offset;
|
||||
size_t length;
|
||||
} OEMCrypto_Substring;
|
||||
|
||||
/**
|
||||
* Used to specify information about CMI Descriptor 0.
|
||||
* @param id: ID value of CMI Descriptor assigned by DTLA.
|
||||
* @param length: byte length of the usage rules field.
|
||||
* @param data: usage rules data.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t id; // 0x00
|
||||
uint8_t extension; // 0x00
|
||||
uint16_t length; // 0x01
|
||||
uint8_t data;
|
||||
} OEMCrypto_DTCP2_CMI_Descriptor_0;
|
||||
|
||||
/**
|
||||
* Used to specify information about CMI Descriptor 1.
|
||||
* @param id: ID value of CMI Descriptor assigned by DTLA.
|
||||
* @param extension: specified by the CMI descriptor
|
||||
* @param length: byte length of the usage rules field.
|
||||
* @param data: usage rules data.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t id; // 0x01
|
||||
uint8_t extension; // 0x00
|
||||
uint16_t length; // 0x03
|
||||
uint8_t data[3];
|
||||
} OEMCrypto_DTCP2_CMI_Descriptor_1;
|
||||
|
||||
/**
|
||||
* Used to specify information about CMI Descriptor 2.
|
||||
* @param id: ID value of CMI Descriptor assigned by DTLA.
|
||||
* @param extension: specified by the CMI descriptor
|
||||
* @param length: byte length of the usage rules field.
|
||||
* @param data: usage rules data.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t id; // 0x02
|
||||
uint8_t extension; // 0x00
|
||||
uint16_t length; // 0x03
|
||||
uint8_t data[3];
|
||||
} OEMCrypto_DTCP2_CMI_Descriptor_2;
|
||||
|
||||
/**
|
||||
* Used to specify the required DTCP2 level. If dtcp2_required is 0, there are
|
||||
* no requirements on any of the keys. If dtcp2_required is 1, any key with the
|
||||
* kControlHDCPRequired bit set requires DTCP2 in its output.
|
||||
* @param dtcp2_required: specifies whether dtcp2 is required. 0 = not required,
|
||||
* 1 = DTCP2 required.
|
||||
* @param cmi_descriptor_1: three bytes of CMI descriptor 1
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t dtcp2_required; // 0 = not required. 1 = DTCP2 v1 required.
|
||||
OEMCrypto_DTCP2_CMI_Descriptor_0 cmi_descriptor_0;
|
||||
OEMCrypto_DTCP2_CMI_Descriptor_1 cmi_descriptor_1;
|
||||
OEMCrypto_DTCP2_CMI_Descriptor_2 cmi_descriptor_2;
|
||||
} OEMCrypto_DTCP2_CMI_Packet;
|
||||
|
||||
/**
|
||||
* Points to the relevant fields for a content key. The fields are extracted
|
||||
* from the License Response message offered to OEMCrypto_LoadKeys(). Each
|
||||
* field points to one of the components of the key. Key data, key control,
|
||||
* and both IV fields are 128 bits (16 bytes):
|
||||
* @param key_id: the unique id of this key.
|
||||
* @param key_id_length: the size of key_id. OEMCrypto may assume this is at
|
||||
* most 16. However, OEMCrypto shall correctly handle key id lengths
|
||||
* from 1 to 16 bytes.
|
||||
* @param key_data_iv: the IV for performing AES-128-CBC decryption of the
|
||||
* key_data field.
|
||||
* @param key_data - the key data. It is encrypted (AES-128-CBC) with the
|
||||
* session's derived encrypt key and the key_data_iv.
|
||||
* @param key_control_iv: the IV for performing AES-128-CBC decryption of the
|
||||
* key_control field.
|
||||
* @param key_control: the key control block. It is encrypted (AES-128-CBC) with
|
||||
* the content key from the key_data field.
|
||||
*
|
||||
* The memory for the OEMCrypto_KeyObject fields is allocated and freed
|
||||
* by the caller of OEMCrypto_LoadKeys().
|
||||
*/
|
||||
typedef struct {
|
||||
OEMCrypto_Substring key_id;
|
||||
OEMCrypto_Substring key_data_iv;
|
||||
OEMCrypto_Substring key_data;
|
||||
OEMCrypto_Substring key_control_iv;
|
||||
OEMCrypto_Substring key_control;
|
||||
} OEMCrypto_KeyObject;
|
||||
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_
|
||||
83
oemcrypto/odk/include/core_message_deserialize.h
Normal file
83
oemcrypto/odk/include/core_message_deserialize.h
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
* core_message_deserialize.h
|
||||
*
|
||||
* OEMCrypto v16 Core Message Serialization library counterpart (a.k.a. KDO)
|
||||
*
|
||||
* This file declares functions to deserialize request messages prepared by
|
||||
* Widevine clients (OEMCrypto/ODK).
|
||||
*
|
||||
* Please refer to core_message_types.h for details.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "core_message_types.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace deserialize {
|
||||
|
||||
/**
|
||||
* Counterpart (deserializer) of ODK_PrepareCoreLicenseRequest (serializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] oemcrypto_core_message
|
||||
* [out] core_license_request
|
||||
*/
|
||||
bool CoreLicenseRequestFromMessage(const std::string& oemcrypto_core_message,
|
||||
ODK_LicenseRequest* core_license_request);
|
||||
|
||||
/**
|
||||
* Counterpart (deserializer) of ODK_PrepareCoreRenewalRequest (serializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] oemcrypto_core_message
|
||||
* [out] core_renewal_request
|
||||
*/
|
||||
bool CoreRenewalRequestFromMessage(const std::string& oemcrypto_core_message,
|
||||
ODK_RenewalRequest* core_renewal_request);
|
||||
|
||||
/**
|
||||
* Counterpart (deserializer) of ODK_PrepareCoreProvisioningRequest (serializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] oemcrypto_core_message
|
||||
* [out] core_provisioning_request
|
||||
*/
|
||||
bool CoreProvisioningRequestFromMessage(
|
||||
const std::string& oemcrypto_core_message,
|
||||
ODK_ProvisioningRequest* core_provisioning_request);
|
||||
|
||||
/**
|
||||
* Counterpart (deserializer) of ODK_PrepareCoreRenewedProvisioningRequest
|
||||
* (serializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] oemcrypto_core_message
|
||||
* [out] core_provisioning_request
|
||||
*/
|
||||
bool CoreRenewedProvisioningRequestFromMessage(
|
||||
const std::string& oemcrypto_core_message,
|
||||
ODK_ProvisioningRequest* core_provisioning_request);
|
||||
|
||||
/**
|
||||
* Serializer counterpart is not used and is therefore not implemented.
|
||||
*
|
||||
* Parameters:
|
||||
* [in] oemcrypto_core_message
|
||||
* [out] core_common_request
|
||||
*/
|
||||
bool CoreCommonRequestFromMessage(const std::string& oemcrypto_core_message,
|
||||
ODK_CommonRequest* core_common_request);
|
||||
|
||||
} // namespace deserialize
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_
|
||||
44
oemcrypto/odk/include/core_message_features.h
Normal file
44
oemcrypto/odk/include/core_message_features.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright 2021 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_FEATURES_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_FEATURES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace features {
|
||||
|
||||
// Features that may be supported by core messages. By restricting values in
|
||||
// this structure, we can turn off features at runtime. This is plain data, and
|
||||
// is essentially a version number.
|
||||
struct CoreMessageFeatures {
|
||||
// A default set of features.
|
||||
static const CoreMessageFeatures kDefaultFeatures;
|
||||
|
||||
// Create the default feature set for the given major version number.
|
||||
static CoreMessageFeatures DefaultFeatures(uint32_t maximum_major_version);
|
||||
|
||||
// This is the published version of the ODK Core Message library. The default
|
||||
// behavior is for the server to restrict messages to at most this version
|
||||
// number. The default is 16.5, the last version used by Chrome. This will
|
||||
// change to 17.0 when v17 has been released.
|
||||
uint32_t maximum_major_version = 17;
|
||||
uint32_t maximum_minor_version = 0;
|
||||
|
||||
bool operator==(const CoreMessageFeatures &other) const;
|
||||
bool operator!=(const CoreMessageFeatures &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const CoreMessageFeatures &features);
|
||||
|
||||
} // namespace features
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_FEATURES_H_
|
||||
78
oemcrypto/odk/include/core_message_serialize.h
Normal file
78
oemcrypto/odk/include/core_message_serialize.h
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
* core_message_serialize.h
|
||||
*
|
||||
* OEMCrypto v16 Core Message Serialization library counterpart (a.k.a. KDO)
|
||||
*
|
||||
* This file declares functions to serialize response messages that will be
|
||||
* parsed by Widevine clients (OEMCrypto/ODK).
|
||||
*
|
||||
* Please refer to core_message_types.h for details.
|
||||
*
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_types.h"
|
||||
#include "odk_structs.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace serialize {
|
||||
using oemcrypto_core_message::features::CoreMessageFeatures;
|
||||
|
||||
/**
|
||||
* Counterpart (serializer) of ODK_ParseLicense (deserializer)
|
||||
* struct-input variant
|
||||
*
|
||||
* Parameters:
|
||||
* [in] features feature support for response message.
|
||||
* [in] parsed_lic
|
||||
* [in] core_request
|
||||
* [in] core_request_sha256
|
||||
* [out] oemcrypto_core_message
|
||||
*/
|
||||
bool CreateCoreLicenseResponse(const CoreMessageFeatures& features,
|
||||
const ODK_ParsedLicense& parsed_lic,
|
||||
const ODK_LicenseRequest& core_request,
|
||||
const std::string& core_request_sha256,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
/**
|
||||
* Counterpart (serializer) of ODK_ParseRenewal (deserializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] features feature support for response message.
|
||||
* [in] core_request
|
||||
* [in] renewal_duration_seconds
|
||||
* [out] oemcrypto_core_message
|
||||
*/
|
||||
bool CreateCoreRenewalResponse(const CoreMessageFeatures& features,
|
||||
const ODK_RenewalRequest& core_request,
|
||||
uint64_t renewal_duration_seconds,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
/**
|
||||
* Counterpart (serializer) of ODK_ParseProvisioning (deserializer)
|
||||
* struct-input variant
|
||||
*
|
||||
* Parameters:
|
||||
* [in] features feature support for response message.
|
||||
* [in] parsed_prov
|
||||
* [in] core_request
|
||||
* [out] oemcrypto_core_message
|
||||
*/
|
||||
bool CreateCoreProvisioningResponse(const CoreMessageFeatures& features,
|
||||
const ODK_ParsedProvisioning& parsed_prov,
|
||||
const ODK_ProvisioningRequest& core_request,
|
||||
std::string* oemcrypto_core_message);
|
||||
} // namespace serialize
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_H_
|
||||
67
oemcrypto/odk/include/core_message_serialize_proto.h
Normal file
67
oemcrypto/odk/include/core_message_serialize_proto.h
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/*********************************************************************
|
||||
* core_message_serialize_proto.h
|
||||
*
|
||||
* These functions are an extension of those found in
|
||||
* core_message_serialize.h. The difference is that these use the
|
||||
* license and provisioning messages in protobuf format to create the core
|
||||
* message.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_PROTO_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_PROTO_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "core_message_features.h"
|
||||
#include "core_message_types.h"
|
||||
#include "license_protocol.pb.h"
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
namespace serialize {
|
||||
// @ public create response (serializer) functions accepting proto input
|
||||
|
||||
/**
|
||||
* Counterpart (serializer) of ODK_ParseLicense (deserializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] features feature support for response message.
|
||||
* [in] serialized_license
|
||||
serialized video_widevine::License
|
||||
* [in] core_request oemcrypto core message from request.
|
||||
* [in] core_request_sha256 - hash of serialized core request.
|
||||
* [in] nonce_required - if the device should require a nonce match.
|
||||
* [in] uses_padding - if the keys use padding.
|
||||
* [out] oemcrypto_core_message - the serialized oemcrypto core response.
|
||||
*/
|
||||
bool CreateCoreLicenseResponseFromProto(
|
||||
const oemcrypto_core_message::features::CoreMessageFeatures& features,
|
||||
const std::string& serialized_license,
|
||||
const ODK_LicenseRequest& core_request,
|
||||
const std::string& core_request_sha256, const bool nonce_required,
|
||||
const bool uses_padding, std::string* oemcrypto_core_message);
|
||||
|
||||
/**
|
||||
* Counterpart (serializer) of ODK_ParseProvisioning (deserializer)
|
||||
*
|
||||
* Parameters:
|
||||
* [in] features feature support for response message.
|
||||
* [in] serialized_provisioning_response
|
||||
* serialized video_widevine::ProvisioningResponse
|
||||
* [in] core_request
|
||||
* [out] oemcrypto_core_message
|
||||
*/
|
||||
bool CreateCoreProvisioningResponseFromProto(
|
||||
const oemcrypto_core_message::features::CoreMessageFeatures& features,
|
||||
const std::string& serialized_provisioning_response,
|
||||
const ODK_ProvisioningRequest& core_request,
|
||||
std::string* oemcrypto_core_message);
|
||||
|
||||
} // namespace serialize
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_SERIALIZE_PROTO_H_
|
||||
115
oemcrypto/odk/include/core_message_types.h
Normal file
115
oemcrypto/odk/include/core_message_types.h
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
// clang-format off
|
||||
/*********************************************************************
|
||||
* core_message_types.h
|
||||
*
|
||||
* OEMCrypto v16 Core Message Serialization library counterpart (a.k.a. KDO)
|
||||
*
|
||||
* For Widevine Modular DRM, there are six message types between a server and
|
||||
* a client device: license request and response, provisioning request and
|
||||
* response, and renewal request and response.
|
||||
*
|
||||
* In OEMCrypto v15 and earlier, messages from the server were parsed by the
|
||||
* CDM layer above OEMCrypto; the CDM in turn gave OEMCrypto a collection of
|
||||
* pointers to protected data within the message. However, the pointers
|
||||
* themselves were not signed by the server.
|
||||
*
|
||||
* Starting from OEMCrypto v16, all fields used by OEMCrypto in each of these
|
||||
* messages have been identified in the document "Widevine Core Message
|
||||
* Serialization". These fields are called the core of the message. Core
|
||||
* message fields are (de)serialized using the ODK, a C library provided by
|
||||
* Widevine. OEMCrypto will parse and verify the core of the message with
|
||||
* help from the ODK.
|
||||
*
|
||||
* The KDO library is the counterpart of ODK used in the CDM & Widevine
|
||||
* servers. For each message type generated by the ODK, KDO provides a
|
||||
* corresponding parser. For each message type to be parsed by the ODK,
|
||||
* KDO provides a corresponding writer.
|
||||
*
|
||||
* Table: ODK vs KDO (s: serialize; d: deserialize)
|
||||
* +----------------------------------------+---------------------------------------+
|
||||
* | ODK | KDO |
|
||||
* +---+------------------------------------+---+-----------------------------------+
|
||||
* | s | ODK_PrepareCoreLicenseRequest | d | CoreLicenseRequestFromMessage |
|
||||
* | +------------------------------------+ +-----------------------------------+
|
||||
* | | ODK_PrepareCoreRenewalRequest | | CoreRenewalRequestFromMessage |
|
||||
* | +------------------------------------+ +-----------------------------------+
|
||||
* | | ODK_PrepareCoreProvisioningRequest | | CoreProvisioningRequestFromMessage|
|
||||
* | +------------------------------------+ +-----------------------------------+
|
||||
* | | ODK_PrepareCommonRequest | | CoreCommonRequestFromMessage |
|
||||
* +---+------------------------------------+---+-----------------------------------+
|
||||
* | d | ODK_ParseLicense | s | CreateCoreLicenseResponse |
|
||||
* | +------------------------------------+ +-----------------------------------+
|
||||
* | | ODK_ParseRenewal | | CreateCoreRenewalResponse |
|
||||
* | +------------------------------------+ +-----------------------------------+
|
||||
* | | ODK_ParseProvisioning | | CreateCoreProvisioningResponse |
|
||||
* +---+------------------------------------+---+-----------------------------------+
|
||||
*
|
||||
*********************************************************************/
|
||||
// clang-format on
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace oemcrypto_core_message {
|
||||
|
||||
// @ input/output structs
|
||||
|
||||
/**
|
||||
* Output structure for CommonRequestFromMessage
|
||||
* Input structure for CreateCommonResponse
|
||||
*/
|
||||
struct ODK_CommonRequest {
|
||||
uint16_t api_minor_version;
|
||||
uint16_t api_major_version;
|
||||
uint32_t nonce;
|
||||
uint32_t session_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Output structure for CoreLicenseRequestFromMessage
|
||||
* Input structure for CreateCoreLicenseResponse
|
||||
*/
|
||||
struct ODK_LicenseRequest {
|
||||
uint16_t api_minor_version;
|
||||
uint16_t api_major_version;
|
||||
uint32_t nonce;
|
||||
uint32_t session_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Output structure for CoreRenewalRequestFromMessage
|
||||
* Input structure for CreateCoreRenewalResponse
|
||||
*/
|
||||
struct ODK_RenewalRequest {
|
||||
uint16_t api_minor_version;
|
||||
uint16_t api_major_version;
|
||||
uint32_t nonce;
|
||||
uint32_t session_id;
|
||||
uint64_t playback_time_seconds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Output structure for CoreProvisioningRequestFromMessage and
|
||||
* CoreRenewedProvisioningRequestFromMessage
|
||||
* Input structure for CreateCoreProvisioningResponse
|
||||
*/
|
||||
struct ODK_ProvisioningRequest {
|
||||
uint16_t api_minor_version;
|
||||
uint16_t api_major_version;
|
||||
uint32_t nonce;
|
||||
uint32_t session_id;
|
||||
std::string device_id;
|
||||
uint16_t renewal_type;
|
||||
std::string renewal_data;
|
||||
};
|
||||
|
||||
} // namespace oemcrypto_core_message
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_
|
||||
664
oemcrypto/odk/include/odk.h
Normal file
664
oemcrypto/odk/include/odk.h
Normal file
@@ -0,0 +1,664 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
/**
|
||||
* @mainpage OEMCrypto v16 Core Message Serialization library
|
||||
*
|
||||
* For Widevine Modular DRM, there are six message types between a server and
|
||||
* a client device: license request and response, provisioning request and
|
||||
* response, and renewal request and response.
|
||||
*
|
||||
* In OEMCrypto v15 and earlier, messages from the server were parsed by the
|
||||
* CDM layer above OEMCrypto; the CDM in turn gave OEMCrypto a collection of
|
||||
* pointers to protected data within the message. However, the pointers
|
||||
* themselves were not signed by the server.
|
||||
*
|
||||
* Starting from OEMCrypto v16, all fields used by OEMCrypto in each of these
|
||||
* messages have been identified in the document "Widevine Core Message
|
||||
* Serialization". These fields are called the core of the message. Core
|
||||
* message fields are (de)serialized using the ODK, a C library provided by
|
||||
* Widevine. OEMCrypto will parse and verify the core of the message with
|
||||
* help from the ODK.
|
||||
*
|
||||
* The ODK functions that parse code will fill out structs that have similar
|
||||
* formats to the function parameters of the OEMCrypto v15 functions being
|
||||
* replaced. The ODK will be provided in source code and it is Widevine's
|
||||
* intention that partners can build and link ODK with their implementation
|
||||
* of OEMCrypto with no or few code changes.
|
||||
*
|
||||
* OEMCrypto implementers shall build the ODK library as part of the Trusted
|
||||
* Application (TA) running in the TEE. All memory and buffers used by the
|
||||
* ODK library shall be sanitized by the OEMCrypto implementer to prevent
|
||||
* modification by any process running the REE.
|
||||
*
|
||||
* See the documents
|
||||
* <a href="../odk">Widevine Core Message Serialization</a>
|
||||
* and
|
||||
* <a href="../../lic_duration_and_renewal">License Duration and Renewal</a>
|
||||
* for a detailed description of the ODK API. You can
|
||||
* find these documents in the widevine repository as
|
||||
* docs/Widevine_Core_Message_Serialization.pdf and
|
||||
* docs/License_Duration_and_Renewal.pdf
|
||||
*
|
||||
* @defgroup odk_parser Core Message Parsing and Verification
|
||||
* Functions that parse core messages and verify they are valid.
|
||||
* TODO(fredgc): add documentation for parsing functions.
|
||||
*
|
||||
* @defgroup odk_packer Core Message Creation
|
||||
* Functions that create core messages.
|
||||
* TODO(fredgc): add documentation for packing functions.
|
||||
*
|
||||
* @defgroup odk_timer Timer and Clock Functions
|
||||
* Functions related to enforcing timer and duration restrictions.
|
||||
* TODO(fredgc): add documentation for timers and clocks.
|
||||
*
|
||||
* @defgroup common_types Common Types
|
||||
* Enumerations and structures that are used by several OEMCrypto and ODK
|
||||
* functions.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "odk_structs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @addtogroup odk_timer
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* This function initializes the session's data structures. It shall be
|
||||
* called from OEMCrypto_OpenSession.
|
||||
*
|
||||
* @param[out] timer_limits: the session's timer limits.
|
||||
* @param[out] clock_values: the session's clock values.
|
||||
* @param[out] nonce_values: the session's ODK nonce values.
|
||||
* @param[in] api_major_version: the API version of OEMCrypto.
|
||||
* @param[in] session_id: the session id of the newly created session.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_InitializeSessionValues(ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
ODK_NonceValues* nonce_values,
|
||||
uint32_t api_major_version,
|
||||
uint32_t session_id);
|
||||
|
||||
/**
|
||||
* This function sets the nonce value in the session's nonce structure. It
|
||||
* shall be called from OEMCrypto_GenerateNonce.
|
||||
*
|
||||
* @param[in,out] nonce_values: the session's nonce data.
|
||||
* @param[in] nonce: the new nonce that was just generated.
|
||||
*
|
||||
* @retval true on success
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_SetNonceValues(ODK_NonceValues* nonce_values,
|
||||
uint32_t nonce);
|
||||
|
||||
/**
|
||||
* This function initializes the clock values in the session clock_values
|
||||
* structure. It shall be called from OEMCrypto_PrepAndSignLicenseRequest.
|
||||
*
|
||||
* Parameters:
|
||||
* @param[in,out] clock_values: the session's clock data.
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
|
||||
* clock.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_InitializeClockValues(ODK_ClockValues* clock_values,
|
||||
uint64_t system_time_seconds);
|
||||
|
||||
/**
|
||||
* This function sets the values in the clock_values structure. It shall be
|
||||
* called from OEMCrypto_LoadUsageEntry. When a usage entry from a v15 or
|
||||
* earlier license is loaded, the value time_of_license_loaded shall be used
|
||||
* in place of time_of_license_request_signed.
|
||||
*
|
||||
* @param[in,out] clock_values: the session's clock data.
|
||||
* @param[in] time_of_license_request_signed: the value time_license_received
|
||||
* from the loaded usage entry.
|
||||
* @param[in] time_of_first_decrypt: the value time_of_first_decrypt from the
|
||||
* loaded usage entry.
|
||||
* @param[in] time_of_last_decrypt: the value time_of_last_decrypt from the
|
||||
* loaded usage entry.
|
||||
* @param[in] status: the value status from the loaded usage entry.
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
|
||||
* clock.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_ReloadClockValues(ODK_ClockValues* clock_values,
|
||||
uint64_t time_of_license_request_signed,
|
||||
uint64_t time_of_first_decrypt,
|
||||
uint64_t time_of_last_decrypt,
|
||||
enum OEMCrypto_Usage_Entry_Status status,
|
||||
uint64_t system_time_seconds);
|
||||
|
||||
/**
|
||||
* This updates the clock values, and determines if playback may start based
|
||||
* on the given system time. It uses the values in clock_values to determine
|
||||
* if this is the first playback for the license or the first playback for
|
||||
* just this session.
|
||||
*
|
||||
* This shall be called from the first call in a session to any of
|
||||
* OEMCrypto_DecryptCENC or any of the OEMCrypto_Generic* functions.
|
||||
*
|
||||
* If OEMCrypto uses a hardware timer, and this function returns
|
||||
* ODK_SET_TIMER, then the timer should be set to the value pointed to by
|
||||
* timer_value.
|
||||
*
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
|
||||
* clock, in seconds.
|
||||
* @param[in] timer_limits: timer limits specified in the license.
|
||||
* @param[in,out] clock_values: the sessions clock values.
|
||||
* @param[out] timer_value: set to the new timer value. Only used if the return
|
||||
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
|
||||
* hardware timer.
|
||||
*
|
||||
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
|
||||
* value and playback is allowed.
|
||||
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
|
||||
* allowed.
|
||||
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_AttemptFirstPlayback(uint64_t system_time_seconds,
|
||||
const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
uint64_t* timer_value);
|
||||
|
||||
/**
|
||||
* Vendors that do not implement their own timer should call
|
||||
* ODK_UpdateLastPlaybackTime regularly during playback. This updates the
|
||||
* clock values, and determines if playback may continue based on the given
|
||||
* system time. This shall be called from any of OEMCrypto_DecryptCENC or any
|
||||
* of the OEMCrypto_Generic* functions.
|
||||
*
|
||||
* All Vendors (i.e. those that do or do not implement their own timer) shall
|
||||
* call ODK_UpdateLastPlaybackTime from the function
|
||||
* OEMCrypto_UpdateUsageEntry before updating the usage entry so that the
|
||||
* clock values are accurate.
|
||||
*
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's monotonic
|
||||
* clock, in seconds.
|
||||
* @param[in] timer_limits: timer limits specified in the license.
|
||||
* @param[in,out] clock_values: the sessions clock values.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS: Success. Playback is allowed.
|
||||
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_UpdateLastPlaybackTime(uint64_t system_time_seconds,
|
||||
const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values);
|
||||
|
||||
/**
|
||||
* This function modifies the session's clock values to indicate that the
|
||||
* license has been deactivated. It shall be called from
|
||||
* OEMCrypto_DeactivateUsageEntry
|
||||
*
|
||||
* Parameters:
|
||||
* @param[in,out] clock_values: the sessions clock values.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_DeactivateUsageEntry(ODK_ClockValues* clock_values);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup odk_packer
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* Modifies the message to include a core license request at the beginning of
|
||||
* the message buffer. The values in nonce_values are used to populate the
|
||||
* message.
|
||||
*
|
||||
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignLicenseRequest.
|
||||
*
|
||||
* NOTE: if the message pointer is null and/or input core_message_size is
|
||||
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
|
||||
* core_message_size to the size needed.
|
||||
*
|
||||
* @param[in,out] message: Pointer to memory for the entire message. Modified by
|
||||
* the ODK library.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in,out] core_message_size: length of the core message at the beginning
|
||||
* of the message. (in) size of buffer reserved for the core message, in
|
||||
* bytes. (out) actual length of the core message, in bytes.
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_PrepareCoreLicenseRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_size,
|
||||
const ODK_NonceValues* nonce_values);
|
||||
|
||||
/**
|
||||
* Modifies the message to include a core renewal request at the beginning of
|
||||
* the message buffer. The values in nonce_values, clock_values and
|
||||
* system_time_seconds are used to populate the message. The nonce_values
|
||||
* should match those from the license.
|
||||
*
|
||||
* This shall be called by OEMCrypto from OEMCrypto_PrepAndSignRenewalRequest.
|
||||
*
|
||||
* If status in clock_values indicates that a license has not been loaded,
|
||||
* then this is a license release. The ODK library will change the value of
|
||||
* nonce_values.api_major_version to 15. This will make
|
||||
* OEMCrypto_PrepAndSignRenewalRequest sign just the message body, as it does
|
||||
* for all legacy licenses.
|
||||
*
|
||||
* NOTE: if the message pointer is null and/or input core_message_size is
|
||||
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
|
||||
* core_message_size to the size needed.
|
||||
*
|
||||
* @param[in,out] message: Pointer to memory for the entire message. Modified by
|
||||
* the ODK library.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in,out] core_message_size: length of the core message at the beginning
|
||||
* of the message. (in) size of buffer reserved for the core message, in
|
||||
* bytes. (out) actual length of the core message, in bytes.
|
||||
* @param[in,out] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in,out] clock_values: the session's clock values.
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's clock, in
|
||||
* seconds.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
|
||||
size_t message_length,
|
||||
size_t* core_message_size,
|
||||
ODK_NonceValues* nonce_values,
|
||||
ODK_ClockValues* clock_values,
|
||||
uint64_t system_time_seconds);
|
||||
|
||||
/**
|
||||
* Modifies the message to include a core provisioning request at the
|
||||
* beginning of the message buffer. The values in nonce_values are used to
|
||||
* populate the message.
|
||||
*
|
||||
* This shall be called by OEMCrypto from
|
||||
* OEMCrypto_PrepAndSignProvisioningRequest.
|
||||
*
|
||||
* The buffer device_id shall be the same string returned by
|
||||
* OEMCrypto_GetDeviceID. The device ID shall be unique to the device, and
|
||||
* stable across reboots and factory resets for an L1 device.
|
||||
*
|
||||
* NOTE: if the message pointer is null and/or input core_message_length is
|
||||
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
|
||||
* core_message_size to the size needed.
|
||||
*
|
||||
* @param[in,out] message: Pointer to memory for the entire message. Modified by
|
||||
* the ODK library.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in,out] core_message_size: length of the core message at the beginning
|
||||
* of the message. (in) size of buffer reserved for the core message, in
|
||||
* bytes. (out) actual length of the core message, in bytes.
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in] device_id: For devices with a keybox, this is the device ID from
|
||||
* the keybox. For devices with an OEM Certificate, this is a device
|
||||
* unique id string.
|
||||
* @param[in] device_id_length: length of device_id. The device ID can be at
|
||||
* most 64 bytes.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_PrepareCoreProvisioningRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length);
|
||||
|
||||
/**
|
||||
* Modifies the message to include a core renewal provisioning request at the
|
||||
* beginning of the message buffer. The values in nonce_values are used to
|
||||
* populate the message.
|
||||
*
|
||||
* This shall be called by OEMCrypto from
|
||||
* OEMCrypto_PrepAndSignProvisioningRequest.
|
||||
*
|
||||
* The buffer device_id shall be the same string returned by
|
||||
* OEMCrypto_GetDeviceID. The device ID shall be unique to the device, and
|
||||
* stable across reboots and factory resets for an L1 device.
|
||||
*
|
||||
* NOTE: if the message pointer is null and/or input core_message_length is
|
||||
* zero, this function returns OEMCrypto_ERROR_SHORT_BUFFER and sets output
|
||||
* core_message_size to the size needed.
|
||||
*
|
||||
* @param[in,out] message: pointer to memory for the entire message. Modified by
|
||||
* the ODK library.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in,out] core_message_size: length of the core message at the beginning
|
||||
* of the message. (in) size of buffer reserved for the core message, in
|
||||
* bytes. (out) actual length of the core message, in bytes.
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in] device_id: For devices with a keybox, this is the device ID from
|
||||
* the keybox. For devices with an OEM Certificate, this is a device
|
||||
* unique id string.
|
||||
* @param[in] device_id_length: length of device_id. The device ID can be at
|
||||
* most 64 bytes.
|
||||
* @param[in] renewal_type: type of renewal used
|
||||
* @param[in] renewal_data: renewal data used. For renewal_type = 1,
|
||||
* renewal_data is the Android attestation batch certificate.
|
||||
* @param[in] renewal_data_length: length of renewal_data
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_SHORT_BUFFER: core_message_size is too small
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 17 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_PrepareCoreRenewedProvisioningRequest(
|
||||
uint8_t* message, size_t message_length, size_t* core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length, uint16_t renewal_type, const uint8_t* renewal_data,
|
||||
size_t renewal_data_length);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup odk_timer
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* This function sets all limits in the timer_limits struct to the
|
||||
* key_duration and initializes the other values. The field
|
||||
* nonce_values.api_major_version will be set to 15. It shall be called from
|
||||
* OEMCrypto_LoadKeys when loading a legacy license.
|
||||
*
|
||||
* @param[out] timer_limits: The session's timer limits.
|
||||
* @param[in,out] clock_values: The session's clock values.
|
||||
* @param[in,out] nonce_values: The session's ODK nonce values.
|
||||
* @param[in] key_duration: The duration from the first key's key control
|
||||
* block. In practice, the key duration is the same for all keys and is
|
||||
* the same as the license duration.
|
||||
* @param[in] system_time_seconds: The current time on the system clock, as
|
||||
* described in the document "License Duration and Renewal".
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_INVALID_CONTEXT
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_InitializeV15Values(ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
ODK_NonceValues* nonce_values,
|
||||
uint32_t key_duration,
|
||||
uint64_t system_time_seconds);
|
||||
|
||||
/**
|
||||
* This function updates the clock_values as needed if a v15 renewal is
|
||||
* accepted. The field nonce_values.api_major_version is verified to be 15.
|
||||
*
|
||||
* This is called from OEMCrypto_RefreshKeys for a valid license renewal.
|
||||
* OEMCrypto shall pass in the current system time, and the key duration from
|
||||
* the first object in the OEMCrypto_KeyRefreshObject.
|
||||
*
|
||||
* @param[in] timer_limits: The session's timer limits.
|
||||
* @param[in,out] clock_values: The session's clock values.
|
||||
* @param[in] nonce_values: The session's ODK nonce values.
|
||||
* @param[in] system_time_seconds: The current time on the system clock, as
|
||||
* described in the document "License Duration and Renewal".
|
||||
* @param[in] new_key_duration: The duration from the first
|
||||
* OEMCrypto_KeyRefreshObject in key_array.
|
||||
* @param[out] timer_value: set to the new timer value. Only used if the return
|
||||
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
|
||||
* hardware timer.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval OEMCrypto_ERROR_UNKNOWN_FAILURE
|
||||
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
|
||||
* value and playback is allowed.
|
||||
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
|
||||
* allowed.
|
||||
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_RefreshV15Values(const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
const ODK_NonceValues* nonce_values,
|
||||
uint64_t system_time_seconds,
|
||||
uint32_t new_key_duration,
|
||||
uint64_t* timer_value);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup odk_parser
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* The function ODK_ParseLicense will parse the message and verify fields in
|
||||
* the message.
|
||||
*
|
||||
* If the message does not parse correctly, ODK_VerifyAndParseLicense will
|
||||
* return ODK_ERROR_CORE_MESSAGE that OEMCrypto should return to the CDM
|
||||
* layer above.
|
||||
*
|
||||
* If the API in the message is not 16, then ODK_UNSUPPORTED_API is returned.
|
||||
*
|
||||
* If initial_license_load is true, and nonce_required in the license is
|
||||
* true, then the ODK library shall verify that nonce_values->nonce and
|
||||
* nonce_values->session_id are the same as those in the message. If
|
||||
* verification fails, then it shall return OEMCrypto_ERROR_INVALID_NONCE.
|
||||
*
|
||||
* If initial_license_load is false, and nonce_required is true, then
|
||||
* ODK_ParseLicense will set the values in nonce_values from those in the
|
||||
* message.
|
||||
*
|
||||
* The function ODK_ParseLicense will verify that each substring points to a
|
||||
* location in the message body. The message body is the buffer starting at
|
||||
* message + core_message_length with size message_length -
|
||||
* core_message_length.
|
||||
*
|
||||
* If initial_license_load is true, then ODK_ParseLicense shall verify that
|
||||
* the parameter request_hash matches request_hash in the parsed license. If
|
||||
* verification fails, then it shall return ODK_ERROR_CORE_MESSAGE. This was
|
||||
* computed by OEMCrypto when the license was requested.
|
||||
*
|
||||
* If usage_entry_present is true, then ODK_ParseLicense shall verify that
|
||||
* the pst in the license has a nonzero length.
|
||||
*
|
||||
* @param[in] message: pointer to the message buffer.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in] core_message_size: length of the core message, at the beginning of
|
||||
* the message buffer.
|
||||
* @param[in] initial_license_load: true when called for OEMCrypto_LoadLicense
|
||||
* and false when called for OEMCrypto_ReloadLicense.
|
||||
* @param[in] usage_entry_present: true if the session has a new usage entry
|
||||
* associated with it created via OEMCrypto_CreateNewUsageEntry.
|
||||
* @param[in,out] timer_limits: The session's timer limits. These will be
|
||||
* updated.
|
||||
* @param[in,out] clock_values: The session's clock values. These will be
|
||||
* updated.
|
||||
* @param[in,out] nonce_values: The session's nonce values. These will be
|
||||
* updated.
|
||||
* @param[out] parsed_license: the destination for the data.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval ODK_ERROR_CORE_MESSAGE: if the message did not parse correctly, or
|
||||
* there were other incorrect values. An error should be returned to the
|
||||
* CDM layer.
|
||||
* @retval ODK_UNSUPPORTED_API
|
||||
* @retval OEMCrypto_ERROR_INVALID_NONCE
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_ParseLicense(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
bool initial_license_load, bool usage_entry_present,
|
||||
ODK_TimerLimits* timer_limits, ODK_ClockValues* clock_values,
|
||||
ODK_NonceValues* nonce_values, ODK_ParsedLicense* parsed_license);
|
||||
|
||||
/**
|
||||
* The function ODK_ParseRenewal will parse the message and verify its
|
||||
* contents. If the message does not parse correctly, an error of
|
||||
* ODK_ERROR_CORE_MESSAGE is returned.
|
||||
*
|
||||
* ODK_ParseRenewal shall verify that all fields in nonce_values match those
|
||||
* in the license. Otherwise it shall return OEMCrypto_ERROR_INVALID_NONCE.
|
||||
*
|
||||
* After parsing the message, this function updates the clock_values based on
|
||||
* the timer_limits and the current system time. If playback may not
|
||||
* continue, then ODK_TIMER_EXPIRED is returned.
|
||||
*
|
||||
* If playback may continue, a return value of ODK_SET_TIMER or
|
||||
* ODK_TIMER_EXPIRED is returned. If the return value is ODK_SET_TIMER, then
|
||||
* playback may continue until the timer expires. If the return value is
|
||||
* ODK_DISABLE_TIMER, then playback time is not limited.
|
||||
*
|
||||
* If OEMCrypto uses a hardware timer, and this function returns
|
||||
* ODK_SET_TIMER, then OEMCrypto shall set the timer to the value pointed to
|
||||
* by timer_value.
|
||||
*
|
||||
* @param[in] message: pointer to the message buffer.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in] core_message_size: length of the core message, at the beginning of
|
||||
* the message buffer.
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in] system_time_seconds: the current time on OEMCrypto's clock, in
|
||||
* seconds.
|
||||
* @param[in] timer_limits: timer limits specified in the license.
|
||||
* @param[in,out] clock_values: the sessions clock values.
|
||||
* @param[out] timer_value: set to the new timer value. Only used if the return
|
||||
* value is ODK_SET_TIMER. This must be non-null if OEMCrypto uses a
|
||||
* hardware timer.
|
||||
*
|
||||
* @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there
|
||||
* were other incorrect values. An error should be returned to the CDM
|
||||
* layer.
|
||||
* @retval ODK_SET_TIMER: Success. The timer should be reset to the specified
|
||||
* timer value.
|
||||
* @retval ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
|
||||
* allowed.
|
||||
* @retval ODK_TIMER_EXPIRED: Set timer as disabled. Playback is not allowed.
|
||||
* @retval ODK_UNSUPPORTED_API
|
||||
* @retval ODK_STALE_RENEWAL: This renewal is not the most recently signed. It
|
||||
* is rejected.
|
||||
* @retval OEMCrypto_ERROR_INVALID_NONCE
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
|
||||
size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values,
|
||||
uint64_t system_time_seconds,
|
||||
const ODK_TimerLimits* timer_limits,
|
||||
ODK_ClockValues* clock_values,
|
||||
uint64_t* timer_value);
|
||||
|
||||
/**
|
||||
* The function ODK_ParseProvisioning will parse the message and verify the
|
||||
* nonce values match those in the license.
|
||||
*
|
||||
* If the message does not parse correctly, ODK_ParseProvisioning will return
|
||||
* an error that OEMCrypto should return to the CDM layer above.
|
||||
*
|
||||
* If the API in the message is larger than 16, then ODK_UNSUPPORTED_API is
|
||||
* returned.
|
||||
*
|
||||
* ODK_ParseProvisioning shall verify that nonce_values->nonce and
|
||||
* nonce_values->session_id are the same as those in the message. Otherwise
|
||||
* it shall return OEMCrypto_ERROR_INVALID_NONCE.
|
||||
*
|
||||
* The function ODK_ParseProvisioning will verify that each substring points
|
||||
* to a location in the message body. The message body is the buffer starting
|
||||
* at message + core_message_length with size message_length -
|
||||
* core_message_length.
|
||||
*
|
||||
* @param[in] message: pointer to the message buffer.
|
||||
* @param[in] message_length: length of the entire message buffer.
|
||||
* @param[in] core_message_size: length of the core message, at the beginning of
|
||||
* the message buffer.
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in] device_id: a pointer to a buffer containing the device ID of the
|
||||
* device. The ODK function will verify it matches that in the message.
|
||||
* @param[in] device_id_length: the length of the device ID.
|
||||
* @param[out] parsed_response: destination for the parse data.
|
||||
*
|
||||
* @retval OEMCrypto_SUCCESS
|
||||
* @retval ODK_ERROR_CORE_MESSAGE: the message did not parse correctly, or there
|
||||
* were other incorrect values. An error should be returned to the CDM
|
||||
* layer.
|
||||
* @retval ODK_UNSUPPORTED_API
|
||||
* @retval OEMCrypto_ERROR_INVALID_NONCE
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 16 of the API.
|
||||
*/
|
||||
OEMCryptoResult ODK_ParseProvisioning(
|
||||
const uint8_t* message, size_t message_length, size_t core_message_length,
|
||||
const ODK_NonceValues* nonce_values, const uint8_t* device_id,
|
||||
size_t device_id_length, ODK_ParsedProvisioning* parsed_response);
|
||||
|
||||
/**
|
||||
* The function ODK_ParseProvisioning will parse the message and verify the
|
||||
* API version is at most the version passed in.
|
||||
*
|
||||
* @param[in] nonce_values: pointer to the session's nonce data.
|
||||
* @param[in] major_versioh: current API major version.
|
||||
* @param[in] minor_version: current API minor version.
|
||||
*
|
||||
* @version
|
||||
* This method is new in version 17 of the API.
|
||||
*/
|
||||
bool CheckApiVersionAtMost(const ODK_NonceValues* nonce_values,
|
||||
uint16_t major_version, uint16_t minor_version);
|
||||
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_H_
|
||||
14
oemcrypto/odk/include/odk_attributes.h
Normal file
14
oemcrypto/odk/include/odk_attributes.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_ATTRIBUTES_H_
|
||||
141
oemcrypto/odk/include/odk_message.h
Normal file
141
oemcrypto/odk/include/odk_message.h
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* ODK_Message is the structure that defines the serialized messages passed
|
||||
* between the REE and TEE. ODK_Message is an abstract data type that represents
|
||||
* the concept of a message without disclosing the implementation details. By
|
||||
* hiding the internal structure, modification of the message fields by code
|
||||
* that is not privy to the message definition can be prevented. If the message
|
||||
* definition was exposed, there could be serious yet subtle errors in message
|
||||
* manipulation anywhere in the code base. By restricting message modification
|
||||
* it is possible to enforce validity and integrity with a small set of
|
||||
* primitives that can be carefully reviewed. Checks can be added to verify that
|
||||
* a message's fields are internally consistent before every operation. As an
|
||||
* example, it can be guaranteed that the message status will be checked prior
|
||||
* to accessing any field so parsing will be stopped when the message status is
|
||||
* set after any parse error is detected. This also makes development easier
|
||||
* since any access to the message structure can be tracked through a single
|
||||
* point so, for example, it becomes possible to add trace statements globally
|
||||
* to all message operations by only changing the field accessors. Finally it
|
||||
* simplifies maintenance by localizing changes to the message structure to a
|
||||
* few files.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define ALIGNED __attribute__((aligned))
|
||||
#else
|
||||
#define ALIGNED
|
||||
#error ODK_Message must be aligned to the maximum useful alignment of the \
|
||||
machine you are compiling for. Define the ALIGNED macro accordingly.
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#define SIZE_OF_ODK_MESSAGE_IMPL 64
|
||||
uint8_t opaque_data[SIZE_OF_ODK_MESSAGE_IMPL];
|
||||
} ALIGNED ODK_Message;
|
||||
|
||||
typedef enum {
|
||||
MESSAGE_STATUS_OK = 0x7937fcf7,
|
||||
MESSAGE_STATUS_UNKNOWN_ERROR = 0x706c1190,
|
||||
MESSAGE_STATUS_OVERFLOW_ERROR = 0x543ae4bc,
|
||||
MESSAGE_STATUS_UNDERFLOW_ERROR = 0x7123cd0b,
|
||||
MESSAGE_STATUS_PARSE_ERROR = 0x0b9f6189,
|
||||
MESSAGE_STATUS_NULL_POINTER_ERROR = 0x2d66837a,
|
||||
MESSAGE_STATUS_API_VALUE_ERROR = 0x6ba34f47,
|
||||
MESSAGE_STATUS_END_OF_MESSAGE_ERROR = 0x798db72a,
|
||||
MESSAGE_STATUS_INVALID_ENUM_VALUE = 0x7db88197,
|
||||
MESSAGE_STATUS_INVALID_TAG_ERROR = 0x14dce06a,
|
||||
MESSAGE_STATUS_NOT_INITIALIZED = 0x2990b6c6,
|
||||
MESSAGE_STATUS_OUT_OF_MEMORY = 0x7c5c64cc,
|
||||
MESSAGE_STATUS_MAP_SHARED_MEMORY_FAILED = 0x7afecacf,
|
||||
MESSAGE_STATUS_SECURE_BUFFER_ERROR = 0x78f0e873
|
||||
} ODK_MessageStatus;
|
||||
|
||||
/*
|
||||
* 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. If |buffer|
|
||||
* is NULL or |capacity| is zero, the message is invalid and the status
|
||||
* will be set to MESSAGE_STATUS_NOT_INITIALIZED.
|
||||
*/
|
||||
ODK_Message ODK_Message_Create(uint8_t* buffer, size_t capacity);
|
||||
|
||||
/*
|
||||
* 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 status is reset to
|
||||
* MESSAGE_STATUS_OK.
|
||||
*/
|
||||
void ODK_Message_Clear(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Get the maximum number of bytes the message can hold.
|
||||
*/
|
||||
size_t ODK_Message_GetCapacity(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Get the number of bytes currently in the message
|
||||
*/
|
||||
size_t ODK_Message_GetSize(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Get the offset of where the next bytes will be read from the message data
|
||||
* buffer.
|
||||
*/
|
||||
size_t ODK_Message_GetOffset(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Return the status of the message
|
||||
*/
|
||||
ODK_MessageStatus ODK_Message_GetStatus(ODK_Message* message);
|
||||
|
||||
/*
|
||||
* Set the message status to a specific value
|
||||
*/
|
||||
void ODK_Message_SetStatus(ODK_Message* message, ODK_MessageStatus 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);
|
||||
|
||||
/*
|
||||
* Test if the integrity of a message. This means that the status must be
|
||||
* MESSAGE_STATUS_OK and that the internal fields of the message are
|
||||
* within the range of valid values.
|
||||
*/
|
||||
bool ODK_Message_IsValid(ODK_Message* message);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_MESSAGE_H_
|
||||
228
oemcrypto/odk/include/odk_structs.h
Normal file
228
oemcrypto/odk/include/odk_structs.h
Normal file
@@ -0,0 +1,228 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file and proprietary
|
||||
// source code may only be used and distributed under the Widevine
|
||||
// License Agreement.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "OEMCryptoCENCCommon.h"
|
||||
#include "odk_target.h"
|
||||
|
||||
/* The version of this library. */
|
||||
#define ODK_MAJOR_VERSION 17
|
||||
#define ODK_MINOR_VERSION 1
|
||||
|
||||
/* ODK Version string. Date changed automatically on each release. */
|
||||
#define ODK_RELEASE_DATE "ODK v17.1 2022-06-17"
|
||||
|
||||
/* The lowest version number for an ODK message. */
|
||||
#define ODK_FIRST_VERSION 16
|
||||
|
||||
/* Some useful constants. */
|
||||
#define ODK_DEVICE_ID_LEN_MAX 64
|
||||
#define ODK_SHA256_HASH_SIZE 32
|
||||
#define ODK_KEYBOX_RENEWAL_DATA_SIZE 1600
|
||||
|
||||
/// @addtogroup odk_timer
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* Timer limits are specified in a license and are used to determine when
|
||||
* playback is allowed. See the document "License Duration and Renewal" for a
|
||||
* discussion on the time restrictions that may be placed on a license. The
|
||||
* fields in this structure are directly related to the fields in the core
|
||||
* license message. The fields are set when OEMCrypto calls the function
|
||||
* ODK_ParseLicense or ODK_InitializeV15Values.
|
||||
*
|
||||
* @param soft_enforce_rental_duration: A boolean controlling the soft or hard
|
||||
* enforcement of rental duration.
|
||||
* @param soft_enforce_playback_duration: A boolean controlling the soft or hard
|
||||
* enforcement of playback duration.
|
||||
* @param earliest_playback_start_seconds: The earliest time that the first
|
||||
* playback is allowed. Measured in seconds since the license request was
|
||||
* signed. For most use cases, this is zero.
|
||||
* @param rental_duration_seconds: Window of time for the allowed first
|
||||
* playback. Measured in seconds since the earliest playback start. If
|
||||
* soft_enforce_rental_duration is true, this applies only to the first
|
||||
* playback. If soft_enforce_rental_duration is false, then this
|
||||
* restricts any playback. A value of zero means no limit.
|
||||
* @param total_playback_duration_seconds: Window of time for allowed playback.
|
||||
* Measured in seconds since the first playback start. If
|
||||
* soft_enforce_playback_duration is true, this applies only to the start
|
||||
* of playback for any session. If soft_enforce_playback_duration is
|
||||
* false, then this restricts any playback. A value of zero means no
|
||||
* limit.
|
||||
* @param initial_renewal_duration_seconds: Window of time for allowed playback.
|
||||
* Measured in seconds since the first playback start. This value is only
|
||||
* used to start the renewal timer. After a renewal message is loaded,
|
||||
* the timer will be reset. A value of zero means no limit.
|
||||
*
|
||||
* @version
|
||||
* This struct changed in API version 16.2.
|
||||
*/
|
||||
typedef struct {
|
||||
bool soft_enforce_rental_duration;
|
||||
bool soft_enforce_playback_duration;
|
||||
uint64_t earliest_playback_start_seconds;
|
||||
uint64_t rental_duration_seconds;
|
||||
uint64_t total_playback_duration_seconds;
|
||||
uint64_t initial_renewal_duration_seconds;
|
||||
} ODK_TimerLimits;
|
||||
|
||||
/**
|
||||
* Clock values are modified when decryption occurs or when a renewal is
|
||||
* processed. They are used to track the current status of the license --
|
||||
* i.e. has playback started? When does the timer expire? See the section
|
||||
* "Complete ODK API" of the document "Widevine Core Message Serialization"
|
||||
* for a complete list of all fields in this structure. Most of these values
|
||||
* shall be saved with the usage entry.
|
||||
*
|
||||
* All times are in seconds. Most of the fields in this structure are saved
|
||||
* in the usage entry. This structure should be initialized when a usage
|
||||
* entry is created or loaded, and should be used to save a usage entry. It
|
||||
* is updated using the ODK functions listed below. The time values are based
|
||||
* on OEMCrypto's system clock, as described in the document "License
|
||||
* Duration and Renewal".
|
||||
*
|
||||
* @param time_of_license_request_signed: Time that the license request was
|
||||
* signed, based on OEMCrypto's system clock. This value shall be stored
|
||||
* and reloaded with usage entry as time_of_license_received.
|
||||
* @param time_of_first_decrypt: Time of the first decrypt or call select key,
|
||||
* based on OEMCrypto's system clock. This is 0 if the license has not
|
||||
* been used to decrypt any data. This value shall be stored and reloaded
|
||||
* with usage entry.
|
||||
* @param time_of_last_decrypt: Time of the most recent decrypt call, based on
|
||||
* OEMCrypto's system clock. This value shall be stored and reloaded with
|
||||
* usage entry.
|
||||
* @param time_of_renewal_request: Time of the most recent renewal request,
|
||||
* based on OEMCrypto's system clock. This is used to verify that a
|
||||
* renewal is not stale.
|
||||
* @param time_when_timer_expires: Time that the current timer expires, based on
|
||||
* OEMCrypto's system clock. If the timer is active, this is used by the
|
||||
* ODK library to determine if it has expired.
|
||||
* @param timer_status: Used internally by the ODK library to indicate the
|
||||
* current timer status.
|
||||
* @param status: The license or usage entry status. This value shall be stored
|
||||
* and reloaded with usage entry.
|
||||
*
|
||||
* @version
|
||||
* This struct changed in API version 16.2.
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t time_of_license_request_signed;
|
||||
uint64_t time_of_first_decrypt;
|
||||
uint64_t time_of_last_decrypt;
|
||||
uint64_t time_of_renewal_request;
|
||||
uint64_t time_when_timer_expires;
|
||||
uint32_t timer_status;
|
||||
enum OEMCrypto_Usage_Entry_Status status;
|
||||
} ODK_ClockValues;
|
||||
|
||||
/**
|
||||
* Nonce values are used to match a license or provisioning request to a
|
||||
* license or provisioning response. They are also used to match a renewal
|
||||
* request and response to a license. For this reason, the api_version might
|
||||
* be lower than that supported by OEMCrypto. The api_version matches the
|
||||
* version of the license. Similarly the nonce and session_id match the
|
||||
* session that generated the license request. For an offline license, these
|
||||
* might not match the session that is loading the license. We use the nonce
|
||||
* to prevent a license from being replayed. By also including a session_id
|
||||
* in the license request and license response, we prevent an attack using
|
||||
* the birthday paradox to generate nonce collisions on a single device.
|
||||
*
|
||||
* @param api_major_version: the API version of the license. This is initialized
|
||||
* to the API version of the ODK library, but may be lower.
|
||||
* @param api_minor_version: the minor version of the ODK library. This is used
|
||||
* by the server to verify that device is not using an obsolete version
|
||||
* of the ODK library.
|
||||
* @param nonce: a randomly generated number used to prevent replay attacks.
|
||||
* @param session_id: the session id of the session which signed the license or
|
||||
* provisioning request. It is used to prevent replay attacks from one
|
||||
* session to another.
|
||||
*
|
||||
* @version
|
||||
* This struct changed in API version 16.2.
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t api_minor_version;
|
||||
uint16_t api_major_version;
|
||||
uint32_t nonce;
|
||||
uint32_t session_id;
|
||||
} ODK_NonceValues;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup odk_parser
|
||||
/// @{
|
||||
|
||||
/**
|
||||
* The parsed license structure contains information from the license
|
||||
* message. The function ODK_ParseLicense will fill in the fields of this
|
||||
* message. All substrings are contained within the message body.
|
||||
*
|
||||
* @param enc_mac_keys_iv: IV for decrypting new mac_key. Size is 128 bits.
|
||||
* @param enc_mac_keys: encrypted mac_keys for generating new mac_keys. Size is
|
||||
* 512 bits.
|
||||
* @param pst: the Provider Session Token.
|
||||
* @param srm_restriction_data: optional data specifying the minimum SRM
|
||||
* version.
|
||||
* @param license_type: specifies if the license contains content keys or
|
||||
* entitlement keys.
|
||||
* @param nonce_required: indicates if the license requires a nonce.
|
||||
* @param timer_limits: time limits of the for the license.
|
||||
* @param watermarking: specifies if device supports watermarking.
|
||||
* @param dtcp2_required: specifies if device supports DTCP.
|
||||
* @param key_array_length: number of keys present.
|
||||
* @param key_array: set of keys to be installed.
|
||||
*
|
||||
* @version
|
||||
* This struct changed in API version 17.
|
||||
*/
|
||||
typedef struct {
|
||||
OEMCrypto_Substring enc_mac_keys_iv;
|
||||
OEMCrypto_Substring enc_mac_keys;
|
||||
OEMCrypto_Substring pst;
|
||||
OEMCrypto_Substring srm_restriction_data;
|
||||
OEMCrypto_LicenseType license_type;
|
||||
bool nonce_required;
|
||||
ODK_TimerLimits timer_limits;
|
||||
uint32_t watermarking;
|
||||
OEMCrypto_DTCP2_CMI_Packet dtcp2_required;
|
||||
uint32_t key_array_length;
|
||||
OEMCrypto_KeyObject key_array[ODK_MAX_NUM_KEYS];
|
||||
} ODK_ParsedLicense;
|
||||
|
||||
/**
|
||||
* The parsed provisioning structure contains information from the license
|
||||
* message. The function ODK_ParseProvisioning will fill in the fields of
|
||||
* this message. All substrings are contained within the message body.
|
||||
*
|
||||
* @param key_type: indicates if this key is an RSA or ECC private key.
|
||||
* @param enc_private_key: encrypted private key for the DRM certificate.
|
||||
* @param enc_private_key_iv: IV for decrypting new private key. Size is 128
|
||||
* bits.
|
||||
* @param encrypted_message_key: used for provisioning 3.0 to derive keys.
|
||||
*
|
||||
* @version
|
||||
* This struct changed in API version 16.2.
|
||||
*/
|
||||
typedef struct {
|
||||
OEMCrypto_PrivateKeyType key_type;
|
||||
OEMCrypto_Substring enc_private_key;
|
||||
OEMCrypto_Substring enc_private_key_iv;
|
||||
OEMCrypto_Substring encrypted_message_key; /* Used for Prov 3.0 */
|
||||
} ODK_ParsedProvisioning;
|
||||
|
||||
/// @}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
|
||||
13
oemcrypto/odk/include/odk_target.h
Normal file
13
oemcrypto/odk/include/odk_target.h
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2019 Google LLC. All rights reserved. This file is distributed
|
||||
// under the Widevine License Agreement.
|
||||
|
||||
// Partners are expected to edit this file to support target specific code
|
||||
// and limits.
|
||||
|
||||
#ifndef WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_
|
||||
#define WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_
|
||||
|
||||
// Maximum number of keys can be modified to suit target's resource tier.
|
||||
#define ODK_MAX_NUM_KEYS 32
|
||||
|
||||
#endif // WIDEVINE_ODK_INCLUDE_ODK_TARGET_H_
|
||||
Reference in New Issue
Block a user