Commit 42e82923 authored by eroman's avatar eroman Committed by Commit bot

Check for integer overflow when HMAC key length as bits cannot fit in an unsigned int.

Review URL: https://codereview.chromium.org/508793002

Cr-Commit-Position: refs/heads/master@{#292203}
parent 097d3a4a
......@@ -8,6 +8,7 @@
#include <sechash.h>
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "content/child/webcrypto/algorithm_implementation.h"
#include "content/child/webcrypto/crypto_data.h"
......@@ -109,16 +110,20 @@ class HmacImplementation : public AlgorithmImplementation {
if (!WebCryptoHashToHMACMechanism(hash, &mechanism))
return Status::ErrorUnsupported();
// TODO(eroman): check for overflow.
unsigned int keylen_bits = key_data.byte_length() * 8;
return ImportKeyRawNss(
key_data,
blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits),
extractable,
usage_mask,
mechanism,
CKF_SIGN | CKF_VERIFY,
key);
base::CheckedNumeric<unsigned int> keylen_bits(key_data.byte_length());
keylen_bits *= 8;
if (!keylen_bits.IsValid())
return Status::ErrorDataTooLarge();
return ImportKeyRawNss(key_data,
blink::WebCryptoKeyAlgorithm::createHmac(
hash.id(), keylen_bits.ValueOrDie()),
extractable,
usage_mask,
mechanism,
CKF_SIGN | CKF_VERIFY,
key);
}
virtual Status ImportKeyJwk(const CryptoData& key_data,
......
......@@ -5,6 +5,7 @@
#include <openssl/hmac.h>
#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/stl_util.h"
#include "content/child/webcrypto/algorithm_implementation.h"
#include "content/child/webcrypto/crypto_data.h"
......@@ -114,15 +115,18 @@ class HmacImplementation : public AlgorithmImplementation {
const blink::WebCryptoAlgorithm& hash =
algorithm.hmacImportParams()->hash();
// TODO(eroman): check for overflow.
unsigned int keylen_bits = key_data.byte_length() * 8;
base::CheckedNumeric<unsigned int> keylen_bits(key_data.byte_length());
keylen_bits *= 8;
return ImportKeyRawOpenSsl(
key_data,
blink::WebCryptoKeyAlgorithm::createHmac(hash.id(), keylen_bits),
extractable,
usage_mask,
key);
if (!keylen_bits.IsValid())
return Status::ErrorDataTooLarge();
return ImportKeyRawOpenSsl(key_data,
blink::WebCryptoKeyAlgorithm::createHmac(
hash.id(), keylen_bits.ValueOrDie()),
extractable,
usage_mask,
key);
}
virtual Status ImportKeyJwk(const CryptoData& key_data,
......
......@@ -523,6 +523,22 @@ TEST(WebCryptoHmacTest, ExportJwkEmptyKey) {
EXPECT_EQ(0u, exported_key_data.size());
}
// Import a huge hmac key (UINT_MAX bytes). This will fail before actually
// reading the bytes, as the key is too large.
TEST(WebCryptoHmacTest, ImportRawKeyTooLarge) {
CryptoData big_data(NULL, UINT_MAX); // Invalid data of big length.
blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
EXPECT_EQ(
Status::ErrorDataTooLarge(),
ImportKey(blink::WebCryptoKeyFormatRaw,
CryptoData(big_data),
CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha1),
true,
blink::WebCryptoKeyUsageSign,
&key));
}
} // namespace
} // namespace webcrypto
......
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