Snap for 6553216 from f870da8567 to sc-release
Change-Id: I08ce6f6c48f1da3c151b294a27be2ba42415c55c
This commit is contained in:
@@ -754,6 +754,10 @@ class Adapter {
|
||||
LOOKUP_ALL(8, Initialize, OEMCrypto_Initialize);
|
||||
LOOKUP_ALL(8, APIVersion, OEMCrypto_APIVersion);
|
||||
LOOKUP_ALL(8, Terminate, OEMCrypto_Terminate);
|
||||
if (level1_.Initialize == nullptr || level1_.APIVersion == nullptr ||
|
||||
level1_.Terminate == nullptr) {
|
||||
level1_valid_ = false;
|
||||
}
|
||||
if (!level1_valid_) {
|
||||
metrics->OemCryptoDynamicAdapterMetrics::SetInitializationMode(
|
||||
wvcdm::metrics::OEMCrypto_INITIALIZED_USING_L3_INVALID_L1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
The ODK Library is used to generate and parse core OEMCrypto messages for
|
||||
This ODK Library is used to generate and parse core OEMCrypto messages for
|
||||
OEMCrypto v16 and above.
|
||||
|
||||
This library is used by both OEMCrypto on a device, and by Widevine license and
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
|
||||
/* The version of this library. */
|
||||
#define ODK_MAJOR_VERSION 16
|
||||
#define ODK_MINOR_VERSION 2
|
||||
#define ODK_MINOR_VERSION 3
|
||||
|
||||
/* ODK Version string. Date changed automatically on each release. */
|
||||
#define ODK_RELEASE_DATE "ODK v16.2 2020-06-02"
|
||||
|
||||
/* The lowest version number for an ODK message. */
|
||||
#define ODK_FIRST_VERSION 16
|
||||
|
||||
/* Some useful constants. */
|
||||
#define ODK_DEVICE_ID_LEN_MAX 64
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace oemcrypto_core_message {
|
||||
namespace deserialize {
|
||||
namespace {
|
||||
|
||||
constexpr int EARLIEST_OEMCRYPTO_VERSION_WITH_ODK = 16;
|
||||
constexpr int LATEST_OEMCRYPTO_VERSION = 16;
|
||||
|
||||
/**
|
||||
* Template for parsing requests
|
||||
*
|
||||
@@ -59,21 +56,31 @@ bool ParseRequest(uint32_t message_type,
|
||||
core_request->session_id = core_message.nonce_values.session_id;
|
||||
// Verify that the minor version matches the released version for the given
|
||||
// major version.
|
||||
if ((core_request->api_major_version < EARLIEST_OEMCRYPTO_VERSION_WITH_ODK) ||
|
||||
(core_request->api_major_version > LATEST_OEMCRYPTO_VERSION)) {
|
||||
// Non existing and future versions are not supported.
|
||||
if (core_request->api_major_version < ODK_FIRST_VERSION) {
|
||||
// Non existing versions are not supported.
|
||||
return false;
|
||||
} else if (core_request->api_major_version == 16) {
|
||||
// For version 16, we demand a minor version of at least 2.
|
||||
// We accept 16.2, 16.3, or higher.
|
||||
if (core_request->api_major_version < 2) return false;
|
||||
} else {
|
||||
// Other versions do not (yet) have a restriction on minor number.
|
||||
// In particular, future versions are accepted for forward compatibility.
|
||||
}
|
||||
return core_message.message_type == message_type &&
|
||||
core_message.message_length == GetOffset(msg) &&
|
||||
core_request->api_major_version >=
|
||||
EARLIEST_OEMCRYPTO_VERSION_WITH_ODK &&
|
||||
core_request->api_major_version <= LATEST_OEMCRYPTO_VERSION;
|
||||
// For v16, a release and a renewal use the same message structure.
|
||||
// However, for future API versions, the release might be a separate
|
||||
// message. Otherwise, we expect an exact match of message types.
|
||||
if (core_message.message_type != message_type &&
|
||||
!(message_type == ODK_Renewal_Request_Type &&
|
||||
core_message.message_type == ODK_Release_Request_Type)) {
|
||||
return false;
|
||||
}
|
||||
// Verify that the amount of buffer we read, which is GetOffset, is not more
|
||||
// than the total message size. We allow the total message size to be larger
|
||||
// for forward compatibility because future messages might have extra fields
|
||||
// that we can ignore.
|
||||
if (core_message.message_length < GetOffset(msg)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -41,6 +41,12 @@ bool CreateResponse(uint32_t message_type, const S& core_request,
|
||||
header->nonce_values.api_minor_version = core_request.api_minor_version;
|
||||
header->nonce_values.nonce = core_request.nonce;
|
||||
header->nonce_values.session_id = core_request.session_id;
|
||||
// The message API version for the response is the minimum of our version and
|
||||
// the request's version.
|
||||
if (core_request.api_major_version > ODK_MAJOR_VERSION) {
|
||||
header->nonce_values.api_major_version = ODK_MAJOR_VERSION;
|
||||
header->nonce_values.api_minor_version = ODK_MINOR_VERSION;
|
||||
}
|
||||
|
||||
static constexpr size_t BUF_CAPACITY = 2048;
|
||||
std::vector<uint8_t> buf(BUF_CAPACITY, 0);
|
||||
|
||||
@@ -87,8 +87,7 @@ bool CreateCoreLicenseResponseFromProto(const std::string& serialized_license,
|
||||
}
|
||||
parsed_lic.enc_mac_keys_iv =
|
||||
GetOecSubstring(serialized_license, k.iv());
|
||||
std::string mac_keys(k.key(), k.key().size());
|
||||
parsed_lic.enc_mac_keys = GetOecSubstring(serialized_license, mac_keys);
|
||||
parsed_lic.enc_mac_keys = GetOecSubstring(serialized_license, k.key());
|
||||
break;
|
||||
}
|
||||
case video_widevine::License_KeyContainer::CONTENT: {
|
||||
|
||||
@@ -190,9 +190,9 @@ OEMCryptoResult ODK_PrepareCoreRenewalRequest(uint8_t* message,
|
||||
* renewal. All releases use v15. */
|
||||
if (clock_values->timer_status == ODK_CLOCK_TIMER_STATUS_LICENSE_NOT_LOADED ||
|
||||
clock_values->timer_status == ODK_CLOCK_TIMER_STATUS_LICENSE_INACTIVE) {
|
||||
nonce_values->api_major_version = 15;
|
||||
nonce_values->api_major_version = ODK_FIRST_VERSION - 1;
|
||||
}
|
||||
if (nonce_values->api_major_version < 16) {
|
||||
if (nonce_values->api_major_version < ODK_FIRST_VERSION) {
|
||||
*core_message_size = 0;
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
@@ -270,12 +270,28 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
return err;
|
||||
}
|
||||
|
||||
/* This function should not be used for legacy licenses. */
|
||||
if (license_response.request.core_message.nonce_values.api_major_version !=
|
||||
ODK_MAJOR_VERSION) {
|
||||
/* We do not support future API version. Also, this function should not be
|
||||
* used for legacy licenses. */
|
||||
if (license_response.request.core_message.nonce_values.api_major_version >
|
||||
ODK_MAJOR_VERSION ||
|
||||
license_response.request.core_message.nonce_values.api_major_version <
|
||||
ODK_FIRST_VERSION) {
|
||||
return ODK_UNSUPPORTED_API;
|
||||
}
|
||||
|
||||
/* If the server sent us an older format, record the license's API version. */
|
||||
if (nonce_values->api_major_version >
|
||||
license_response.request.core_message.nonce_values.api_major_version) {
|
||||
nonce_values->api_major_version =
|
||||
license_response.request.core_message.nonce_values.api_major_version;
|
||||
nonce_values->api_minor_version =
|
||||
license_response.request.core_message.nonce_values.api_minor_version;
|
||||
} else if (nonce_values->api_minor_version >
|
||||
license_response.request.core_message.nonce_values
|
||||
.api_minor_version) {
|
||||
nonce_values->api_minor_version =
|
||||
license_response.request.core_message.nonce_values.api_minor_version;
|
||||
}
|
||||
/* If the license has a provider session token (pst), then OEMCrypto should
|
||||
* have a usage entry loaded. The opposite is also an error. */
|
||||
if ((usage_entry_present && parsed_license->pst.length == 0) ||
|
||||
@@ -302,7 +318,7 @@ OEMCryptoResult ODK_ParseLicense(
|
||||
* OEMCrypto stores a hash of the core license request and only signs the
|
||||
* message body. Here, when we process the license response, we verify that
|
||||
* the server has the same hash of the core request. */
|
||||
if (initial_license_load &&
|
||||
if (initial_license_load && parsed_license->nonce_required &&
|
||||
crypto_memcmp(request_hash, license_response.request_hash,
|
||||
ODK_SHA256_HASH_SIZE)) {
|
||||
return ODK_ERROR_CORE_MESSAGE;
|
||||
|
||||
@@ -10,11 +10,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if (__STDC_VERSION__ >= 201112L)
|
||||
# include <assert.h>
|
||||
# define odk_static_assert static_assert
|
||||
#include <assert.h>
|
||||
#define odk_static_assert static_assert
|
||||
#else
|
||||
# define odk_static_assert(msg, e) \
|
||||
enum { odk_static_assert = 1 / (!!((msg) && (e))) };
|
||||
#define odk_static_assert(msg, e) \
|
||||
enum { odk_static_assert = 1 / (!!((msg) && (e))) };
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -10,11 +10,11 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__ANDROID__)
|
||||
# include <endian.h>
|
||||
# define oemcrypto_htobe32 htobe32
|
||||
# define oemcrypto_be32toh be32toh
|
||||
# define oemcrypto_htobe64 htobe64
|
||||
# define oemcrypto_be64toh be64toh
|
||||
#include <endian.h>
|
||||
#define oemcrypto_htobe32 htobe32
|
||||
#define oemcrypto_be32toh be32toh
|
||||
#define oemcrypto_htobe64 htobe64
|
||||
#define oemcrypto_be64toh be64toh
|
||||
#else /* defined(__linux__) || defined(__ANDROID__) */
|
||||
uint32_t oemcrypto_htobe32(uint32_t u32);
|
||||
uint32_t oemcrypto_be32toh(uint32_t u32);
|
||||
|
||||
@@ -21,6 +21,10 @@ typedef enum {
|
||||
ODK_Renewal_Response_Type = 4,
|
||||
ODK_Provisioning_Request_Type = 5,
|
||||
ODK_Provisioning_Response_Type = 6,
|
||||
|
||||
/* Reserve future message types to support forward compatibility. */
|
||||
ODK_Release_Request_Type = 7,
|
||||
ODK_Release_Response_Type = 8,
|
||||
} ODK_MessageType;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "odk.h"
|
||||
#include "odk_overflow.h"
|
||||
#include "odk_structs_priv.h"
|
||||
|
||||
@@ -630,7 +630,7 @@ OEMCryptoResult LicenseRoundTrip::LoadResponse(Session* session) {
|
||||
|
||||
// Note: we verify content licenses here. For entitlement license, we verify
|
||||
// the key control blocks after loading entitled content keys.
|
||||
if (license_type_ == OEMCrypto_ContentLicense) VerifyTestKeys();
|
||||
if (license_type_ == OEMCrypto_ContentLicense) VerifyTestKeys(session);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -644,12 +644,12 @@ OEMCryptoResult LicenseRoundTrip::ReloadResponse(Session* session) {
|
||||
// with the truth key control block. Failures in this function probably
|
||||
// indicate the OEMCrypto_LoadLicense/LoadKeys did not correctly process the key
|
||||
// control block.
|
||||
void LicenseRoundTrip::VerifyTestKeys() {
|
||||
void LicenseRoundTrip::VerifyTestKeys(Session* session) {
|
||||
for (unsigned int i = 0; i < num_keys_; i++) {
|
||||
KeyControlBlock block;
|
||||
size_t size = sizeof(block);
|
||||
OEMCryptoResult sts = OEMCrypto_QueryKeyControl(
|
||||
session_->session_id(), response_data_.keys[i].key_id,
|
||||
session->session_id(), response_data_.keys[i].key_id,
|
||||
response_data_.keys[i].key_id_length,
|
||||
reinterpret_cast<uint8_t*>(&block), &size);
|
||||
if (sts != OEMCrypto_ERROR_NOT_IMPLEMENTED) {
|
||||
|
||||
@@ -298,7 +298,7 @@ class LicenseRoundTrip
|
||||
// Reload an offline license into a different session. This derives new mac
|
||||
// keys and then calls LoadResponse.
|
||||
OEMCryptoResult ReloadResponse(Session* session);
|
||||
void VerifyTestKeys();
|
||||
void VerifyTestKeys(Session* session);
|
||||
// Set the default key control block for all keys. This is used in
|
||||
// CreateDefaultResponse. The key control block determines the restrictions
|
||||
// that OEMCrypto should place on a key's use. For example, it specifies the
|
||||
|
||||
@@ -154,13 +154,13 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
||||
// tests are failing when the device has the wrong keybox installed.
|
||||
TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
const std::string log_message =
|
||||
"OEMCrypto unit tests for API 16.2. Tests last updated 2020-03-27";
|
||||
"OEMCrypto unit tests for API 16.3. Tests last updated 2020-06-01";
|
||||
cout << " " << log_message << "\n";
|
||||
LOGI("%s", log_message.c_str());
|
||||
// If any of the following fail, then it is time to update the log message
|
||||
// above.
|
||||
EXPECT_EQ(ODK_MAJOR_VERSION, 16);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 2);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 3);
|
||||
EXPECT_EQ(kCurrentAPI, 16u);
|
||||
const char* level = OEMCrypto_SecurityLevel();
|
||||
ASSERT_NE(nullptr, level);
|
||||
@@ -854,7 +854,13 @@ TEST_P(OEMCryptoLicenseTest, LoadKeyWithNoRequest) {
|
||||
license_messages_.core_request().api_minor_version = ODK_MINOR_VERSION;
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.CreateDefaultResponse());
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.EncryptAndSignResponse());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse());
|
||||
|
||||
// Load license in a different session, which did not create the request.
|
||||
Session session2;
|
||||
ASSERT_NO_FATAL_FAILURE(session2.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestRSAKey(&session2));
|
||||
ASSERT_NO_FATAL_FAILURE(session2.GenerateDerivedKeysFromSessionKey());
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, license_messages_.LoadResponse(&session2));
|
||||
}
|
||||
|
||||
// Verify that a license may be loaded with a nonce.
|
||||
@@ -2197,10 +2203,11 @@ class OEMCryptoSessionTestsDecryptTests
|
||||
void TestDecryptCENC() {
|
||||
OEMCryptoResult sts;
|
||||
|
||||
// OEMCrypto only supports providing a decrypt hash for one sample.
|
||||
if (samples_.size() > 1) verify_crc_ = false;
|
||||
|
||||
// If supported, check the decrypt hashes.
|
||||
if (verify_crc_) {
|
||||
// OEMCrypto only supports providing a decrypt hash for the first sample
|
||||
// in the sample array.
|
||||
const TestSample& sample = samples_[0];
|
||||
|
||||
uint32_t hash =
|
||||
@@ -2255,7 +2262,7 @@ class OEMCryptoSessionTestsDecryptTests
|
||||
}
|
||||
}
|
||||
}
|
||||
if (global_features.supports_crc) {
|
||||
if (verify_crc_) {
|
||||
uint32_t frame;
|
||||
ASSERT_EQ(OEMCrypto_GetHashErrorCode(session_.session_id(), &frame),
|
||||
OEMCrypto_SUCCESS);
|
||||
|
||||
Reference in New Issue
Block a user