Merge "Unit Test Updates for v13"
This commit is contained in:
committed by
Android (Google) Code Review
commit
de6d208380
@@ -697,6 +697,63 @@ bool SessionContext::LoadRSAKey(const uint8_t* pkcs8_rsa_key,
|
||||
return rsa_key_.LoadPkcs8RsaKey(pkcs8_rsa_key, rsa_key_length);
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::AllowKeyUse(const std::string& log_string,
|
||||
uint32_t use_type,
|
||||
OEMCryptoBufferType buffer_type) {
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
if (use_type && (!(control.control_bits() & use_type))) {
|
||||
LOGE("[%s(): control bit says not allowed.", log_string.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.control_bits() & kControlDataPathSecure) {
|
||||
if (!ce_->config_closed_platform() &&
|
||||
buffer_type == OEMCrypto_BufferType_Clear) {
|
||||
LOGE("[%s(): Secure key with insecure buffer]", log_string.c_str());
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[%s(): usage entry not valid]", log_string.c_str());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[%s(): key expired.", log_string.c_str());
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (!ce_->config_local_display_only()) {
|
||||
// Only look at HDCP and Analog restrictions if the display is non-local.
|
||||
if (control.control_bits() & kControlHDCPRequired) {
|
||||
uint8_t required_hdcp =
|
||||
(control.control_bits() & kControlHDCPVersionMask) >>
|
||||
kControlHDCPVersionShift;
|
||||
// For reference implementation, we pretend we can handle the current
|
||||
// HDCP version.
|
||||
if (required_hdcp > ce_->config_current_hdcp_capability() ||
|
||||
ce_->config_current_hdcp_capability() == 0) {
|
||||
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlSRMVersionRequired) {
|
||||
LOGE("[%s(): control bit says SRM version required.",
|
||||
log_string.c_str());
|
||||
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
|
||||
}
|
||||
}
|
||||
if (!ce_->config_local_display_only()
|
||||
|| buffer_type == OEMCrypto_BufferType_Clear) {
|
||||
if (control.control_bits() & kControlDisableAnalogOutput) {
|
||||
LOGE("[%s(): control bit says disable analog.",
|
||||
log_string.c_str());
|
||||
return OEMCrypto_ERROR_ANALOG_OUTPUT;
|
||||
}
|
||||
}
|
||||
return OEMCrypto_SUCCESS;
|
||||
}
|
||||
|
||||
OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
size_t buffer_length,
|
||||
const uint8_t* iv,
|
||||
@@ -708,28 +765,14 @@ OEMCryptoResult SessionContext::Generic_Encrypt(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
||||
}
|
||||
const std::vector<uint8_t>& key = current_content_key()->value();
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
// Set the AES key.
|
||||
if (static_cast<int>(key.size()) != AES_BLOCK_SIZE) {
|
||||
LOGE("[Generic_Encrypt(): CONTENT_KEY has wrong size: %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (!(control.control_bits() & kControlAllowEncrypt)) {
|
||||
LOGE("[Generic_Encrypt(): control bit says not allowed.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[Generic_Encrypt(): key expired.");
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[Generic_Encrypt(): usage entry not valid]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
OEMCryptoResult result = AllowKeyUse("Generic_Encrypt", kControlAllowEncrypt,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
|
||||
LOGE("[Generic_Encrypt(): algorithm bad.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -762,34 +805,15 @@ OEMCryptoResult SessionContext::Generic_Decrypt(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_NO_CONTENT_KEY;
|
||||
}
|
||||
const std::vector<uint8_t>& key = current_content_key()->value();
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
// Set the AES key.
|
||||
if (static_cast<int>(key.size()) != AES_BLOCK_SIZE) {
|
||||
LOGE("[Generic_Decrypt(): CONTENT_KEY has wrong size.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (!(control.control_bits() & kControlAllowDecrypt)) {
|
||||
LOGE("[Generic_Decrypt(): control bit says not allowed.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.control_bits() & kControlDataPathSecure) {
|
||||
if (!ce_->config_closed_platform()) {
|
||||
LOGE("[Generic_Decrypt(): control bit says secure path only.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[Generic_Decrypt(): key expired.");
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[Generic_Decrypt(): usage entry not valid]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
OEMCryptoResult result = AllowKeyUse("Generic_Decrypt", kControlAllowDecrypt,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
|
||||
if (algorithm != OEMCrypto_AES_CBC_128_NO_PADDING) {
|
||||
LOGE("[Generic_Decrypt(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -827,27 +851,13 @@ OEMCryptoResult SessionContext::Generic_Sign(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
const std::vector<uint8_t>& key = current_content_key()->value();
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
if (static_cast<int>(key.size()) != SHA256_DIGEST_LENGTH) {
|
||||
LOGE("[Generic_Sign(): CONTENT_KEY has wrong size; %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (!(control.control_bits() & kControlAllowSign)) {
|
||||
LOGE("[Generic_Sign(): control bit says not allowed.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[Generic_Sign(): key expired.");
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[Generic_Sign(): usage entry not valid]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
OEMCryptoResult result = AllowKeyUse("Generic_Sign", kControlAllowSign,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
LOGE("[Generic_Sign(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -877,27 +887,13 @@ OEMCryptoResult SessionContext::Generic_Verify(const uint8_t* in_buffer,
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
const std::vector<uint8_t>& key = current_content_key()->value();
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
if (static_cast<int>(key.size()) != SHA256_DIGEST_LENGTH) {
|
||||
LOGE("[Generic_Verify(): CONTENT_KEY has wrong size: %d", key.size());
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (!(control.control_bits() & kControlAllowVerify)) {
|
||||
LOGE("[Generic_Verify(): control bit says not allowed.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[Generic_Verify(): key expired.");
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[Generic_Verify(): usage entry not valid]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
OEMCryptoResult result = AllowKeyUse("Generic_Verify", kControlAllowVerify,
|
||||
OEMCrypto_BufferType_Clear);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
if (algorithm != OEMCrypto_HMAC_SHA256) {
|
||||
LOGE("[Generic_Verify(): bad algorithm.");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
@@ -1083,40 +1079,10 @@ OEMCryptoResult SessionContext::DecryptCENC(
|
||||
LOGE("[DecryptCTR(): OEMCrypto_ERROR_NO_CONTENT_KEY]");
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
const KeyControlBlock& control = current_content_key()->control();
|
||||
if (control.control_bits() & kControlDataPathSecure) {
|
||||
if (!ce_->config_closed_platform() &&
|
||||
buffer_type == OEMCrypto_BufferType_Clear) {
|
||||
LOGE("[DecryptCTR(): Secure key with insecure buffer]");
|
||||
return OEMCrypto_ERROR_DECRYPT_FAILED;
|
||||
}
|
||||
}
|
||||
if (control.duration() > 0) {
|
||||
if (control.duration() < CurrentTimer()) {
|
||||
LOGE("[DecryptCTR(): KEY_EXPIRED]");
|
||||
return OEMCrypto_ERROR_KEY_EXPIRED;
|
||||
}
|
||||
}
|
||||
if (control.control_bits() & kControlReplayMask) {
|
||||
if (!IsUsageEntryValid()) {
|
||||
LOGE("[DecryptCTR(): usage entry not valid]");
|
||||
return OEMCrypto_ERROR_UNKNOWN_FAILURE;
|
||||
}
|
||||
}
|
||||
if (!ce_->config_local_display_only()) {
|
||||
// Only look at HDCP if the display is non-local.
|
||||
if (control.control_bits() & kControlHDCPRequired) {
|
||||
uint8_t required_hdcp =
|
||||
(control.control_bits() & kControlHDCPVersionMask) >>
|
||||
kControlHDCPVersionShift;
|
||||
// For reference implementation, we pretend we can handle the current
|
||||
// HDCP version.
|
||||
if (required_hdcp > ce_->config_current_hdcp_capability() ||
|
||||
ce_->config_current_hdcp_capability() == 0) {
|
||||
return OEMCrypto_ERROR_INSUFFICIENT_HDCP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OEMCryptoResult result = AllowKeyUse("DecryptCENC", 0, buffer_type);
|
||||
if (result != OEMCrypto_SUCCESS) return result;
|
||||
|
||||
const std::vector<uint8_t>& content_key = current_content_key()->value();
|
||||
|
||||
// Set the AES key.
|
||||
|
||||
@@ -212,7 +212,8 @@ class SessionContext {
|
||||
OEMCryptoResult DecryptCTR(const uint8_t* key_u8, const uint8_t* iv,
|
||||
size_t block_offset, const uint8_t* cipher_data,
|
||||
size_t cipher_data_length, uint8_t* clear_data);
|
||||
|
||||
OEMCryptoResult AllowKeyUse(const std::string& log_string, uint32_t use_type,
|
||||
OEMCryptoBufferType buffer_type);
|
||||
RSA* rsa_key() { return rsa_key_.get(); }
|
||||
|
||||
bool valid_;
|
||||
|
||||
@@ -59,6 +59,13 @@ KeyControlBlock::KeyControlBlock(
|
||||
LOGD(" nonce: %08X", nonce());
|
||||
LOGD(" magic: %08X", verification());
|
||||
LOGD(" bits: %08X", control_bits());
|
||||
LOGD(" bit kControlSRMVersionRequired %s.",
|
||||
(control_bits() & kControlSRMVersionRequired) ? "set" : "unset");
|
||||
LOGD(" bit kControlDisableAnalogOutput %s.",
|
||||
(control_bits() & kControlDisableAnalogOutput) ? "set" : "unset");
|
||||
LOGD(" bits kControlSecurityPatchLevel 0x%02x.",
|
||||
(control_bits() & kControlSecurityPatchLevelMask)
|
||||
>> kControlSecurityPatchLevelShift);
|
||||
switch (control_bits() & kControlReplayMask) {
|
||||
case kControlNonceRequired:
|
||||
LOGD(" bits kControlReplay kControlNonceRequired.");
|
||||
@@ -70,12 +77,9 @@ KeyControlBlock::KeyControlBlock(
|
||||
LOGD(" bits kControlReplay unset.");
|
||||
break;
|
||||
}
|
||||
LOGD(" bits kControlKDCPVersion 0x%02x.",
|
||||
LOGD(" bits kControlHDCPVersion 0x%02x.",
|
||||
(control_bits() & kControlHDCPVersionMask)
|
||||
>> kControlHDCPVersionShift);
|
||||
LOGD(" bits kControlSecurityPatchLevel 0x%02x.",
|
||||
(control_bits() & kControlSecurityPatchLevelMask)
|
||||
>> kControlSecurityPatchLevelShift);
|
||||
LOGD(" bit kControlAllowEncrypt %s.",
|
||||
(control_bits() & kControlAllowEncrypt) ? "set" : "unset");
|
||||
LOGD(" bit kControlAllowDecrypt %s.",
|
||||
|
||||
@@ -15,6 +15,8 @@ const uint32_t kControlObserveDataPath = (1<<31);
|
||||
const uint32_t kControlObserveHDCP = (1<<30);
|
||||
const uint32_t kControlObserveCGMS = (1<<29);
|
||||
const uint32_t kControlRequireAntiRollbackHardware = (1<<28);
|
||||
const uint32_t kControlSRMVersionRequired = (1<<22);
|
||||
const uint32_t kControlDisableAnalogOutput = (1<<21);
|
||||
const uint32_t kControlSecurityPatchLevelShift = 15;
|
||||
const uint32_t kControlSecurityPatchLevelMask =
|
||||
(0x3F<<kControlSecurityPatchLevelShift);
|
||||
|
||||
@@ -123,6 +123,7 @@ std::string DeviceFeatures::RestrictFilter(const std::string& initial_filter) {
|
||||
if (api_version < 10) FilterOut(&filter, "*API10*");
|
||||
if (api_version < 11) FilterOut(&filter, "*API11*");
|
||||
if (api_version < 12) FilterOut(&filter, "*API12*");
|
||||
if (api_version < 13) FilterOut(&filter, "*API13*");
|
||||
// Performance tests take a long time. Filter them out if they are not
|
||||
// specifically requested.
|
||||
if (filter.find("Performance") == std::string::npos) {
|
||||
|
||||
@@ -309,8 +309,11 @@ void Session::FillSimpleMessage(uint32_t duration, uint32_t control,
|
||||
sizeof(license_.keys[i].key_iv)));
|
||||
EXPECT_EQ(1, RAND_pseudo_bytes(license_.keys[i].control_iv,
|
||||
sizeof(license_.keys[i].control_iv)));
|
||||
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
|
||||
if (global_features.api_version == 12) {
|
||||
if (global_features.api_version == 13) {
|
||||
// For version 13, we require OEMCrypto to handle kc13 for all licenses.
|
||||
memcpy(license_.keys[i].control.verification, "kc13", 4);
|
||||
} else if (global_features.api_version == 12) {
|
||||
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
|
||||
memcpy(license_.keys[i].control.verification, "kc12", 4);
|
||||
} else if (control & wvoec_mock::kControlSecurityPatchLevelMask) {
|
||||
// For versions before 12, we require the special key control block only
|
||||
@@ -338,7 +341,10 @@ void Session::FillRefreshMessage(size_t key_count, uint32_t control_bits,
|
||||
encrypted_license().keys[i].key_id_length = license_.keys[i].key_id_length;
|
||||
memcpy(encrypted_license().keys[i].key_id, license_.keys[i].key_id,
|
||||
encrypted_license().keys[i].key_id_length);
|
||||
if (global_features.api_version == 12) {
|
||||
if (global_features.api_version == 13) {
|
||||
// For version 13, we require OEMCrypto to handle kc13 for all licenses.
|
||||
memcpy(encrypted_license().keys[i].control.verification, "kc13", 4);
|
||||
} else if (global_features.api_version == 12) {
|
||||
// For version 12, we require OEMCrypto to handle kc12 for all licenses.
|
||||
memcpy(encrypted_license().keys[i].control.verification, "kc12", 4);
|
||||
} else {
|
||||
@@ -538,6 +544,10 @@ void Session::TestDecryptCTR(bool select_key_first,
|
||||
// Report HDCP errors.
|
||||
ASSERT_EQ(OEMCrypto_ERROR_INSUFFICIENT_HDCP, sts);
|
||||
ASSERT_NE(unencryptedData, outputBuffer);
|
||||
} else if (expected_result == OEMCrypto_ERROR_ANALOG_OUTPUT) {
|
||||
// Report analog errors.
|
||||
ASSERT_EQ(OEMCrypto_ERROR_ANALOG_OUTPUT, sts);
|
||||
ASSERT_NE(unencryptedData, outputBuffer);
|
||||
} else {
|
||||
// OEM's can fine tune other error codes for debugging.
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
|
||||
@@ -131,6 +131,24 @@ TEST_F(OEMCryptoClientTest, CheckHDCPCapability) {
|
||||
HDCPCapabilityAsString(maximum));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, CheckSRMCapabilityV13) {
|
||||
// This just tests some trivial functionality of the SRM update functions.
|
||||
bool supported = OEMCrypto_IsSRMUpdateSupported();
|
||||
printf(" Update SRM Supported: %s.\n",
|
||||
supported ? "true" : "false");
|
||||
uint16_t version = 0;
|
||||
OEMCryptoResult current_result = OEMCrypto_GetCurrentSRMVersion(&version);
|
||||
if (current_result == OEMCrypto_SUCCESS) {
|
||||
printf(" Current SRM Version: %d.\n", version);
|
||||
EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_GetCurrentSRMVersion(NULL));
|
||||
} else {
|
||||
EXPECT_EQ(OEMCrypto_ERROR_NOT_IMPLEMENTED, current_result);
|
||||
}
|
||||
vector<uint8_t> bad_srm(42);
|
||||
RAND_pseudo_bytes(&bad_srm[0], bad_srm.size());
|
||||
EXPECT_NE(OEMCrypto_SUCCESS, OEMCrypto_LoadSRM(&bad_srm[0], bad_srm.size()));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoClientTest, CheckMaxNumberOfSessionsAPI10) {
|
||||
size_t sessions_count;
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS,
|
||||
@@ -1153,7 +1171,8 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) {
|
||||
ASSERT_NE(OEMCrypto_SUCCESS, sts);
|
||||
} else {
|
||||
// Otherwise, LoadKeys should succeed.
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts);
|
||||
ASSERT_EQ(OEMCrypto_SUCCESS, sts)
|
||||
<< "LoadKeys failed for key control block kc" << target_api_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,7 +1180,7 @@ TEST_P(SessionTestAlternateVerification, LoadKeys) {
|
||||
// the current API + 2. We use +2 because we want to test at least 1
|
||||
// future API, and the ::testing::Range is not inclusive.
|
||||
INSTANTIATE_TEST_CASE_P(TestAll, SessionTestAlternateVerification,
|
||||
Range(8, 12 + 2));
|
||||
Range(8, 13 + 2));
|
||||
|
||||
TEST_F(OEMCryptoSessionTests, LoadKeysBadSignature) {
|
||||
Session s;
|
||||
@@ -2104,6 +2123,18 @@ TEST_F(OEMCryptoSessionTests, DecryptSecureToClear) {
|
||||
s.TestDecryptCTR(true, OEMCrypto_ERROR_UNKNOWN_FAILURE));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoSessionTests, DecryptNoAnalogToClear) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
ASSERT_NO_FATAL_FAILURE(InstallTestSessionKeys(&s));
|
||||
ASSERT_NO_FATAL_FAILURE(s.FillSimpleMessage(
|
||||
kDuration, wvoec_mock::kControlDisableAnalogOutput, 0));
|
||||
ASSERT_NO_FATAL_FAILURE(s.EncryptAndSign());
|
||||
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys());
|
||||
ASSERT_NO_FATAL_FAILURE(
|
||||
s.TestDecryptCTR(true, OEMCrypto_ERROR_ANALOG_OUTPUT));
|
||||
}
|
||||
|
||||
TEST_F(OEMCryptoSessionTests, KeyDuration) {
|
||||
Session s;
|
||||
ASSERT_NO_FATAL_FAILURE(s.open());
|
||||
|
||||
Reference in New Issue
Block a user