Source release 19.4.0
This commit is contained in:
@@ -438,3 +438,6 @@ OEMCryptoResult _oecc153(OEMCrypto_SESSION session);
|
||||
// OEMCrypto_SetSessionUsage defined in v18.7
|
||||
OEMCryptoResult _oecc155(OEMCrypto_SESSION session, uint32_t intent,
|
||||
uint32_t mode);
|
||||
|
||||
// OEMCrypto_GetBCCSignatureType defined in v19.4
|
||||
OEMCryptoResult _oecc156(OEMCrypto_BCCSignatureType* bcc_signature_type);
|
||||
|
||||
@@ -17,6 +17,7 @@ void advance_dest_buffer(OEMCrypto_DestBufferDesc* dest_buffer, size_t bytes) {
|
||||
switch (dest_buffer->type) {
|
||||
case OEMCrypto_BufferType_Clear:
|
||||
dest_buffer->buffer.clear.clear_buffer += bytes;
|
||||
dest_buffer->buffer.clear.clear_buffer_length -= bytes;
|
||||
break;
|
||||
|
||||
case OEMCrypto_BufferType_Secure:
|
||||
@@ -98,11 +99,6 @@ OEMCryptoResult DecryptFallbackChain::DecryptSample(
|
||||
const size_t length =
|
||||
subsample.num_bytes_clear + subsample.num_bytes_encrypted;
|
||||
fake_sample.buffers.input_data_length = length;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
length;
|
||||
}
|
||||
fake_sample.subsamples = &subsample;
|
||||
fake_sample.subsamples_length = 1;
|
||||
|
||||
@@ -148,11 +144,6 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample(
|
||||
|
||||
if (subsample.num_bytes_clear > 0) {
|
||||
fake_sample.buffers.input_data_length = subsample.num_bytes_clear;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
subsample.num_bytes_clear;
|
||||
}
|
||||
fake_subsample.num_bytes_clear = subsample.num_bytes_clear;
|
||||
fake_subsample.num_bytes_encrypted = 0;
|
||||
fake_subsample.block_offset = 0;
|
||||
@@ -176,11 +167,6 @@ OEMCryptoResult DecryptFallbackChain::DecryptSubsample(
|
||||
|
||||
if (subsample.num_bytes_encrypted > 0) {
|
||||
fake_sample.buffers.input_data_length = subsample.num_bytes_encrypted;
|
||||
if (fake_sample.buffers.output_descriptor.type ==
|
||||
OEMCrypto_BufferType_Clear) {
|
||||
fake_sample.buffers.output_descriptor.buffer.clear.clear_buffer_length =
|
||||
subsample.num_bytes_encrypted;
|
||||
}
|
||||
fake_subsample.num_bytes_clear = 0;
|
||||
fake_subsample.num_bytes_encrypted = subsample.num_bytes_encrypted;
|
||||
fake_subsample.block_offset = subsample.block_offset;
|
||||
|
||||
@@ -287,6 +287,7 @@ class ProvisioningRoundTrip
|
||||
OEMCryptoResult LoadResponse() override { return LoadResponse(session_); }
|
||||
OEMCryptoResult LoadResponse(Session* session) override;
|
||||
void VerifyLoadFailed();
|
||||
const std::vector<uint8_t>& request() { return request_; }
|
||||
const std::vector<uint8_t>& encoded_rsa_key() { return encoded_rsa_key_; }
|
||||
const std::vector<uint8_t>& wrapped_rsa_key() { return wrapped_rsa_key_; }
|
||||
void set_allowed_schemes(uint32_t allowed_schemes) {
|
||||
|
||||
@@ -73,6 +73,76 @@ int32_t JsmnAncestorCount(const std::vector<jsmntok_t>& tokens,
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const char* BoolName(bool value) { return value ? "true" : "false"; }
|
||||
const char* SecurityLevelName(OEMCrypto_Security_Level value) {
|
||||
switch (value) {
|
||||
case OEMCrypto_Level_Unknown:
|
||||
return "OEMCrypto_Level_Unknown";
|
||||
case OEMCrypto_Level1:
|
||||
return "OEMCrypto_Level1";
|
||||
case OEMCrypto_Level2:
|
||||
return "OEMCrypto_Level2";
|
||||
case OEMCrypto_Level3:
|
||||
return "OEMCrypto_Level3";
|
||||
}
|
||||
// Not reachable unless the enum value is invalid
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
const char* HDCPCapabilityName(OEMCrypto_HDCP_Capability value) {
|
||||
switch (value) {
|
||||
case HDCP_NONE:
|
||||
return "HDCP_NONE";
|
||||
case HDCP_V1:
|
||||
return "HDCP_V1";
|
||||
case HDCP_V1_0:
|
||||
return "HDCP_V1_0";
|
||||
case HDCP_V1_1:
|
||||
return "HDCP_V1_1";
|
||||
case HDCP_V1_2:
|
||||
return "HDCP_V1_2";
|
||||
case HDCP_V1_3:
|
||||
return "HDCP_V1_3";
|
||||
case HDCP_V1_4:
|
||||
return "HDCP_V1_4";
|
||||
case HDCP_V2:
|
||||
return "HDCP_V2";
|
||||
case HDCP_V2_1:
|
||||
return "HDCP_V2_1";
|
||||
case HDCP_V2_2:
|
||||
return "HDCP_V2_2";
|
||||
case HDCP_V2_3:
|
||||
return "HDCP_V2_3";
|
||||
case HDCP_NO_DIGITAL_OUTPUT:
|
||||
return "HDCP_NO_DIGITAL_OUTPUT";
|
||||
}
|
||||
// Not reachable unless the enum value is invalid
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
const char* WatermarkingSupportName(OEMCrypto_WatermarkingSupport value) {
|
||||
switch (value) {
|
||||
case OEMCrypto_WatermarkingError:
|
||||
return "OEMCrypto_WatermarkingError";
|
||||
case OEMCrypto_WatermarkingNotSupported:
|
||||
return "OEMCrypto_WatermarkingNotSupported";
|
||||
case OEMCrypto_WatermarkingConfigurable:
|
||||
return "OEMCrypto_WatermarkingConfigurable";
|
||||
case OEMCrypto_WatermarkingAlwaysOn:
|
||||
return "OEMCrypto_WatermarkingAlwaysOn";
|
||||
}
|
||||
// Not reachable unless the enum value is invalid
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
const char* DTCP2CapabiityName(OEMCrypto_DTCP2_Capability value) {
|
||||
switch (value) {
|
||||
case OEMCrypto_NO_DTCP2:
|
||||
return "OEMCrypto_NO_DTCP2";
|
||||
case OEMCrypto_DTCP2_V1:
|
||||
return "OEMCrypto_DTCP2_V1";
|
||||
}
|
||||
// Not reachable unless the enum value is invalid
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void OEMCryptoClientTest::SetUp() {
|
||||
@@ -148,6 +218,11 @@ OEMCryptoResult OEMCryptoClientTest::CopyBuffer(
|
||||
dest_buffer_descriptor, subsample_flags);
|
||||
}
|
||||
|
||||
void OEMCryptoClientTest::RecordWvProperty(const std::string& key,
|
||||
const std::string& value) {
|
||||
RecordProperty("widevine_metadata_oec_" + key, value);
|
||||
}
|
||||
|
||||
const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
||||
switch (value) {
|
||||
case HDCP_NONE:
|
||||
@@ -174,9 +249,9 @@ const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value) {
|
||||
return "HDCP version 2.3";
|
||||
case HDCP_NO_DIGITAL_OUTPUT:
|
||||
return "No HDCP device attached/using local display with secure path";
|
||||
default:
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
// Not reachable unless the enum value is invalid
|
||||
return "<INVALID VALUE>";
|
||||
}
|
||||
|
||||
// Return a printable string from data. If all the characters are printable,
|
||||
@@ -242,40 +317,55 @@ TEST_F(OEMCryptoClientTest, FreeUnallocatedSecureBufferNoFailure) {
|
||||
*/
|
||||
TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
const std::string log_message =
|
||||
"OEMCrypto unit tests for API 19.3. Tests last updated 2024-09-04";
|
||||
"OEMCrypto unit tests for API 19.4. Tests last updated 2024-11-04";
|
||||
cout << " " << log_message << "\n";
|
||||
cout << " " << "These tests are part of Android V." << "\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, 19);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 3);
|
||||
EXPECT_EQ(ODK_MINOR_VERSION, 4);
|
||||
EXPECT_EQ(kCurrentAPI, static_cast<unsigned>(ODK_MAJOR_VERSION));
|
||||
RecordWvProperty("test_major_version", std::to_string(ODK_MAJOR_VERSION));
|
||||
RecordWvProperty("test_minor_version", std::to_string(ODK_MINOR_VERSION));
|
||||
|
||||
OEMCrypto_Security_Level level = OEMCrypto_SecurityLevel();
|
||||
EXPECT_GT(level, OEMCrypto_Level_Unknown);
|
||||
EXPECT_LE(level, OEMCrypto_Level3);
|
||||
cout << " OEMCrypto Security Level is L" << level << endl;
|
||||
RecordWvProperty("security_level", SecurityLevelName(level));
|
||||
|
||||
uint32_t version = OEMCrypto_APIVersion();
|
||||
uint32_t minor_version = OEMCrypto_MinorAPIVersion();
|
||||
cout << " OEMCrypto API version is " << version << "."
|
||||
<< minor_version << endl;
|
||||
RecordWvProperty("major_version", std::to_string(version));
|
||||
RecordWvProperty("minor_version", std::to_string(minor_version));
|
||||
|
||||
cout << " OEMCrypto Device ID is '" << GetDeviceId() << "'"
|
||||
<< endl;
|
||||
|
||||
if (OEMCrypto_SupportsUsageTable()) {
|
||||
const bool supports_usage_tables = OEMCrypto_SupportsUsageTable();
|
||||
if (supports_usage_tables) {
|
||||
cout << " OEMCrypto supports usage tables" << endl;
|
||||
} else {
|
||||
cout << " OEMCrypto does not support usage tables" << endl;
|
||||
}
|
||||
RecordWvProperty("supports_usage_tables", BoolName(supports_usage_tables));
|
||||
|
||||
if (version >= 15) {
|
||||
const uint32_t tier = OEMCrypto_ResourceRatingTier();
|
||||
cout << " Resource Rating Tier: " << tier << endl;
|
||||
RecordWvProperty("resource_rating_tier", std::to_string(tier));
|
||||
}
|
||||
|
||||
if (version >= 17) {
|
||||
OEMCryptoResult sts = OEMCrypto_ProductionReady();
|
||||
if (sts != OEMCrypto_SUCCESS) {
|
||||
LOGW("Device is not production ready, returns %d", sts);
|
||||
}
|
||||
RecordWvProperty("is_production_ready", BoolName(sts == OEMCrypto_SUCCESS));
|
||||
|
||||
std::string build_info;
|
||||
size_t buf_length = 0;
|
||||
sts = OEMCrypto_BuildInformation(&build_info[0], &buf_length);
|
||||
@@ -287,6 +377,7 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
if (build_info.size() != buf_length) {
|
||||
build_info.resize(buf_length);
|
||||
}
|
||||
RecordWvProperty("build_info", build_info);
|
||||
const std::string comma = ",";
|
||||
const std::string pretty_comma = ",\n ";
|
||||
std::string::size_type pos = 0;
|
||||
@@ -295,9 +386,12 @@ TEST_F(OEMCryptoClientTest, VersionNumber) {
|
||||
pos += pretty_comma.size();
|
||||
}
|
||||
cout << " BuildInformation: " << build_info << endl;
|
||||
|
||||
OEMCrypto_WatermarkingSupport support = OEMCrypto_GetWatermarkingSupport();
|
||||
cout << " WatermarkingSupport: " << support << endl;
|
||||
RecordWvProperty("watermarking_support", WatermarkingSupportName(support));
|
||||
}
|
||||
|
||||
ASSERT_GE(version, 8u);
|
||||
ASSERT_LE(version, kCurrentAPI);
|
||||
}
|
||||
@@ -317,8 +411,9 @@ TEST_F(OEMCryptoClientTest, ResourceRatingAPI15) {
|
||||
TEST_F(OEMCryptoClientTest, ProvisioningDeclaredAPI12) {
|
||||
OEMCrypto_ProvisioningMethod provisioning_method =
|
||||
OEMCrypto_GetProvisioningMethod();
|
||||
cout << " Provisioning method = "
|
||||
<< ProvisioningMethodName(provisioning_method) << endl;
|
||||
const char* const name = ProvisioningMethodName(provisioning_method);
|
||||
cout << " Provisioning method = " << name << endl;
|
||||
RecordWvProperty("provisioning_method", name);
|
||||
ASSERT_NE(OEMCrypto_ProvisioningError, provisioning_method);
|
||||
}
|
||||
|
||||
@@ -331,6 +426,8 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapabilityAPI09) {
|
||||
static_cast<unsigned int>(current), HDCPCapabilityAsString(current));
|
||||
printf(" Maximum HDCP Capability: 0x%02x = %s.\n",
|
||||
static_cast<unsigned int>(maximum), HDCPCapabilityAsString(maximum));
|
||||
RecordWvProperty("hdcp_current", HDCPCapabilityName(current));
|
||||
RecordWvProperty("hdcp_max", HDCPCapabilityName(maximum));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) {
|
||||
@@ -339,11 +436,15 @@ TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) {
|
||||
OEMCryptoResult current_result = OEMCrypto_GetCurrentSRMVersion(&version);
|
||||
if (current_result == OEMCrypto_SUCCESS) {
|
||||
printf(" Current SRM Version: %d.\n", version);
|
||||
RecordWvProperty("srm_supported", BoolName(true));
|
||||
RecordWvProperty("srm_version", std::to_string(version));
|
||||
EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_GetCurrentSRMVersion(nullptr));
|
||||
} else if (current_result == OEMCrypto_LOCAL_DISPLAY_ONLY) {
|
||||
printf(" Current SRM Status: Local Display Only.\n");
|
||||
RecordWvProperty("srm_supported", BoolName(false));
|
||||
} else {
|
||||
EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result);
|
||||
RecordWvProperty("srm_supported", BoolName(false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,6 +687,9 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
|
||||
{"is_debug", JSMN_PRIMITIVE},
|
||||
};
|
||||
|
||||
// The prefix of every field name when logged to RecordWvProperty.
|
||||
const std::string kBuildInfoRecordPrefix = "build_info_";
|
||||
|
||||
// A set of the required fields found when examining the
|
||||
// build information, use to verify all fields are present.
|
||||
std::set<std::string> found_required_fields;
|
||||
@@ -612,11 +716,17 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
|
||||
<< "Unexpected required field type: field = " << key
|
||||
<< ", build_info = " << build_info;
|
||||
found_required_fields.insert(key);
|
||||
RecordWvProperty(kBuildInfoRecordPrefix + key,
|
||||
build_info.substr(value_token.start,
|
||||
value_token.end - value_token.start));
|
||||
} else if (kOptionalFields.find(key) != kOptionalFields.end()) {
|
||||
ASSERT_EQ(value_token.type, kOptionalFields.at(key))
|
||||
<< "Unexpected optional field type: field = " << key
|
||||
<< ", build_info = " << build_info;
|
||||
} // Do not validate vendor fields.
|
||||
RecordWvProperty(kBuildInfoRecordPrefix + key,
|
||||
build_info.substr(value_token.start,
|
||||
value_token.end - value_token.start));
|
||||
} // Do not validate or record vendor fields.
|
||||
|
||||
if (key == kSpecialCaseReeKey) {
|
||||
// Store the tokens of the "ree" field for additional validation.
|
||||
@@ -657,6 +767,11 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
|
||||
// If no "ree" field tokens, then end here.
|
||||
if (!has_ree_info) return;
|
||||
// Step 4a: Verify "ree" object scheme.
|
||||
|
||||
// The prefix of every REE field name when logged to RecordWvProperty.
|
||||
const std::string kReeBuildInfoRecordPrefix =
|
||||
kBuildInfoRecordPrefix + kSpecialCaseReeKey + "_";
|
||||
|
||||
ASSERT_FALSE(ree_tokens.empty())
|
||||
<< "REE field was specified, but contents were empty: build_info = "
|
||||
<< build_info;
|
||||
@@ -686,7 +801,10 @@ TEST_F(OEMCryptoClientTest, CheckJsonBuildInformationAPI18) {
|
||||
<< "Unexpected optional REE field type: ree_field = " << key
|
||||
<< ", build_info = " << build_info;
|
||||
found_required_fields.insert(key);
|
||||
} // Do not validate vendor fields.
|
||||
RecordWvProperty(kReeBuildInfoRecordPrefix + key,
|
||||
build_info.substr(value_token.start,
|
||||
value_token.end - value_token.start));
|
||||
} // Do not validate or record vendor fields.
|
||||
|
||||
// Skip potential nested tokens.
|
||||
i += JsmnAncestorCount(ree_tokens, i + 1);
|
||||
@@ -722,6 +840,7 @@ TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
||||
OEMCryptoResult sts = OEMCrypto_GetMaxNumberOfSessions(&maximum);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
printf(" Max Number of Sessions: %zu.\n", maximum);
|
||||
RecordWvProperty("max_number_of_sessions", std::to_string(maximum));
|
||||
size_t required_max = GetResourceValue(kMaxConcurrentSession);
|
||||
ASSERT_GE(maximum, required_max);
|
||||
}
|
||||
@@ -729,6 +848,7 @@ TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
||||
TEST_F(OEMCryptoClientTest, CheckUsageTableSizeAPI16) {
|
||||
const size_t maximum = OEMCrypto_MaximumUsageTableHeaderSize();
|
||||
printf(" Max Usage Table Size: %zu.\n", maximum);
|
||||
RecordWvProperty("max_usage_table_size", std::to_string(maximum));
|
||||
// A maximum of 0 means the table is constrained by dynamic memory allocation.
|
||||
if (maximum > 0) {
|
||||
ASSERT_GE(maximum, RequiredUsageSize());
|
||||
@@ -765,6 +885,7 @@ TEST_F(OEMCryptoClientTest, CheckDTCP2CapabilityAPI17) {
|
||||
"DTCP2 is supported.\n");
|
||||
break;
|
||||
}
|
||||
RecordWvProperty("dtcp2_capability", DTCP2CapabiityName(capability));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -35,6 +35,7 @@ class OEMCryptoClientTest : public ::testing::Test, public SessionUtil {
|
||||
size_t input_buffer_size,
|
||||
const OEMCrypto_DestBufferDesc* dest_buffer_descriptor,
|
||||
uint8_t subsample_flags);
|
||||
void RecordWvProperty(const std::string& key, const std::string& value);
|
||||
};
|
||||
} // namespace wvoec
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "oemcrypto_cast_test.h"
|
||||
|
||||
#include "oemcrypto_usage_table_test.h"
|
||||
|
||||
using ::testing::Range;
|
||||
|
||||
namespace wvoec {
|
||||
@@ -260,18 +258,8 @@ class OEMCryptoCastReceiverTest : public OEMCryptoLoadsCertificateAlternates {
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadWrappedRsaDrmKey(wrapped_drm_key_));
|
||||
|
||||
// The application will compute the SHA-1 Hash of the message, so this
|
||||
// test must do that also.
|
||||
uint8_t hash[SHA_DIGEST_LENGTH];
|
||||
if (!SHA1(message.data(), message.size(), hash)) {
|
||||
dump_boringssl_error();
|
||||
FAIL() << "boringssl error creating SHA1 hash.";
|
||||
}
|
||||
|
||||
// The application will prepend the digest info to the hash.
|
||||
// SHA-1 digest info prefix = 0x30 0x21 0x30 ...
|
||||
vector<uint8_t> digest = wvutil::a2b_hex("3021300906052b0e03021a05000414");
|
||||
digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH);
|
||||
vector<uint8_t> digest;
|
||||
ASSERT_NO_FATAL_FAILURE(PrepareCastDigestedMessage(message, digest));
|
||||
|
||||
// OEMCrypto will apply the padding, and encrypt to generate the
|
||||
// signature.
|
||||
@@ -1019,5 +1007,6 @@ TEST_P(OEMCryptoSessionTestLoadCasKeysWithHDCP, CasOnlyLoadCasKeysAPI17) {
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(TestHDCP, OEMCryptoSessionTestLoadCasKeysWithHDCP,
|
||||
Range(1, 6));
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "OEMCryptoCENC.h"
|
||||
#include "oemcrypto_provisioning_test.h"
|
||||
#include "oemcrypto_session_tests_helper.h"
|
||||
#include "oemcrypto_usage_table_test.h"
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
@@ -22,6 +23,25 @@ const char* HDCPCapabilityAsString(OEMCrypto_HDCP_Capability value);
|
||||
// This test attempts to use alternate algorithms for loaded device certs.
|
||||
class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
|
||||
protected:
|
||||
// The message to be signed by OEMCrypto_GenerateRSASignature() starts with a
|
||||
// constant digest info prefix followed by a SHA-1 hash of the message.
|
||||
void PrepareCastDigestedMessage(const std::vector<uint8_t>& message,
|
||||
std::vector<uint8_t>& digest) {
|
||||
// The application will compute the SHA-1 Hash of the message, so this
|
||||
// test must do that also.
|
||||
uint8_t hash[SHA_DIGEST_LENGTH];
|
||||
if (!SHA1(message.data(), message.size(), hash)) {
|
||||
dump_boringssl_error();
|
||||
FAIL() << "boringssl error creating SHA1 hash.";
|
||||
}
|
||||
// The application will prepend the digest info to the hash.
|
||||
// SHA-1 digest info prefix = 0x30 0x21 0x30 ...
|
||||
static const std::vector<uint8_t> prefix =
|
||||
wvutil::a2b_hex("3021300906052b0e03021a05000414");
|
||||
digest.insert(digest.end(), prefix.begin(), prefix.end());
|
||||
digest.insert(digest.end(), hash, hash + SHA_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
void TestSignature(RSA_Padding_Scheme scheme, size_t size) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
@@ -29,16 +49,19 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
|
||||
|
||||
vector<uint8_t> licenseRequest(size);
|
||||
GetRandBytes(licenseRequest.data(), licenseRequest.size());
|
||||
vector<uint8_t> digested_message;
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
PrepareCastDigestedMessage(licenseRequest, digested_message));
|
||||
size_t signature_length = 0;
|
||||
OEMCryptoResult sts = OEMCrypto_GenerateRSASignature(
|
||||
s.session_id(), licenseRequest.data(), licenseRequest.size(), nullptr,
|
||||
&signature_length, scheme);
|
||||
s.session_id(), digested_message.data(), digested_message.size(),
|
||||
nullptr, &signature_length, scheme);
|
||||
ASSERT_EQ(OEMCrypto_ERROR_SHORT_BUFFER, sts);
|
||||
ASSERT_NE(static_cast<size_t>(0), signature_length);
|
||||
|
||||
std::vector<uint8_t> signature(signature_length, 0);
|
||||
sts = OEMCrypto_GenerateRSASignature(
|
||||
s.session_id(), licenseRequest.data(), licenseRequest.size(),
|
||||
s.session_id(), digested_message.data(), digested_message.size(),
|
||||
signature.data(), &signature_length, scheme);
|
||||
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts)
|
||||
@@ -48,7 +71,7 @@ class OEMCryptoLoadsCertificateAlternates : public OEMCryptoLoadsCertificate {
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromPrivateKeyInfo(
|
||||
encoded_rsa_key_.data(), encoded_rsa_key_.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyRsaSignature(
|
||||
licenseRequest, signature.data(), signature_length, scheme));
|
||||
digested_message, signature.data(), signature_length, scheme));
|
||||
}
|
||||
|
||||
// If force is true, we assert that the key loads successfully.
|
||||
|
||||
@@ -13,6 +13,9 @@ using ::testing::Values;
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
/// @addtogroup decrypt
|
||||
/// @{
|
||||
|
||||
// Cannot decrypt without first getting a key handle.
|
||||
TEST_P(OEMCryptoLicenseTest, FailDecryptWithoutGettingAHandle) {
|
||||
ASSERT_NO_FATAL_FAILURE(license_messages_.SignAndVerifyRequest());
|
||||
@@ -658,4 +661,5 @@ TEST_P(OEMCryptoLicenseTest, KeyDuration) {
|
||||
INSTANTIATE_TEST_SUITE_P(TestAll, OEMCryptoLicenseTest,
|
||||
Range<uint32_t>(kCurrentAPI - 2, kCurrentAPI + 1));
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "oemcrypto_license_test.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "platform.h"
|
||||
#include "test_sleep.h"
|
||||
|
||||
@@ -769,6 +771,7 @@ TEST_P(OEMCryptoLicenseTest, MaxTotalKeysManySessions) {
|
||||
TEST_F(OEMCryptoSessionTests, CheckMinimumPatchLevel) {
|
||||
uint8_t patch_level = OEMCrypto_Security_Patch_Level();
|
||||
printf(" Current Patch Level: %u.\n", patch_level);
|
||||
RecordWvProperty("security_patch_level", std::to_string(patch_level));
|
||||
{
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
|
||||
#include "oemcrypto_provisioning_test.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "bcc_validator.h"
|
||||
#include "device_info_validator.h"
|
||||
#include "log.h"
|
||||
@@ -15,6 +19,9 @@
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
/// @addtogroup provision
|
||||
/// @{
|
||||
|
||||
// This test is used to print the device ID to stdout.
|
||||
TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) {
|
||||
OEMCryptoResult sts;
|
||||
@@ -24,6 +31,7 @@ TEST_F(OEMCryptoKeyboxTest, NormalGetDeviceId) {
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
cout << " NormalGetDeviceId: dev_id = "
|
||||
<< MaybeHex(dev_id, dev_id_len) << " len = " << dev_id_len << endl;
|
||||
RecordWvProperty("device_id", wvutil::HexEncode(dev_id, dev_id_len));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoKeyboxTest, GetDeviceIdShortBuffer) {
|
||||
@@ -53,8 +61,12 @@ TEST_F(OEMCryptoKeyboxTest, NormalGetKeyData) {
|
||||
sts = OEMCrypto_GetKeyData(key_data, &key_data_len);
|
||||
|
||||
uint32_t* data = reinterpret_cast<uint32_t*>(key_data);
|
||||
const uint32_t system_id = htonl(data[1]);
|
||||
const uint32_t version = htonl(data[0]);
|
||||
printf(" NormalGetKeyData: system_id = %u = 0x%04X, version=%u\n",
|
||||
htonl(data[1]), htonl(data[1]), htonl(data[0]));
|
||||
system_id, system_id, version);
|
||||
RecordWvProperty("system_id", std::to_string(system_id));
|
||||
RecordWvProperty("key_data_version", std::to_string(version));
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
}
|
||||
|
||||
@@ -91,6 +103,8 @@ TEST_F(OEMCryptoProv30Test, GetDeviceId) {
|
||||
dev_id.resize(dev_id_len);
|
||||
cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id)
|
||||
<< " len = " << dev_id_len << endl;
|
||||
RecordWvProperty("device_id",
|
||||
wvutil::HexEncode(dev_id.data(), dev_id.size()));
|
||||
}
|
||||
|
||||
// The OEM certificate must be valid.
|
||||
@@ -241,6 +255,35 @@ TEST_F(OEMCryptoProv40Test, GetBootCertificateChainSuccess) {
|
||||
EXPECT_EQ(util::CborMessageStatus::kCborValidateOk, validator.Validate());
|
||||
}
|
||||
|
||||
// Verifies BCC signature and its type if they are available.
|
||||
TEST_F(OEMCryptoProv40Test, AdditionalBccSignature) {
|
||||
std::vector<uint8_t> bcc;
|
||||
size_t bcc_size = 0;
|
||||
std::vector<uint8_t> additional_signature;
|
||||
size_t additional_signature_size = 0;
|
||||
ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size,
|
||||
additional_signature.data(),
|
||||
&additional_signature_size),
|
||||
OEMCrypto_ERROR_SHORT_BUFFER);
|
||||
|
||||
bcc.resize(bcc_size);
|
||||
additional_signature.resize(additional_signature_size);
|
||||
ASSERT_EQ(OEMCrypto_GetBootCertificateChain(bcc.data(), &bcc_size,
|
||||
additional_signature.data(),
|
||||
&additional_signature_size),
|
||||
OEMCrypto_SUCCESS);
|
||||
OEMCrypto_BCCSignatureType bcc_signature_type;
|
||||
const OEMCryptoResult result =
|
||||
OEMCrypto_GetBCCSignatureType(&bcc_signature_type);
|
||||
if (result == OEMCrypto_ERROR_NOT_IMPLEMENTED) return;
|
||||
ASSERT_EQ(result, OEMCrypto_SUCCESS);
|
||||
if (!additional_signature.empty()) {
|
||||
ASSERT_NE(bcc_signature_type, OEMCrypto_BCCSigType_Unknown);
|
||||
} else {
|
||||
ASSERT_EQ(bcc_signature_type, OEMCrypto_BCCSigType_Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies that short buffer error returns when the buffer is short.
|
||||
TEST_F(OEMCryptoProv40Test, GenerateCertificateKeyPairShortBuffer) {
|
||||
Session s;
|
||||
@@ -546,13 +589,13 @@ TEST_F(OEMCryptoProv40Test, InstallOemPrivateKeyCanBeUsed) {
|
||||
wrapped_private_key2.resize(wrapped_private_key_size2);
|
||||
|
||||
// Verify public_key_signature2 with public_key1.
|
||||
if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) {
|
||||
if (key_type1 == OEMCrypto_PrivateKeyType::OEMCrypto_RSA_Private_Key) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetRsaPublicKeyFromSubjectPublicKey(
|
||||
public_key1.data(), public_key1.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.VerifyRsaSignature(public_key2, public_key_signature2.data(),
|
||||
public_key_signature2.size(), kSign_RSASSA_PSS));
|
||||
} else if (key_type2 == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) {
|
||||
} else if (key_type1 == OEMCrypto_PrivateKeyType::OEMCrypto_ECC_Private_Key) {
|
||||
ASSERT_NO_FATAL_FAILURE(s.SetEccPublicKeyFromSubjectPublicKey(
|
||||
public_key1.data(), public_key1.size()));
|
||||
ASSERT_NO_FATAL_FAILURE(s.VerifyEccSignature(public_key2,
|
||||
@@ -620,6 +663,8 @@ TEST_F(OEMCryptoProv40Test, GetDeviceId) {
|
||||
dev_id.resize(dev_id_len);
|
||||
cout << " NormalGetDeviceId: dev_id = " << MaybeHex(dev_id)
|
||||
<< " len = " << dev_id_len << endl;
|
||||
RecordWvProperty("device_id",
|
||||
wvutil::HexEncode(dev_id.data(), dev_id.size()));
|
||||
// Device id should be stable. Query again.
|
||||
std::vector<uint8_t> dev_id2(dev_id_len);
|
||||
sts = OEMCrypto_GetDeviceID(dev_id2.data(), &dev_id_len);
|
||||
@@ -1282,4 +1327,5 @@ TEST_F(OEMCryptoLoadsCertificate, SupportsCertificatesAPI13) {
|
||||
<< "Supported certificates is only " << OEMCrypto_SupportedCertificates();
|
||||
}
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,9 @@
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
/// @addtogroup android
|
||||
/// @{
|
||||
|
||||
/** These tests are required for LollyPop Android devices.*/
|
||||
class OEMCryptoAndroidLMPTest : public ::testing::Test {
|
||||
protected:
|
||||
@@ -102,7 +105,7 @@ TEST_F(OEMCryptoAndroidMNCTest, LoadsTestKeyboxImplemented) {
|
||||
}
|
||||
|
||||
/** Android requires implementation of functions that report how many open
|
||||
* sesions are available. */
|
||||
* sessions are available. */
|
||||
TEST_F(OEMCryptoAndroidMNCTest, NumberOfSessionsImplemented) {
|
||||
ASSERT_NE(OEMCrypto_ERROR_NOT_IMPLEMENTED,
|
||||
OEMCrypto_GetNumberOfOpenSessions(nullptr));
|
||||
@@ -126,4 +129,5 @@ TEST_F(OEMCryptoAndroidRVCTest, MinVersionNumber16) {
|
||||
ASSERT_GE(version, 16u);
|
||||
}
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
'oemcrypto_generic_crypto_test.cpp',
|
||||
'oemcrypto_license_test.cpp',
|
||||
'oemcrypto_provisioning_test.cpp',
|
||||
'oemcrypto_security_test.cpp',
|
||||
'oemcrypto_usage_table_test.cpp',
|
||||
'oemcrypto_test.cpp',
|
||||
'<(jsmn_dir)/jsmn.c',
|
||||
|
||||
@@ -10,6 +10,9 @@ using ::testing::Values;
|
||||
|
||||
namespace wvoec {
|
||||
|
||||
/// @addtogroup usage_table
|
||||
/// @{
|
||||
|
||||
// Test that successive calls to PrepAndSignProvisioningRequest only increase
|
||||
// the provisioning count in the ODK message
|
||||
TEST_F(OEMCryptoSessionTests, Provisioning_IncrementCounterAPI18) {
|
||||
@@ -1810,4 +1813,5 @@ INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableDefragTest,
|
||||
INSTANTIATE_TEST_SUITE_P(TestAPI16, OEMCryptoUsageTableTestWallClock,
|
||||
Values<uint32_t>(kCurrentAPI));
|
||||
|
||||
/// @}
|
||||
} // namespace wvoec
|
||||
|
||||
Reference in New Issue
Block a user