Snap for 6553216 from f870da8567 to sc-release

Change-Id: I08ce6f6c48f1da3c151b294a27be2ba42415c55c
This commit is contained in:
android-build-team Robot
2020-06-03 02:08:49 +00:00
14 changed files with 90 additions and 40 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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: {

View File

@@ -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;

View File

@@ -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

View File

@@ -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);

View File

@@ -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 {

View File

@@ -4,6 +4,7 @@
#include <stdint.h>
#include <string.h>
#include "odk.h"
#include "odk_overflow.h"
#include "odk_structs_priv.h"

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);