summaryrefslogtreecommitdiffstats
path: root/components/gcm_driver/crypto/gcm_encryption_provider.cc
diff options
context:
space:
mode:
authorpeter <peter@chromium.org>2016-02-19 10:51:39 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-19 18:53:04 +0000
commit266a2aa40f2fb11662afe0af694b4be0cfb3efe4 (patch)
treeb6ee69a7062ed42db093e5e6d4033b01423eae50 /components/gcm_driver/crypto/gcm_encryption_provider.cc
parenta83fb3a4c55025a39a0ec95ba10504affdc33e95 (diff)
downloadchromium_src-266a2aa40f2fb11662afe0af694b4be0cfb3efe4.zip
chromium_src-266a2aa40f2fb11662afe0af694b4be0cfb3efe4.tar.gz
chromium_src-266a2aa40f2fb11662afe0af694b4be0cfb3efe4.tar.bz2
Add various UMA histograms for measuring GCM crypto performance
This adds (and tests) UMA in the GCMKeyStore, an on-disk database, and the decryption routines part of the GCMEncryptionProvider and the GCMMessageCryptographer. Adding the metrics comes with an extra free refactoring adjusting the message-received flow to make it cleaner to measure them. BUG=486040 Review URL: https://codereview.chromium.org/1707513002 Cr-Commit-Position: refs/heads/master@{#376501}
Diffstat (limited to 'components/gcm_driver/crypto/gcm_encryption_provider.cc')
-rw-r--r--components/gcm_driver/crypto/gcm_encryption_provider.cc62
1 files changed, 35 insertions, 27 deletions
diff --git a/components/gcm_driver/crypto/gcm_encryption_provider.cc b/components/gcm_driver/crypto/gcm_encryption_provider.cc
index bb6d4ab..a89fedf 100644
--- a/components/gcm_driver/crypto/gcm_encryption_provider.cc
+++ b/components/gcm_driver/crypto/gcm_encryption_provider.cc
@@ -29,25 +29,27 @@ const base::FilePath::CharType kEncryptionDirectoryName[] =
} // namespace
-std::string GCMEncryptionProvider::ToDecryptionFailureDetailsString(
- DecryptionFailure reason) {
- switch(reason) {
- case DECRYPTION_FAILURE_UNKNOWN:
- return "Unknown failure";
- case DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER:
+std::string GCMEncryptionProvider::ToDecryptionResultDetailsString(
+ DecryptionResult result) {
+ switch(result) {
+ case DECRYPTION_RESULT_UNENCRYPTED:
+ return "Message was not encrypted";
+ case DECRYPTION_RESULT_DECRYPTED:
+ return "Message decrypted";
+ case DECRYPTION_RESULT_INVALID_ENCRYPTION_HEADER:
return "Invalid format for the Encryption header";
- case DECRYPTION_FAILURE_INVALID_CRYPTO_KEY_HEADER:
+ case DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER:
return "Invalid format for the Crypto-Key header";
- case DECRYPTION_FAILURE_NO_KEYS:
+ case DECRYPTION_RESULT_NO_KEYS:
return "There are no associated keys with the subscription";
- case DECRYPTION_FAILURE_INVALID_PUBLIC_KEY:
- return "The public key in the Crypto-Key header is invalid";
- case DECRYPTION_FAILURE_INVALID_PAYLOAD:
+ case DECRYPTION_RESULT_INVALID_SHARED_SECRET:
+ return "The shared secret cannot be derived from the keying material";
+ case DECRYPTION_RESULT_INVALID_PAYLOAD:
return "AES-GCM decryption failed";
}
NOTREACHED();
- return "(invalid reason)";
+ return "(invalid result)";
}
GCMEncryptionProvider::GCMEncryptionProvider()
@@ -103,14 +105,18 @@ bool GCMEncryptionProvider::IsEncryptedMessage(const IncomingMessage& message)
void GCMEncryptionProvider::DecryptMessage(
const std::string& app_id,
const IncomingMessage& message,
- const MessageDecryptedCallback& success_callback,
- const DecryptionFailedCallback& failure_callback) {
+ const MessageCallback& callback) {
DCHECK(key_store_);
+ if (!IsEncryptedMessage(message)) {
+ callback.Run(DECRYPTION_RESULT_UNENCRYPTED, message);
+ return;
+ }
+ // IsEncryptedMessage() verifies that both the Encryption and Crypto-Key HTTP
+ // headers have been provided for the |message|.
const auto& encryption_header = message.data.find(kEncryptionProperty);
const auto& crypto_key_header = message.data.find(kCryptoKeyProperty);
- // Callers are expected to call IsEncryptedMessage() prior to this method.
DCHECK(encryption_header != message.data.end());
DCHECK(crypto_key_header != message.data.end());
@@ -118,7 +124,8 @@ void GCMEncryptionProvider::DecryptMessage(
if (!ParseEncryptionHeader(encryption_header->second,
&encryption_header_values)) {
DLOG(ERROR) << "Unable to parse the value of the Encryption header";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER);
+ callback.Run(DECRYPTION_RESULT_INVALID_ENCRYPTION_HEADER,
+ IncomingMessage());
return;
}
@@ -126,7 +133,8 @@ void GCMEncryptionProvider::DecryptMessage(
encryption_header_values[0].salt.size() !=
GCMMessageCryptographer::kSaltSize) {
DLOG(ERROR) << "Invalid values supplied in the Encryption header";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_ENCRYPTION_HEADER);
+ callback.Run(DECRYPTION_RESULT_INVALID_ENCRYPTION_HEADER,
+ IncomingMessage());
return;
}
@@ -134,22 +142,23 @@ void GCMEncryptionProvider::DecryptMessage(
if (!ParseCryptoKeyHeader(crypto_key_header->second,
&crypto_key_header_values)) {
DLOG(ERROR) << "Unable to parse the value of the Crypto-Key header";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_CRYPTO_KEY_HEADER);
+ callback.Run(DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
+ IncomingMessage());
return;
}
if (crypto_key_header_values.size() != 1u ||
!crypto_key_header_values[0].dh.size()) {
DLOG(ERROR) << "Invalid values supplied in the Crypto-Key header";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_CRYPTO_KEY_HEADER);
+ callback.Run(DECRYPTION_RESULT_INVALID_CRYPTO_KEY_HEADER,
+ IncomingMessage());
return;
}
key_store_->GetKeys(
app_id, base::Bind(&GCMEncryptionProvider::DecryptMessageWithKey,
weak_ptr_factory_.GetWeakPtr(), message,
- success_callback, failure_callback,
- encryption_header_values[0].salt,
+ callback, encryption_header_values[0].salt,
crypto_key_header_values[0].dh,
encryption_header_values[0].rs));
}
@@ -186,8 +195,7 @@ void GCMEncryptionProvider::DidCreateEncryptionInfo(
void GCMEncryptionProvider::DecryptMessageWithKey(
const IncomingMessage& message,
- const MessageDecryptedCallback& success_callback,
- const DecryptionFailedCallback& failure_callback,
+ const MessageCallback& callback,
const std::string& salt,
const std::string& dh,
uint64_t rs,
@@ -195,7 +203,7 @@ void GCMEncryptionProvider::DecryptMessageWithKey(
const std::string& auth_secret) {
if (!pair.IsInitialized()) {
DLOG(ERROR) << "Unable to retrieve the keys for the incoming message.";
- failure_callback.Run(DECRYPTION_FAILURE_NO_KEYS);
+ callback.Run(DECRYPTION_RESULT_NO_KEYS, IncomingMessage());
return;
}
@@ -205,7 +213,7 @@ void GCMEncryptionProvider::DecryptMessageWithKey(
if (!ComputeSharedP256Secret(pair.private_key(), pair.public_key_x509(), dh,
&shared_secret)) {
DLOG(ERROR) << "Unable to calculate the shared secret.";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_PUBLIC_KEY);
+ callback.Run(DECRYPTION_RESULT_INVALID_SHARED_SECRET, IncomingMessage());
return;
}
@@ -216,7 +224,7 @@ void GCMEncryptionProvider::DecryptMessageWithKey(
if (!cryptographer.Decrypt(message.raw_data, shared_secret, salt, rs,
&plaintext)) {
DLOG(ERROR) << "Unable to decrypt the incoming data.";
- failure_callback.Run(DECRYPTION_FAILURE_INVALID_PAYLOAD);
+ callback.Run(DECRYPTION_RESULT_INVALID_PAYLOAD, IncomingMessage());
return;
}
@@ -230,7 +238,7 @@ void GCMEncryptionProvider::DecryptMessageWithKey(
// to make sure that we don't end up in an infinite decryption loop.
DCHECK_EQ(0u, decrypted_message.data.size());
- success_callback.Run(decrypted_message);
+ callback.Run(DECRYPTION_RESULT_DECRYPTED, decrypted_message);
}
} // namespace gcm