Merge "Adjust nonce flood rate in mock oemcrypto"

This commit is contained in:
TreeHugger Robot
2018-02-26 23:08:09 +00:00
committed by Android (Google) Code Review
6 changed files with 33 additions and 10 deletions

View File

@@ -514,6 +514,8 @@ class AndroidModifiableCryptoEngine : public CryptoEngine {
return false; return false;
} }
virtual int nonce_flood_count() { GetOption("nonce_flood_count", 20); }
virtual void adjust_destination(OEMCrypto_DestBufferDesc *out_description, virtual void adjust_destination(OEMCrypto_DestBufferDesc *out_description,
size_t data_length, uint8_t subsample_flags) { size_t data_length, uint8_t subsample_flags) {
if (out_description->type != OEMCrypto_BufferType_Secure) return; if (out_description->type != OEMCrypto_BufferType_Secure) return;

View File

@@ -146,6 +146,9 @@ class CryptoEngine {
virtual bool srm_blacklisted_device_attached() { return false; } virtual bool srm_blacklisted_device_attached() { return false; }
// Rate limit for nonce generation. Default to 20 nonce/second.
virtual int nonce_flood_count() { return 20; }
// Set destination pointer based on the output destination description. // Set destination pointer based on the output destination description.
OEMCryptoResult SetDestination(OEMCrypto_DestBufferDesc* out_description, OEMCryptoResult SetDestination(OEMCrypto_DestBufferDesc* out_description,
size_t data_length, uint8_t subsample_flags); size_t data_length, uint8_t subsample_flags);

View File

@@ -13,6 +13,7 @@
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/time.h>
#include <time.h> #include <time.h>
#include <iostream> #include <iostream>
#include <string> #include <string>
@@ -196,6 +197,13 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateDerivedKeys(
return OEMCrypto_SUCCESS; return OEMCrypto_SUCCESS;
} }
static const uint64_t one_second = 1000000ull;
static uint64_t TimeStamp(void) {
struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_sec * one_second + tv.tv_usec;
}
extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session, extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
uint32_t* nonce) { uint32_t* nonce) {
if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) { if (LogCategoryEnabled(kLoggingTraceOEMCryptoCalls)) {
@@ -213,12 +221,15 @@ extern "C" OEMCryptoResult OEMCrypto_GenerateNonce(OEMCrypto_SESSION session,
} }
// Prevent nonce flood. // Prevent nonce flood.
static time_t last_nonce_time = 0; uint64_t now = TimeStamp();
static int nonce_count = 0; static uint64_t last_nonce_time = now;
time_t now = time(NULL); // For testing, we set nonce_flood_count to 1. Since count is initialized to
if (now == last_nonce_time) { // 1, the very first nonce after initialization is counted as a flood.
static int nonce_count = 1;
if (now - last_nonce_time < one_second) {
nonce_count++; nonce_count++;
if (nonce_count > 20) { if (nonce_count > crypto_engine->nonce_flood_count()) {
LOGE("[OEMCrypto_GenerateNonce(): Nonce Flood detected]"); LOGE("[OEMCrypto_GenerateNonce(): Nonce Flood detected]");
return OEMCrypto_ERROR_UNKNOWN_FAILURE; return OEMCrypto_ERROR_UNKNOWN_FAILURE;
} }

View File

@@ -1197,15 +1197,17 @@ void Session::VerifyPST(const Test_PST_Report& expected) {
char* pst_ptr = reinterpret_cast<char *>(computed.pst()); char* pst_ptr = reinterpret_cast<char *>(computed.pst());
std::string computed_pst(pst_ptr, pst_ptr + computed.pst_length()); std::string computed_pst(pst_ptr, pst_ptr + computed.pst_length());
ASSERT_EQ(expected.pst, computed_pst); ASSERT_EQ(expected.pst, computed_pst);
EXPECT_NEAR(expected.seconds_since_license_received, time_t now = time(NULL);
int64_t age = now - expected.time_created; // How old is this report.
EXPECT_NEAR(expected.seconds_since_license_received + age,
computed.seconds_since_license_received(), computed.seconds_since_license_received(),
kTimeTolerance); kTimeTolerance);
// Decrypt times only valid on licenses that have been active. // Decrypt times only valid on licenses that have been active.
if (expected.status == kActive || expected.status == kInactiveUsed) { if (expected.status == kActive || expected.status == kInactiveUsed) {
EXPECT_NEAR(expected.seconds_since_first_decrypt, EXPECT_NEAR(expected.seconds_since_first_decrypt + age,
computed.seconds_since_first_decrypt(), computed.seconds_since_first_decrypt(),
kUsageTableTimeTolerance); kUsageTableTimeTolerance);
EXPECT_NEAR(expected.seconds_since_last_decrypt, EXPECT_NEAR(expected.seconds_since_last_decrypt + age,
computed.seconds_since_last_decrypt(), computed.seconds_since_last_decrypt(),
kUsageTableTimeTolerance); kUsageTableTimeTolerance);
} }

View File

@@ -94,13 +94,14 @@ struct RSAPrivateKeyMessage {
struct Test_PST_Report { struct Test_PST_Report {
Test_PST_Report(const std::string& pst_in, Test_PST_Report(const std::string& pst_in,
OEMCrypto_Usage_Entry_Status status_in) OEMCrypto_Usage_Entry_Status status_in)
: status(status_in), pst(pst_in) {} : status(status_in), pst(pst_in), time_created(time(NULL)) {}
OEMCrypto_Usage_Entry_Status status; OEMCrypto_Usage_Entry_Status status;
int64_t seconds_since_license_received; int64_t seconds_since_license_received;
int64_t seconds_since_first_decrypt; int64_t seconds_since_first_decrypt;
int64_t seconds_since_last_decrypt; int64_t seconds_since_last_decrypt;
std::string pst; std::string pst;
time_t time_created;
}; };
struct EntitledContentKeyData { struct EntitledContentKeyData {

View File

@@ -4935,6 +4935,7 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
std::string pst = "my_pst"; std::string pst = "my_pst";
Session s; Session s;
ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s, pst)); ASSERT_NO_FATAL_FAILURE(LoadOfflineLicense(s, pst));
time_t loaded = time(NULL);
// Offline license with new mac keys should fail. // Offline license with new mac keys should fail.
Session s2; Session s2;
@@ -4961,7 +4962,10 @@ TEST_P(UsageTableTestWithMAC, BadReloadOfflineLicense) {
ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry()); ASSERT_NO_FATAL_FAILURE(s.ReloadUsageEntry());
ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_)); ASSERT_NO_FATAL_FAILURE(s.LoadTestKeys(pst, new_mac_keys_));
ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_)); ASSERT_NO_FATAL_FAILURE(s.UpdateUsageEntry(&encrypted_usage_header_));
ASSERT_NO_FATAL_FAILURE(s.GenerateVerifyReport(pst, kUnused)); ASSERT_NO_FATAL_FAILURE(
s.GenerateVerifyReport(pst, kUnused,
loaded, // license loaded.
0, 0)); // first and last decrypt
} }
// An offline license should not load on the first call if the nonce is bad. // An offline license should not load on the first call if the nonce is bad.