Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2493)

Unified Diff: content/renderer/webcrypto/webcrypto_impl_unittest.cc

Issue 100593002: [webcrypto] Add symmetric key export for NSS and OpenSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add more testing, fix minor bug, and add support for OpenSSL Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/webcrypto/webcrypto_impl_unittest.cc
diff --git a/content/renderer/webcrypto/webcrypto_impl_unittest.cc b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
index f9ff0d67f232b6d36e1fa38689175c289d2fa9f5..350fc84f2fb835e8f38a573c0ffcdd5d71777817 100644
--- a/content/renderer/webcrypto/webcrypto_impl_unittest.cc
+++ b/content/renderer/webcrypto/webcrypto_impl_unittest.cc
@@ -98,6 +98,34 @@ blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm(
#endif // #if !defined(USE_OPENSSL)
+// MIT HAKMEM Bit Count for 8-bit Unsigned Char
+int BitCount8(unsigned char b) {
+ b = (b & 0x55u) + ((b >> 1) & 0x55u);
+ b = (b & 0x33u) + ((b >> 2) & 0x33u);
+ b = (b & 0x0fu) + ((b >> 4) & 0x0fu);
+ return (b);
+}
+
+// Use a binary entropy calculation to check whether the input data appears
+// random. See http://en.wikipedia.org/wiki/Binary_entropy.
+void ExpectDataAppearsRandom(const blink::WebArrayBuffer& key_bytes) {
+ DCHECK(key_bytes.data());
+ DCHECK(key_bytes.byteLength());
+ int n_set_bits = 0;
+ unsigned char* data_ptr = static_cast<unsigned char*>(key_bytes.data());
+ unsigned char* const data_ptr_end = data_ptr + key_bytes.byteLength();
+ while (data_ptr < data_ptr_end) {
+ n_set_bits += BitCount8(*data_ptr++);
+ }
+ // Binary entropy is calculated as -p * log2(p) - (1 - p) * log2(1 - p), where
+ // p is the percentage of set bits in the input data. This function has a
+ // maximum of 1.0 at p = 0.5. Arbitrarily say the input data is random if the
+ // calculated entropy is > 0.75, which solves to 0.2145 ~< p ~< 0.7855.
eroman 2013/12/04 19:04:00 Doesn't this mean that truly random buffers will f
padolph 2013/12/04 22:22:13 No, the math does not work that way. However, I re
+ double p = static_cast<double>(n_set_bits) / (key_bytes.byteLength() * 8);
+ EXPECT_GT(p, 0.2145);
+ EXPECT_LT(p, 0.7855);
+}
+
} // namespace
namespace content {
@@ -421,6 +449,11 @@ TEST_F(WebCryptoImplTest, HMACSampleSets) {
blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
test.key, algorithm, blink::WebCryptoKeyUsageSign);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(test.key, raw_key);
+
std::vector<uint8> message_raw = HexStringToBytes(test.message);
blink::WebArrayBuffer output;
@@ -463,11 +496,17 @@ TEST_F(WebCryptoImplTest, HMACSampleSets) {
}
TEST_F(WebCryptoImplTest, AesCbcFailures) {
+ const std::string key_hex = "2b7e151628aed2a6abf7158809cf4f3c";
blink::WebCryptoKey key = ImportSecretKeyFromRawHexString(
- "2b7e151628aed2a6abf7158809cf4f3c",
+ key_hex,
CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(key_hex, raw_key);
+
blink::WebArrayBuffer output;
// Use an invalid |iv| (fewer than 16 bytes)
@@ -521,9 +560,10 @@ TEST_F(WebCryptoImplTest, AesCbcFailures) {
&key));
}
- // Fail exporting the key in SPKI format (SPKI export not allowed for secret
- // keys)
+ // Fail exporting the key in SPKI and PKCS#8 formats (not allowed for secret
+ // keys).
EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
+ EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatPkcs8, key, &output));
}
TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
@@ -613,6 +653,11 @@ TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc),
blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt);
+ // Verify exported raw key is identical to the imported data
+ blink::WebArrayBuffer raw_key;
+ EXPECT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &raw_key));
+ ExpectArrayBufferMatchesHex(test.key, raw_key);
+
std::vector<uint8> plain_text = HexStringToBytes(test.plain_text);
std::vector<uint8> iv = HexStringToBytes(test.iv);
@@ -657,13 +702,14 @@ TEST_F(WebCryptoImplTest, AesCbcSampleSets) {
}
}
-// TODO(padolph): Add test to verify generated symmetric keys appear random.
-
TEST_F(WebCryptoImplTest, GenerateKeyAes) {
blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key));
EXPECT_TRUE(key.handle());
EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ blink::WebArrayBuffer key_bytes;
+ ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
+ ExpectDataAppearsRandom(key_bytes);
}
TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) {
@@ -680,6 +726,9 @@ TEST_F(WebCryptoImplTest, GenerateKeyHmac) {
EXPECT_FALSE(key.isNull());
EXPECT_TRUE(key.handle());
EXPECT_EQ(blink::WebCryptoKeyTypeSecret, key.type());
+ blink::WebArrayBuffer key_bytes;
+ ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &key_bytes));
+ ExpectDataAppearsRandom(key_bytes);
}
TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) {
@@ -780,6 +829,10 @@ TEST_F(WebCryptoImplTest, ImportExportSpki) {
ASSERT_TRUE(ExportKeyInternal(blink::WebCryptoKeyFormatSpki, key, &output));
ExpectArrayBufferMatchesHex(hex_rsa_spki_der, output);
+ // Failing case: Try to export a previously imported RSA public key in raw
+ // format (not allowed for a public key).
+ EXPECT_FALSE(ExportKeyInternal(blink::WebCryptoKeyFormatRaw, key, &output));
+
// Failing case: Try to export a non-extractable key
ASSERT_TRUE(ImportKeyInternal(
blink::WebCryptoKeyFormatSpki,

Powered by Google App Engine
This is Rietveld 408576698