Commit 66eac028 authored by Staphany Park's avatar Staphany Park Committed by Commit Bot

CacheStorage: Extract padding calculation logic.

Bug: 918293
Change-Id: I8e8a7e9e5ead7eca1c6712d8464ae1d63049b96c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1538977Reviewed-by: default avatarBen Kelly <wanderview@chromium.org>
Reviewed-by: default avatarVictor Costan <pwnall@chromium.org>
Commit-Queue: Staphany Park <staphany@chromium.org>
Cr-Commit-Position: refs/heads/master@{#644532}
parent c129ba0f
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_data_handle.h"
#include "storage/browser/blob/blob_storage_context.h" #include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/blob/blob_url_request_job_factory.h" #include "storage/browser/blob/blob_url_request_job_factory.h"
#include "storage/browser/quota/padding_key.h"
#include "storage/browser/quota/quota_manager_proxy.h" #include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/common/blob_storage/blob_handle.h" #include "storage/common/blob_storage/blob_handle.h"
#include "storage/common/storage_histograms.h" #include "storage/common/storage_histograms.h"
...@@ -75,10 +76,6 @@ const size_t kMaxQueryCacheResultBytes = ...@@ -75,10 +76,6 @@ const size_t kMaxQueryCacheResultBytes =
const char kRecordBytesLabel[] = "DiskCache.CacheStorage"; const char kRecordBytesLabel[] = "DiskCache.CacheStorage";
// The range of the padding added to response sizes for opaque resources.
// Increment padding version if changed.
const uint64_t kPaddingRange = 14431 * 1024;
// If the way that a cache's padding is calculated changes increment this // If the way that a cache's padding is calculated changes increment this
// version. // version.
// //
...@@ -392,37 +389,14 @@ bool ShouldPadResourceSize(const blink::mojom::FetchAPIResponse& response) { ...@@ -392,37 +389,14 @@ bool ShouldPadResourceSize(const blink::mojom::FetchAPIResponse& response) {
!response.url_list.empty()); !response.url_list.empty());
} }
int64_t CalculateResponsePaddingInternal(
const std::string& response_url,
const crypto::SymmetricKey* padding_key,
int side_data_size) {
DCHECK(!response_url.empty());
crypto::HMAC hmac(crypto::HMAC::SHA256);
if (!hmac.Init(padding_key))
LOG(FATAL) << "Failed to init HMAC.";
std::vector<uint8_t> digest(hmac.DigestLength());
bool success;
if (side_data_size)
success = hmac.Sign(response_url + "METADATA", &digest[0], digest.size());
else
success = hmac.Sign(response_url, &digest[0], digest.size());
if (!success)
LOG(FATAL) << "Failed to sign URL.";
DCHECK_GE(digest.size(), sizeof(uint64_t));
uint64_t val = *(reinterpret_cast<uint64_t*>(&digest[0]));
return val % kPaddingRange;
}
int64_t CalculateResponsePaddingInternal( int64_t CalculateResponsePaddingInternal(
const ::content::proto::CacheResponse* response, const ::content::proto::CacheResponse* response,
const crypto::SymmetricKey* padding_key, const crypto::SymmetricKey* padding_key,
int side_data_size) { int side_data_size) {
DCHECK(ShouldPadResourceSize(response)); DCHECK(ShouldPadResourceSize(response));
DCHECK_GE(side_data_size, 0);
const std::string& url = response->url_list(response->url_list_size() - 1); const std::string& url = response->url_list(response->url_list_size() - 1);
return CalculateResponsePaddingInternal(url, padding_key, side_data_size); return storage::ComputeResponsePadding(url, padding_key, side_data_size > 0);
} }
} // namespace } // namespace
...@@ -1247,10 +1221,11 @@ int64_t CacheStorageCache::CalculateResponsePadding( ...@@ -1247,10 +1221,11 @@ int64_t CacheStorageCache::CalculateResponsePadding(
const blink::mojom::FetchAPIResponse& response, const blink::mojom::FetchAPIResponse& response,
const crypto::SymmetricKey* padding_key, const crypto::SymmetricKey* padding_key,
int side_data_size) { int side_data_size) {
DCHECK_GE(side_data_size, 0);
if (!ShouldPadResourceSize(response)) if (!ShouldPadResourceSize(response))
return 0; return 0;
return CalculateResponsePaddingInternal(response.url_list.back().spec(), return storage::ComputeResponsePadding(response.url_list.back().spec(),
padding_key, side_data_size); padding_key, side_data_size > 0);
} }
// static // static
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
#include "storage/browser/quota/padding_key.h" #include "storage/browser/quota/padding_key.h"
#include <cstdint>
#include <vector>
#include "base/no_destructor.h" #include "base/no_destructor.h"
#include "crypto/hmac.h"
using crypto::SymmetricKey; using crypto::SymmetricKey;
...@@ -14,6 +18,10 @@ namespace { ...@@ -14,6 +18,10 @@ namespace {
const SymmetricKey::Algorithm kPaddingKeyAlgorithm = SymmetricKey::AES; const SymmetricKey::Algorithm kPaddingKeyAlgorithm = SymmetricKey::AES;
// The range of the padding added to response sizes for opaque resources.
// Increment padding version if changed.
constexpr uint64_t kPaddingRange = 14431 * 1024;
std::unique_ptr<SymmetricKey>* GetPaddingKey() { std::unique_ptr<SymmetricKey>* GetPaddingKey() {
static base::NoDestructor<std::unique_ptr<SymmetricKey>> s_padding_key([] { static base::NoDestructor<std::unique_ptr<SymmetricKey>> s_padding_key([] {
return SymmetricKey::GenerateRandomKey(kPaddingKeyAlgorithm, 128); return SymmetricKey::GenerateRandomKey(kPaddingKeyAlgorithm, 128);
...@@ -40,4 +48,19 @@ void ResetPaddingKeyForTesting() { ...@@ -40,4 +48,19 @@ void ResetPaddingKeyForTesting() {
*GetPaddingKey() = SymmetricKey::GenerateRandomKey(kPaddingKeyAlgorithm, 128); *GetPaddingKey() = SymmetricKey::GenerateRandomKey(kPaddingKeyAlgorithm, 128);
} }
int64_t ComputeResponsePadding(const std::string& response_url,
const crypto::SymmetricKey* padding_key,
bool has_metadata) {
DCHECK(!response_url.empty());
crypto::HMAC hmac(crypto::HMAC::SHA256);
CHECK(hmac.Init(padding_key));
std::string key = has_metadata ? response_url + "METADATA" : response_url;
uint64_t digest_start;
CHECK(hmac.Sign(key, reinterpret_cast<uint8_t*>(&digest_start),
sizeof(digest_start)));
return digest_start % kPaddingRange;
}
} // namespace storage } // namespace storage
...@@ -43,6 +43,20 @@ std::string SerializeDefaultPaddingKey(); ...@@ -43,6 +43,20 @@ std::string SerializeDefaultPaddingKey();
COMPONENT_EXPORT(STORAGE_BROWSER) COMPONENT_EXPORT(STORAGE_BROWSER)
void ResetPaddingKeyForTesting(); void ResetPaddingKeyForTesting();
// Compute the padding size for a resource.
//
// For AppCache, which does not support storing metadata for a resource,
// |has_metadata| will always be false.
//
// For CacheStorage, the padding size of an entry depends on whether it contains
// metadata (a.k.a. "side data"). If metadata is added to the entry, the entry
// must be assigned a new padding size. Otherwise, the growth in the entry's
// size would leak the exact size of the added metadata.
COMPONENT_EXPORT(STORAGE_BROWSER)
int64_t ComputeResponsePadding(const std::string& response_url,
const crypto::SymmetricKey* padding_key,
bool has_metadata);
} // namespace storage } // namespace storage
#endif // STORAGE_BROWSER_QUOTA_PADDING_KEY_H_ #endif // STORAGE_BROWSER_QUOTA_PADDING_KEY_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment