OEMCrypto v16.1

Merge of http://go/wvgerrit/93404

This CL updates the Widevine CDM to support OEMCrypto v16.1

Test: Tested in 16.2 CL
Bug: 141247171
Change-Id: I69bd993500f6fb63bf6010c8b0250dc7acc3d71b
This commit is contained in:
Fred Gylys-Colwell
2020-01-18 10:11:24 -08:00
parent 7e2619e379
commit 7665614b2e
132 changed files with 12331 additions and 9341 deletions

View File

@@ -1,6 +1,6 @@
// 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.
/* 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. */
/*********************************************************************
* OEMCryptoCENCCommon.h
@@ -9,8 +9,8 @@
*
*********************************************************************/
#ifndef OEMCRYPTO_CENC_COMMON_H_
#define OEMCRYPTO_CENC_COMMON_H_
#ifndef WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_
#define WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_
#include <stdbool.h>
#include <stddef.h>
@@ -20,17 +20,17 @@
extern "C" {
#endif
// clang-format off
/* clang-format off */
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_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_DEVICE_KEY = 8, /* no keybox device key. */
OEMCrypto_ERROR_NO_ASSET_KEY = 9,
OEMCrypto_ERROR_KEYBOX_INVALID = 10,
OEMCrypto_ERROR_NO_KEYDATA = 11,
@@ -62,9 +62,9 @@ typedef enum OEMCryptoResult {
OEMCrypto_ERROR_INSUFFICIENT_RESOURCES = 37,
OEMCrypto_ERROR_INSUFFICIENT_HDCP = 38,
OEMCrypto_ERROR_BUFFER_TOO_LARGE = 39,
OEMCrypto_WARNING_GENERATION_SKEW = 40, // Warning, not an error.
OEMCrypto_WARNING_GENERATION_SKEW = 40, /* Warning, not error. */
OEMCrypto_ERROR_GENERATION_SKEW = 41,
OEMCrypto_LOCAL_DISPLAY_ONLY = 42, // Info, not an error.
OEMCrypto_LOCAL_DISPLAY_ONLY = 42, /* Info, not an error. */
OEMCrypto_ERROR_ANALOG_OUTPUT = 43,
OEMCrypto_ERROR_WRONG_PST = 44,
OEMCrypto_ERROR_WRONG_KEYS = 45,
@@ -72,8 +72,9 @@ typedef enum OEMCryptoResult {
OEMCrypto_ERROR_LICENSE_INACTIVE = 47,
OEMCrypto_ERROR_ENTRY_NEEDS_UPDATE = 48,
OEMCrypto_ERROR_ENTRY_IN_USE = 49,
OEMCrypto_ERROR_USAGE_TABLE_UNRECOVERABLE = 50, // Reserved. Do not use.
OEMCrypto_KEY_NOT_LOADED = 51, // obsolete. use error 26.
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,
@@ -89,8 +90,9 @@ typedef enum OEMCryptoResult {
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,
} OEMCryptoResult;
// clang-format on
/* clang-format on */
/*
* OEMCrypto_Usage_Entry_Status.
@@ -99,7 +101,7 @@ typedef enum OEMCryptoResult {
typedef enum OEMCrypto_Usage_Entry_Status {
kUnused = 0,
kActive = 1,
kInactive = 2, // Deprecated. Used kInactiveUsed or kInactiveUnused.
kInactive = 2, /* Deprecated. Use kInactiveUsed or kInactiveUnused. */
kInactiveUsed = 3,
kInactiveUnused = 4,
} OEMCrypto_Usage_Entry_Status;
@@ -150,4 +152,4 @@ typedef struct {
}
#endif
#endif // OEMCRYPTO_CENC_COMMON_H_
#endif /* WIDEVINE_ODK_INCLUDE_OEMCRYPTOCENCCOMMON_H_ */

View File

@@ -0,0 +1,59 @@
/* 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. */
/*********************************************************************
* 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 "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);
} /* namespace deserialize */
} /* namespace oemcrypto_core_message */
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_DESERIALIZE_H_ */

View File

@@ -0,0 +1,64 @@
/* 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. */
/*********************************************************************
* 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 "core_message_types.h"
#include "odk_structs.h"
namespace oemcrypto_core_message {
namespace serialize {
/**
* Counterpart (serializer) of ODK_ParseLicense (deserializer)
* struct-input variant
*
* Parameters:
* [in] parsed_lic
* [in] core_request
* [out] oemcrypto_core_message
*/
bool CreateCoreLicenseResponse(const ODK_ParsedLicense& parsed_lic,
const ODK_LicenseRequest& core_request,
std::string* oemcrypto_core_message);
/**
* Counterpart (serializer) of ODK_ParseRenewal (deserializer)
*
* Parameters:
* [in] core_request
* [out] oemcrypto_core_message
*/
bool CreateCoreRenewalResponse(const ODK_RenewalRequest& core_request,
std::string* oemcrypto_core_message);
/**
* Counterpart (serializer) of ODK_ParseProvisioning (deserializer)
* struct-input variant
*
* Parameters:
* [in] parsed_prov
* [in] core_request
* [out] oemcrypto_core_message
*/
bool CreateCoreProvisioningResponse(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_ */

View File

@@ -0,0 +1,59 @@
/* 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. */
/*********************************************************************
* 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_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] serialized_license
* serialized video_widevine::License
* [in] core_request
* [out] oemcrypto_core_message
*/
bool CreateCoreLicenseResponseFromProto(const std::string& serialized_license,
const ODK_LicenseRequest& core_request,
const std::string& core_request_sha256,
std::string* oemcrypto_core_message);
/**
* Counterpart (serializer) of ODK_ParseProvisioning (deserializer)
*
* Parameters:
* [in] serialized_provisioning_response
* serialized video_widevine::ProvisioningResponse
* [in] core_request
* [out] oemcrypto_core_message
*/
bool CreateCoreProvisioningResponseFromProto(
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_ */

View File

@@ -0,0 +1,96 @@
/* 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. */
/* 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|
* +---+------------------------------------+---+-----------------------------------+
* | 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 CoreLicenseRequestFromMessage
* Input structure for CreateCoreLicenseResponse
*/
struct ODK_LicenseRequest {
uint32_t api_version;
uint32_t nonce;
uint32_t session_id;
};
/**
* Output structure for CoreRenewalRequestFromMessage
* Input structure for CreateCoreRenewalResponse
*/
struct ODK_RenewalRequest {
uint32_t api_version;
uint32_t nonce;
uint32_t session_id;
uint64_t playback_time_seconds;
};
/**
* Output structure for CoreProvisioningRequestFromMessage
* Input structure for CreateCoreProvisioningResponse
*/
struct ODK_ProvisioningRequest {
uint32_t api_version;
uint32_t nonce;
uint32_t session_id;
std::string device_id;
};
} /* namespace oemcrypto_core_message */
#endif /* WIDEVINE_ODK_INCLUDE_CORE_MESSAGE_TYPES_H_ */

View File

@@ -1,8 +1,6 @@
/*
* 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.
*/
/* 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. */
/*********************************************************************
* odk.h
@@ -44,10 +42,11 @@
*
*********************************************************************/
#ifndef ODK_H_
#define ODK_H_
#ifndef WIDEVINE_ODK_INCLUDE_ODK_H_
#define WIDEVINE_ODK_INCLUDE_ODK_H_
#include <stdint.h>
#include "OEMCryptoCENCCommon.h"
#include "odk_structs.h"
@@ -319,7 +318,7 @@ OEMCryptoResult ODK_PrepareCoreLicenseRequest(
*/
OEMCryptoResult ODK_PrepareCoreRenewalRequest(
uint8_t* message, size_t message_length, size_t* core_message_size,
const ODK_NonceValues* nonce_values, const ODK_ClockValues* clock_values,
const ODK_NonceValues* nonce_values, ODK_ClockValues* clock_values,
uint64_t system_time_seconds);
/*
@@ -327,8 +326,8 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(
*
* Description:
* 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.
* beginning of the message buffer. The values in nonce_values, clock_values
* and system_time_seconds are used to populate the message.
*
* This shall be called by OEMCrypto from
* OEMCrypto_PrepAndSignProvisioningRequest.
@@ -400,39 +399,60 @@ OEMCryptoResult ODK_InitializeV15Values(ODK_TimerLimits* timer_limits,
uint32_t key_duration,
uint64_t system_time_seconds);
/*
* ODK_RefreshV15Values
*
* Description:
* This function updates the clock_values as needed if the renewal is
* accepted. The field nonce_values.api_level is verified to be 15.
*
* Parameters:
* [in] timer_limits: The session's timer limits.
* [in/out] clock_values: The session's clock values.
* [in] nonce_values: The session's ODK nonce values.
* [in] system_time_seconds: The current time on the system clock, as
* described in the document "License Duration and Renewal".
* [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.
*
* Returns:
* OEMCrypto_SUCCESS
* OEMCrypto_ERROR_UNKNOWN_FAILURE
* ODK_SET_TIMER: Success. The timer should be reset to the specified value
* and playback is allowed.
* ODK_DISABLE_TIMER: Success, but disable timer. Unlimited playback is
* allowed.
* 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,
uint64_t* timer_value);
/*
* ODK_ParseLicense
*
* Description:
* The function ODK_ParseLicense will parse the message and verify fields in
* the message.
* The function ODK_ParseLicense will parse the message and verify
*
* 1. Either the nonce matches the one passed in or the license does not
* require a nonce.
* 2. The API version of the message matches.
* 3. The session id matches.
* The function ODK_ParseLicense will parse the message and set each
* substring pointer to point 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 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 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
* hash matches request_hash in the parsed license. If verification fails,
* then it shall return ODK_ERROR_CORE_MESSAGE.
*
* If usage_entry_present is true, then ODK_ParseLicense shall verify that
* the pst in the license has a nonzero length.
* layer above. If the api in the message is larger than 16, then
* ODK_UNSUPPORTED_API is returned.
*
* Parameters:
* [in] message: pointer to the message buffer.
@@ -470,12 +490,9 @@ OEMCryptoResult ODK_ParseLicense(
* ODK_ParseRenewal
*
* Description:
* The function ODK_ParseRenewal will parse the message and verify. 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.
* The function ODK_ParseRenewal will parse the message and verify that the
* nonce values match those in the license. If the message does not parse
* correctly, an error of ODK_ERROR_CORE_MESSAGE is returned.
*
* After parsing the message, this function updates the clock_values based on
* the timer_limits and the current system time. If playback may not
@@ -534,21 +551,14 @@ OEMCryptoResult ODK_ParseRenewal(const uint8_t* message, size_t message_length,
* The function ODK_ParseProvisioning will parse the message and verify the
* nonce values match those in the license.
*
* The function ODK_ParseProvisioning will parse the message and set each
* substring pointer to point 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 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 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.
*
* Parameters:
* [in] message: pointer to the message buffer.
* [in] message_length: length of the entire message buffer.
@@ -580,4 +590,4 @@ OEMCryptoResult ODK_ParseProvisioning(
}
#endif
#endif // ODK_H_
#endif /* WIDEVINE_ODK_INCLUDE_ODK_H_ */

View File

@@ -1,13 +1,12 @@
/*
* 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.
*/
/* 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. */
#ifndef ODK_STRUCTS_H_
#define ODK_STRUCTS_H_
#ifndef WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
#define WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_
#include <stdint.h>
#include "OEMCryptoCENCCommon.h"
#define ODK_MAX_NUM_KEYS 32
@@ -24,11 +23,11 @@
*/
typedef struct {
uint32_t /*boolean*/ soft_expiry;
uint64_t earliest_playback_start_seconds; // seconds since license signed.
uint64_t latest_playback_start_seconds; // seconds since license signed.
uint64_t initial_playback_duration_seconds; // seconds since playback start.
uint64_t renewal_playback_duration_seconds; // seconds since renewal signed.
uint64_t license_duration_seconds; // seconds since license signed.
uint64_t earliest_playback_start_seconds; /* since license signed. */
uint64_t latest_playback_start_seconds; /* since license signed. */
uint64_t initial_playback_duration_seconds; /* since playback start. */
uint64_t renewal_playback_duration_seconds; /* since renewal signed. */
uint64_t license_duration_seconds; /* since license signed. */
} ODK_TimerLimits;
/*
@@ -71,6 +70,7 @@ typedef struct {
uint64_t time_of_license_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;
@@ -93,4 +93,4 @@ typedef struct {
uint32_t session_id;
} ODK_NonceValues;
#endif // ODK_STRUCTS_H_
#endif /* WIDEVINE_ODK_INCLUDE_ODK_STRUCTS_H_ */